Initial commit
This commit is contained in:
341
skills/c4model-c4/SKILL.md
Normal file
341
skills/c4model-c4/SKILL.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
name: c4model-c4
|
||||
description: Expert methodology for C4 Model Level 4 (Code) analysis - identifying classes, functions, methods, interfaces, and types within components. Use when analyzing code-level structure, mapping signatures, detecting complexity, identifying code patterns, or documenting code elements after C3 component identification. Essential for c4-abstractor agent during code element identification phase.
|
||||
---
|
||||
|
||||
# C4 Model - Level 4: Code Methodology
|
||||
|
||||
## Overview
|
||||
|
||||
You are an expert in the C4 Model's Level 4 (Code) methodology. This skill provides comprehensive knowledge for identifying and documenting code elements at the most granular level of architectural abstraction.
|
||||
|
||||
**Your Mission:** Help identify WHAT code elements exist within components, WHAT they do, and HOW they interact - focusing on classes, functions, methods, interfaces, and types.
|
||||
|
||||
### C4 Level Definition
|
||||
|
||||
The Code level shows the **internal implementation** of components - the actual code building blocks:
|
||||
|
||||
- **Classes** - Object-oriented class definitions with inheritance and interfaces
|
||||
- **Functions** - Standalone functions and async functions
|
||||
- **Methods** - Class methods with visibility modifiers
|
||||
- **Interfaces** - Type contracts and interface definitions
|
||||
- **Types** - Type aliases, generics, and type definitions
|
||||
- **Constants/Enums** - Constant values and enumerations
|
||||
|
||||
**At C4, we focus on:** Class structure, function signatures, method implementations, type definitions, code metrics, inheritance hierarchies, interface implementations, parameter types, return types, decorators/annotations.
|
||||
|
||||
**At C4, we do NOT focus on:** System boundaries (C1), container technologies (C2), component organization (C3), infrastructure configuration.
|
||||
|
||||
**Important Note (per C4 Model methodology):** The Code level is often skipped or auto-generated because:
|
||||
- IDEs can generate this automatically
|
||||
- UML class diagrams serve this purpose
|
||||
- It's too detailed to maintain manually
|
||||
- Code is the source of truth
|
||||
|
||||
Focus on **significant code elements** only - public APIs, complex functions, key classes.
|
||||
|
||||
---
|
||||
|
||||
## Detailed References
|
||||
|
||||
For comprehensive guidance on specific aspects of C4 code analysis, see:
|
||||
|
||||
- **[Code Element Identification](./code-element-identification.md)** - Element types, detection rules, significance criteria, naming conventions
|
||||
- **[Signature Analysis](./signature-analysis.md)** - Parameter extraction, return types, generics, decorators
|
||||
- **[Complexity Metrics](./complexity-metrics.md)** - Cyclomatic complexity, cognitive complexity, nesting depth, LOC
|
||||
- **[Observation Guide](./observation-guide-c4.md)** - 10 observation categories, severity levels, evidence collection
|
||||
- **[Relation Types](./relation-types-c4.md)** - calls, returns, imports, inherits, implements, and more
|
||||
|
||||
These references are loaded progressively when needed for detailed analysis.
|
||||
|
||||
---
|
||||
|
||||
## Code Element Identification Summary
|
||||
|
||||
A **code element** at C4 level is a discrete unit of code with clear purpose - such as a class definition, function declaration, interface contract, or type alias.
|
||||
|
||||
### Element Types
|
||||
|
||||
1. **class** - Object-oriented class definition
|
||||
2. **function** - Standalone function (sync)
|
||||
3. **async-function** - Async function returning Promise
|
||||
4. **method** - Class or object method
|
||||
5. **interface** - TypeScript/Java interface
|
||||
6. **type** - Type alias or type definition
|
||||
7. **constant** - Exported constant value
|
||||
8. **variable** - Module-level variable
|
||||
9. **enum** - Enumeration definition
|
||||
10. **decorator** - Decorator/annotation definition
|
||||
11. **generator** - Generator function
|
||||
12. **module** - Module or namespace export
|
||||
13. **namespace** - Namespace declaration
|
||||
|
||||
### Significance Criteria
|
||||
|
||||
Document a code element if **ANY** apply:
|
||||
- Public API (exported from module)
|
||||
- Lines of code > 20
|
||||
- Cyclomatic complexity > 4
|
||||
- Multiple callers or dependencies
|
||||
- Implements design pattern
|
||||
- Contains critical business logic
|
||||
- Has security implications
|
||||
- Is entry point or controller action
|
||||
- Defines key data structure
|
||||
|
||||
**Key principles:** Focus on significant elements, preserve original naming, document public APIs thoroughly, calculate metrics for functions/methods.
|
||||
|
||||
For complete methodology, see [code-element-identification.md](./code-element-identification.md).
|
||||
|
||||
---
|
||||
|
||||
## Signature Analysis Summary
|
||||
|
||||
Extract signature information for functions, methods, and interfaces:
|
||||
|
||||
### Parameters
|
||||
- Name (original case)
|
||||
- Type (full type including generics)
|
||||
- Optional flag
|
||||
- Default value (if any)
|
||||
|
||||
### Return Type
|
||||
- Full return type
|
||||
- Promise type for async functions
|
||||
- Void for procedures
|
||||
|
||||
### Modifiers
|
||||
- async (true/false)
|
||||
- generic_params (type parameters)
|
||||
- visibility (public/private/protected)
|
||||
|
||||
For complete methodology, see [signature-analysis.md](./signature-analysis.md).
|
||||
|
||||
---
|
||||
|
||||
## Complexity Metrics Summary
|
||||
|
||||
Calculate and document these metrics:
|
||||
|
||||
1. **Lines of Code (LOC)** - Actual code lines excluding comments
|
||||
2. **Cyclomatic Complexity** - Number of independent paths through code
|
||||
3. **Cognitive Complexity** - Mental effort to understand code
|
||||
4. **Parameter Count** - Number of function/method parameters
|
||||
5. **Nesting Depth** - Maximum depth of nested structures
|
||||
|
||||
### Thresholds
|
||||
|
||||
| Metric | Good | Warning | Critical |
|
||||
|--------|------|---------|----------|
|
||||
| Cyclomatic | 1-6 | 7-10 | >10 |
|
||||
| Cognitive | 0-10 | 11-20 | >20 |
|
||||
| Parameters | 0-3 | 4-5 | >5 |
|
||||
| Nesting | 0-3 | 4-5 | >5 |
|
||||
| LOC | 1-30 | 31-50 | >50 |
|
||||
|
||||
For complete methodology, see [complexity-metrics.md](./complexity-metrics.md).
|
||||
|
||||
---
|
||||
|
||||
## Observation Categories
|
||||
|
||||
Document findings using these 10 categories:
|
||||
|
||||
1. **implementation** - Code patterns, algorithms, logic flow
|
||||
2. **error-handling** - Exception handling, error propagation
|
||||
3. **type-safety** - Type definitions, generics, type guards
|
||||
4. **documentation** - JSDoc, docstrings, inline comments
|
||||
5. **testing** - Test coverage, testability, mocking
|
||||
6. **complexity** - Cyclomatic/cognitive complexity metrics
|
||||
7. **performance** - Algorithm efficiency, memory, async patterns
|
||||
8. **security** - Input validation, sanitization, auth
|
||||
9. **concurrency** - Async/await, promises, race conditions
|
||||
10. **patterns** - Design patterns, code patterns, anti-patterns
|
||||
|
||||
**Severity levels:**
|
||||
- ℹ️ info (informational)
|
||||
- ⚠️ warning (potential issue)
|
||||
- 🔴 critical (requires immediate action)
|
||||
|
||||
For complete guide, see [observation-guide-c4.md](./observation-guide-c4.md).
|
||||
|
||||
---
|
||||
|
||||
## Relation Types
|
||||
|
||||
Document relationships between code elements:
|
||||
|
||||
### Code Flow Relations
|
||||
- **calls** - Invokes another function/method
|
||||
- **awaits** - Awaits an async function
|
||||
- **returns** - Returns a specific type
|
||||
- **throws** - Throws an exception type
|
||||
|
||||
### Structural Relations
|
||||
- **inherits** - Extends another class
|
||||
- **implements** - Implements an interface
|
||||
- **declares** - Declares a type or interface
|
||||
- **uses-type** - Uses a type in signature/body
|
||||
|
||||
### Data Relations
|
||||
- **creates** - Instantiates a class
|
||||
- **mutates** - Modifies state or data
|
||||
- **reads** - Reads from data source
|
||||
|
||||
### Dependency Relations
|
||||
- **imports** - Imports from module
|
||||
- **depends-on** - General dependency
|
||||
- **overrides** - Overrides parent method
|
||||
|
||||
For complete guide, see [relation-types-c4.md](./relation-types-c4.md).
|
||||
|
||||
---
|
||||
|
||||
## Integration with Melly Workflow
|
||||
|
||||
### When This Skill is Used
|
||||
|
||||
This skill is activated during **Phase 4: C4 Code Identification** (`/melly-c4-code`) for code element identification, signature analysis, metrics calculation, and pattern detection. Also used in **Phase 5: Documentation** (`/melly-doc-c4model`) for markdown generation.
|
||||
|
||||
### Input Expectations
|
||||
|
||||
Expects data from `c3-components.json` with component details including id, name, type, container_id, structure (path, language, files, exports).
|
||||
|
||||
### Output Format
|
||||
|
||||
Generates `c4-code.json` with metadata, code_elements array, and summary.
|
||||
|
||||
### Validation
|
||||
|
||||
Generated output must pass: Schema validation, timestamp ordering (c4 > c3), referential integrity (all component_ids exist), required fields, ID format (kebab-case).
|
||||
|
||||
Validation script:
|
||||
```bash
|
||||
python3 ${CLAUDE_PLUGIN_ROOT}/validation/scripts/validate-c4-code.py c4-code.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Workflow
|
||||
|
||||
### Systematic Approach for c4-abstractor Agent
|
||||
|
||||
**Step 1: Load Input Data**
|
||||
```bash
|
||||
cat c3-components.json | jq '.components'
|
||||
```
|
||||
|
||||
**Step 2: Analyze Each Component**
|
||||
Navigate to component path, understand file structure, identify source files.
|
||||
|
||||
**Step 3: Identify Code Elements**
|
||||
For each source file:
|
||||
- Parse class definitions
|
||||
- Extract function declarations
|
||||
- Identify interfaces and types
|
||||
- Find constants and enums
|
||||
|
||||
**Step 4: Extract Signatures**
|
||||
For functions/methods:
|
||||
- Parameter names and types
|
||||
- Return type
|
||||
- Async modifier
|
||||
- Generic parameters
|
||||
|
||||
For classes:
|
||||
- Parent class (extends)
|
||||
- Implemented interfaces
|
||||
- Decorators/annotations
|
||||
- Abstract modifier
|
||||
|
||||
**Step 5: Calculate Metrics**
|
||||
- Count lines of code
|
||||
- Calculate cyclomatic complexity
|
||||
- Measure cognitive complexity
|
||||
- Determine nesting depth
|
||||
|
||||
**Step 6: Map Relationships**
|
||||
- Find function calls
|
||||
- Identify imports
|
||||
- Track inheritance
|
||||
- Document interface implementations
|
||||
|
||||
**Step 7: Generate Observations**
|
||||
Document findings across 10 categories with evidence.
|
||||
|
||||
**Step 8: Validate Output**
|
||||
Check element IDs, component references, timestamps, run validation script.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
|
||||
1. **Focus on significant elements** - Public APIs, complex functions, key classes
|
||||
2. **Preserve original names** - Use original case in name field
|
||||
3. **Use kebab-case IDs** - Convert PascalCase/camelCase to kebab-case for IDs
|
||||
4. **Document signatures thoroughly** - Parameters, types, return values
|
||||
5. **Calculate metrics** - LOC, complexity for all functions/methods
|
||||
6. **Track inheritance** - Document extends and implements
|
||||
7. **Note decorators** - Record applied decorators/annotations
|
||||
8. **Provide evidence** - File paths, line numbers, code snippets
|
||||
9. **Document relationships** - calls, imports, inherits, implements
|
||||
10. **Validate output** - Always run validation script
|
||||
|
||||
### ❌ DON'T:
|
||||
|
||||
1. **Don't document every element** - Skip trivial getters/setters, private helpers
|
||||
2. **Don't use file names as IDs** - Use meaningful descriptive IDs
|
||||
3. **Don't skip signatures** - Always extract parameter and return types
|
||||
4. **Don't ignore complexity** - High complexity deserves observations
|
||||
5. **Don't miss inheritance** - Always document class hierarchies
|
||||
6. **Don't skip validation** - Always validate generated JSON
|
||||
7. **Don't forget async** - Mark async functions appropriately
|
||||
8. **Don't miss generics** - Document type parameters
|
||||
9. **Don't ignore decorators** - They indicate patterns and behaviors
|
||||
10. **Don't mix abstraction levels** - Keep C4 focused on code, not components
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Element Types
|
||||
class, function, async-function, method, interface, type, constant, variable, enum, decorator, generator, module, namespace
|
||||
|
||||
### Visibility Levels
|
||||
public, private, protected, internal, unknown
|
||||
|
||||
### Observation Categories
|
||||
implementation, error-handling, type-safety, documentation, testing, complexity, performance, security, concurrency, patterns
|
||||
|
||||
### Relation Types
|
||||
calls, returns, imports, inherits, implements, declares, uses-type, depends-on, throws, awaits, creates, mutates, reads, overrides
|
||||
|
||||
### Complexity Thresholds
|
||||
- Cyclomatic: 1-6 (good), 7-10 (warning), >10 (critical)
|
||||
- Cognitive: 0-10 (good), 11-20 (warning), >20 (critical)
|
||||
- Parameters: 0-3 (good), 4-5 (warning), >5 (critical)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
You now have comprehensive knowledge of C4 Model Level 4 (Code) methodology. When invoked:
|
||||
|
||||
1. **Load input data** from `c3-components.json`
|
||||
2. **Analyze each component** to understand structure
|
||||
3. **Identify code elements** (classes, functions, interfaces, types)
|
||||
4. **Extract signatures** (parameters, return types, modifiers)
|
||||
5. **Calculate metrics** (LOC, complexity, nesting)
|
||||
6. **Map relationships** (calls, inherits, implements)
|
||||
7. **Generate observations** with evidence
|
||||
8. **Validate output** before finalizing
|
||||
|
||||
Remember: **C4 is about code implementation.** Focus on WHAT code elements exist, WHAT they do, and HOW they relate - at the most granular level. But be selective - only document significant elements.
|
||||
|
||||
---
|
||||
|
||||
**Skill Version**: 1.0.0
|
||||
**Last Updated**: 2025-11-26
|
||||
**Compatibility**: Melly 1.0.0+
|
||||
343
skills/c4model-c4/code-element-identification.md
Normal file
343
skills/c4model-c4/code-element-identification.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# Code Element Identification Methodology
|
||||
|
||||
This guide provides comprehensive methodology for identifying code elements at the C4 (Code) level of the C4 Model.
|
||||
|
||||
---
|
||||
|
||||
## Code Element Types
|
||||
|
||||
### 1. Classes
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript/JavaScript
|
||||
class ClassName { }
|
||||
export class ClassName { }
|
||||
abstract class ClassName { }
|
||||
export default class ClassName { }
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
class ClassName:
|
||||
pass
|
||||
|
||||
class ClassName(ParentClass):
|
||||
pass
|
||||
|
||||
class ClassName(ABC): # Abstract
|
||||
pass
|
||||
```
|
||||
|
||||
```java
|
||||
// Java
|
||||
public class ClassName { }
|
||||
public abstract class ClassName { }
|
||||
public final class ClassName { }
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{class-name}-class`
|
||||
**Example:** `auth-service-user-manager-class`
|
||||
|
||||
---
|
||||
|
||||
### 2. Functions
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript/JavaScript
|
||||
function functionName() { }
|
||||
export function functionName() { }
|
||||
const functionName = () => { }
|
||||
export const functionName = () => { }
|
||||
export default function functionName() { }
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
def function_name():
|
||||
pass
|
||||
```
|
||||
|
||||
```java
|
||||
// Java - methods are always in classes
|
||||
public static void functionName() { }
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{function-name}`
|
||||
**Example:** `auth-service-validate-token`
|
||||
|
||||
---
|
||||
|
||||
### 3. Async Functions
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript/JavaScript
|
||||
async function functionName() { }
|
||||
export async function functionName() { }
|
||||
const functionName = async () => { }
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
async def function_name():
|
||||
pass
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{function-name}`
|
||||
**Example:** `auth-service-authenticate`
|
||||
|
||||
---
|
||||
|
||||
### 4. Methods
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript/JavaScript - inside class
|
||||
class Example {
|
||||
methodName() { }
|
||||
async methodName() { }
|
||||
private methodName() { }
|
||||
static methodName() { }
|
||||
get propertyName() { }
|
||||
set propertyName(value) { }
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
class Example:
|
||||
def method_name(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def class_method(cls):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def static_method():
|
||||
pass
|
||||
```
|
||||
|
||||
**ID format:** `{class-id}-{method-name}`
|
||||
**Example:** `auth-service-class-get-user`
|
||||
|
||||
---
|
||||
|
||||
### 5. Interfaces
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript
|
||||
interface InterfaceName { }
|
||||
export interface InterfaceName { }
|
||||
interface InterfaceName extends OtherInterface { }
|
||||
```
|
||||
|
||||
```java
|
||||
// Java
|
||||
public interface InterfaceName { }
|
||||
public interface InterfaceName extends OtherInterface { }
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{interface-name}-interface`
|
||||
**Example:** `auth-service-i-user-repository-interface`
|
||||
|
||||
---
|
||||
|
||||
### 6. Types
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript
|
||||
type TypeName = string | number;
|
||||
export type TypeName = { field: string };
|
||||
type TypeName<T> = T[];
|
||||
type TypeName = Pick<OtherType, 'field'>;
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{type-name}-type`
|
||||
**Example:** `auth-service-user-credentials-type`
|
||||
|
||||
---
|
||||
|
||||
### 7. Constants
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript/JavaScript
|
||||
const CONSTANT_NAME = 'value';
|
||||
export const CONSTANT_NAME = 42;
|
||||
export const CONFIG = { ... } as const;
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
CONSTANT_NAME = 'value'
|
||||
MAX_RETRIES = 3
|
||||
```
|
||||
|
||||
```java
|
||||
// Java
|
||||
public static final String CONSTANT_NAME = "value";
|
||||
public static final int MAX_RETRIES = 3;
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{constant-name}-const`
|
||||
**Example:** `auth-service-max-login-attempts-const`
|
||||
|
||||
---
|
||||
|
||||
### 8. Enums
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript
|
||||
enum EnumName { A, B, C }
|
||||
export enum EnumName { A = 'a', B = 'b' }
|
||||
const enum EnumName { A, B, C }
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
from enum import Enum
|
||||
|
||||
class EnumName(Enum):
|
||||
A = 1
|
||||
B = 2
|
||||
```
|
||||
|
||||
```java
|
||||
// Java
|
||||
public enum EnumName { A, B, C }
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{enum-name}-enum`
|
||||
**Example:** `auth-service-user-role-enum`
|
||||
|
||||
---
|
||||
|
||||
### 9. Decorators
|
||||
|
||||
**Detection patterns:**
|
||||
```typescript
|
||||
// TypeScript
|
||||
function DecoratorName(target: any) { }
|
||||
export function DecoratorName(): MethodDecorator { }
|
||||
```
|
||||
|
||||
```python
|
||||
# Python
|
||||
def decorator_name(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
```
|
||||
|
||||
**ID format:** `{component}-{decorator-name}-decorator`
|
||||
**Example:** `auth-service-authenticated-decorator`
|
||||
|
||||
---
|
||||
|
||||
## Significance Criteria
|
||||
|
||||
Only document a code element if **ANY** of these apply:
|
||||
|
||||
### Public API
|
||||
- Exported from module
|
||||
- Part of public interface
|
||||
- Used by external callers
|
||||
|
||||
### Complexity
|
||||
- Lines of code > 20
|
||||
- Cyclomatic complexity > 4
|
||||
- Cognitive complexity > 10
|
||||
|
||||
### Architecture
|
||||
- Implements design pattern
|
||||
- Key abstraction or facade
|
||||
- Entry point or controller action
|
||||
|
||||
### Business Logic
|
||||
- Contains critical business rules
|
||||
- Handles sensitive data
|
||||
- Has security implications
|
||||
|
||||
### Dependencies
|
||||
- Multiple callers (> 2)
|
||||
- Multiple dependencies (> 3)
|
||||
- Central to component
|
||||
|
||||
---
|
||||
|
||||
## Detection Commands
|
||||
|
||||
```bash
|
||||
# TypeScript - Find classes
|
||||
grep -rn "^export class\|^class " src/ --include="*.ts"
|
||||
|
||||
# TypeScript - Find functions
|
||||
grep -rn "^export function\|^export async function\|^export const.*=.*=>" src/ --include="*.ts"
|
||||
|
||||
# TypeScript - Find interfaces
|
||||
grep -rn "^export interface\|^interface " src/ --include="*.ts"
|
||||
|
||||
# TypeScript - Find types
|
||||
grep -rn "^export type\|^type " src/ --include="*.ts"
|
||||
|
||||
# TypeScript - Find enums
|
||||
grep -rn "^export enum\|^enum " src/ --include="*.ts"
|
||||
|
||||
# Python - Find classes
|
||||
grep -rn "^class " src/ --include="*.py"
|
||||
|
||||
# Python - Find functions
|
||||
grep -rn "^def \|^async def " src/ --include="*.py"
|
||||
|
||||
# Count lines per file
|
||||
wc -l src/**/*.ts | sort -n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
### ID Format
|
||||
- Use kebab-case
|
||||
- Include component prefix
|
||||
- Include element type suffix where helpful
|
||||
- Pattern: `{component-id}-{element-name}[-{type}]`
|
||||
|
||||
### Name Field
|
||||
- Preserve original case (PascalCase, camelCase, snake_case)
|
||||
- Use exact name from source code
|
||||
|
||||
### Examples
|
||||
|
||||
| Source Name | ID | name |
|
||||
|------------|-----|------|
|
||||
| `UserService` | `auth-user-service-class` | `UserService` |
|
||||
| `authenticate` | `auth-authenticate` | `authenticate` |
|
||||
| `IUserRepository` | `auth-i-user-repository-interface` | `IUserRepository` |
|
||||
| `LoginCredentials` | `auth-login-credentials-type` | `LoginCredentials` |
|
||||
| `MAX_RETRIES` | `auth-max-retries-const` | `MAX_RETRIES` |
|
||||
| `UserRole` | `auth-user-role-enum` | `UserRole` |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
- Focus on significant, public elements
|
||||
- Use consistent ID naming
|
||||
- Preserve original casing in name field
|
||||
- Document all public API elements
|
||||
- Include classes that define key abstractions
|
||||
|
||||
### ❌ DON'T:
|
||||
- Document every private helper function
|
||||
- Document trivial getters/setters
|
||||
- Document test files as code elements
|
||||
- Use file names as element IDs
|
||||
- Skip exported functions/classes
|
||||
364
skills/c4model-c4/complexity-metrics.md
Normal file
364
skills/c4model-c4/complexity-metrics.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# Complexity Metrics Methodology
|
||||
|
||||
This guide provides methodology for calculating and documenting code complexity metrics at the C4 Code level.
|
||||
|
||||
---
|
||||
|
||||
## Metrics Overview
|
||||
|
||||
| Metric | Description | Threshold |
|
||||
|--------|-------------|-----------|
|
||||
| Lines of Code (LOC) | Actual code lines | Warning: >30, Critical: >50 |
|
||||
| Cyclomatic Complexity | Decision paths | Warning: >6, Critical: >10 |
|
||||
| Cognitive Complexity | Mental effort | Warning: >10, Critical: >20 |
|
||||
| Parameter Count | Function parameters | Warning: >3, Critical: >5 |
|
||||
| Nesting Depth | Max nesting level | Warning: >3, Critical: >5 |
|
||||
|
||||
---
|
||||
|
||||
## Lines of Code (LOC)
|
||||
|
||||
### Definition
|
||||
Count of actual code lines excluding:
|
||||
- Blank lines
|
||||
- Comments
|
||||
- Import statements (debatable)
|
||||
|
||||
### Calculation
|
||||
|
||||
```typescript
|
||||
// Example function - LOC = 8
|
||||
function processOrder(order: Order): ProcessedOrder {
|
||||
const validated = validateOrder(order); // 1
|
||||
if (!validated) { // 2
|
||||
throw new Error('Invalid order'); // 3
|
||||
} // 4
|
||||
const enriched = enrichOrder(validated); // 5
|
||||
const processed = applyRules(enriched); // 6
|
||||
logOrder(processed); // 7
|
||||
return processed; // 8
|
||||
}
|
||||
```
|
||||
|
||||
### Thresholds
|
||||
|
||||
| Range | Rating | Action |
|
||||
|-------|--------|--------|
|
||||
| 1-30 | Good | No action needed |
|
||||
| 31-50 | Warning | Consider extracting methods |
|
||||
| >50 | Critical | Must refactor |
|
||||
|
||||
---
|
||||
|
||||
## Cyclomatic Complexity
|
||||
|
||||
### Definition
|
||||
Number of linearly independent paths through code. Calculated as:
|
||||
- Start with 1
|
||||
- Add 1 for each: `if`, `else if`, `case`, `for`, `while`, `do`, `catch`, `&&`, `||`, `?:`
|
||||
|
||||
### Calculation Example
|
||||
|
||||
```typescript
|
||||
function processPayment(payment: Payment): Result { // CC = 1 (base)
|
||||
if (payment.amount <= 0) { // CC = 2
|
||||
return { error: 'Invalid amount' };
|
||||
}
|
||||
|
||||
if (payment.type === 'credit') { // CC = 3
|
||||
if (payment.amount > 10000) { // CC = 4
|
||||
return { error: 'Amount exceeds limit' };
|
||||
}
|
||||
return processCreditCard(payment);
|
||||
} else if (payment.type === 'debit') { // CC = 5
|
||||
return processDebitCard(payment);
|
||||
} else if (payment.type === 'crypto') { // CC = 6
|
||||
return processCrypto(payment);
|
||||
}
|
||||
|
||||
return { error: 'Unknown payment type' };
|
||||
}
|
||||
// Total Cyclomatic Complexity = 6
|
||||
```
|
||||
|
||||
### Decision Points
|
||||
|
||||
| Construct | Adds |
|
||||
|-----------|------|
|
||||
| `if` | +1 |
|
||||
| `else if` | +1 |
|
||||
| `case` (switch) | +1 per case |
|
||||
| `for` | +1 |
|
||||
| `while` | +1 |
|
||||
| `do...while` | +1 |
|
||||
| `catch` | +1 |
|
||||
| `&&` | +1 |
|
||||
| `||` | +1 |
|
||||
| `?:` (ternary) | +1 |
|
||||
| `?.` (optional chain) | +1 |
|
||||
| `??` (nullish coalesce) | +1 |
|
||||
|
||||
### Thresholds
|
||||
|
||||
| Range | Rating | Interpretation |
|
||||
|-------|--------|----------------|
|
||||
| 1-6 | Good | Simple, easy to test |
|
||||
| 7-10 | Warning | Moderate complexity |
|
||||
| 11-20 | High | Difficult to test |
|
||||
| >20 | Critical | Untestable, must refactor |
|
||||
|
||||
---
|
||||
|
||||
## Cognitive Complexity
|
||||
|
||||
### Definition
|
||||
A metric that measures the mental effort required to understand code. Unlike cyclomatic complexity, it:
|
||||
- Penalizes nesting
|
||||
- Ignores shorthand structures
|
||||
- Focuses on readability
|
||||
|
||||
### Calculation Rules
|
||||
|
||||
1. **Increment for each:**
|
||||
- `if`, `else if`, `else`
|
||||
- `switch`
|
||||
- `for`, `foreach`, `while`, `do`
|
||||
- `catch`
|
||||
- `break`/`continue` to label
|
||||
- Sequences of logical operators
|
||||
|
||||
2. **Nesting penalty:**
|
||||
- Add +1 for each level of nesting when incrementing
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
function example(arr: number[], target: number): number {
|
||||
// Base: 0
|
||||
for (const item of arr) { // +1 (increment)
|
||||
if (item === target) { // +2 (increment + 1 nesting)
|
||||
return item;
|
||||
} else if (item > target) { // +2 (increment + 1 nesting)
|
||||
if (item % 2 === 0) { // +3 (increment + 2 nesting)
|
||||
return item * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
// Total Cognitive Complexity = 8
|
||||
```
|
||||
|
||||
### Thresholds
|
||||
|
||||
| Range | Rating | Action |
|
||||
|-------|--------|--------|
|
||||
| 0-10 | Good | Understandable |
|
||||
| 11-20 | Warning | Getting complex |
|
||||
| >20 | Critical | Hard to understand |
|
||||
|
||||
---
|
||||
|
||||
## Parameter Count
|
||||
|
||||
### Definition
|
||||
Number of parameters a function accepts.
|
||||
|
||||
### Guidelines
|
||||
|
||||
| Count | Rating | Recommendation |
|
||||
|-------|--------|----------------|
|
||||
| 0-3 | Good | Ideal range |
|
||||
| 4-5 | Warning | Consider parameter object |
|
||||
| >5 | Critical | Use parameter object |
|
||||
|
||||
### Refactoring Example
|
||||
|
||||
```typescript
|
||||
// Before: 6 parameters (Critical)
|
||||
function createUser(
|
||||
name: string,
|
||||
email: string,
|
||||
age: number,
|
||||
address: string,
|
||||
phone: string,
|
||||
role: string
|
||||
) { }
|
||||
|
||||
// After: 1 parameter object (Good)
|
||||
interface CreateUserInput {
|
||||
name: string;
|
||||
email: string;
|
||||
age: number;
|
||||
address: string;
|
||||
phone: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
function createUser(input: CreateUserInput) { }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nesting Depth
|
||||
|
||||
### Definition
|
||||
Maximum depth of nested control structures.
|
||||
|
||||
### Calculation
|
||||
|
||||
```typescript
|
||||
function process(data: Data): Result {
|
||||
if (data.valid) { // Depth 1
|
||||
for (const item of data.items) { // Depth 2
|
||||
if (item.active) { // Depth 3
|
||||
try { // Depth 4
|
||||
if (item.type === 'A') { // Depth 5 (Critical!)
|
||||
// ...
|
||||
}
|
||||
} catch (e) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Maximum Nesting Depth = 5
|
||||
```
|
||||
|
||||
### Thresholds
|
||||
|
||||
| Depth | Rating | Action |
|
||||
|-------|--------|--------|
|
||||
| 0-3 | Good | Easy to follow |
|
||||
| 4-5 | Warning | Consider extracting |
|
||||
| >5 | Critical | Must refactor |
|
||||
|
||||
### Refactoring Techniques
|
||||
|
||||
1. **Early returns (guard clauses)**
|
||||
```typescript
|
||||
// Before
|
||||
function process(data) {
|
||||
if (data) {
|
||||
if (data.valid) {
|
||||
// actual logic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After
|
||||
function process(data) {
|
||||
if (!data) return;
|
||||
if (!data.valid) return;
|
||||
// actual logic
|
||||
}
|
||||
```
|
||||
|
||||
2. **Extract nested logic**
|
||||
```typescript
|
||||
// Before
|
||||
for (const item of items) {
|
||||
if (item.active) {
|
||||
if (item.valid) {
|
||||
// complex logic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After
|
||||
function processItem(item) {
|
||||
if (!item.active || !item.valid) return;
|
||||
// complex logic
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
processItem(item);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metrics JSON Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"metrics": {
|
||||
"lines_of_code": 45,
|
||||
"cyclomatic_complexity": 8,
|
||||
"cognitive_complexity": 15,
|
||||
"parameter_count": 3,
|
||||
"nesting_depth": 4
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Threshold Summary Table
|
||||
|
||||
| Metric | Good | Warning | Critical |
|
||||
|--------|------|---------|----------|
|
||||
| LOC | 1-30 | 31-50 | >50 |
|
||||
| Cyclomatic | 1-6 | 7-10 | >10 |
|
||||
| Cognitive | 0-10 | 11-20 | >20 |
|
||||
| Parameters | 0-3 | 4-5 | >5 |
|
||||
| Nesting | 0-3 | 4-5 | >5 |
|
||||
|
||||
---
|
||||
|
||||
## Observation Examples
|
||||
|
||||
### High Complexity Warning
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "obs-auth-service-complexity-01",
|
||||
"category": "complexity",
|
||||
"severity": "warning",
|
||||
"description": "Cyclomatic complexity of 8 exceeds recommended threshold of 6. Consider extracting authentication steps into separate methods.",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/services/auth.ts:45-120",
|
||||
"type": "metric"
|
||||
}
|
||||
],
|
||||
"tags": ["complexity", "refactoring-candidate"]
|
||||
}
|
||||
```
|
||||
|
||||
### Critical Nesting
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "obs-order-processor-nesting-01",
|
||||
"category": "complexity",
|
||||
"severity": "critical",
|
||||
"description": "Maximum nesting depth of 6 makes code difficult to understand. Extract nested logic into helper functions.",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/services/order.ts:78-150",
|
||||
"type": "code",
|
||||
"snippet": "if (order.valid) { for (...) { if (...) { try { if (...) {"
|
||||
}
|
||||
],
|
||||
"tags": ["nesting", "refactoring-required"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
- Calculate all five metrics for functions/methods
|
||||
- Flag any metric exceeding warning threshold
|
||||
- Provide specific refactoring suggestions
|
||||
- Include evidence with line numbers
|
||||
|
||||
### ❌ DON'T:
|
||||
- Skip metrics for simple functions
|
||||
- Ignore nesting depth
|
||||
- Accept critical thresholds without observation
|
||||
- Forget to suggest refactoring approaches
|
||||
317
skills/c4model-c4/observation-guide-c4.md
Normal file
317
skills/c4model-c4/observation-guide-c4.md
Normal file
@@ -0,0 +1,317 @@
|
||||
# Observation Guide for C4 Code Elements
|
||||
|
||||
This guide provides comprehensive methodology for documenting observations at the C4 Code level.
|
||||
|
||||
---
|
||||
|
||||
## Observation Categories
|
||||
|
||||
### 1. **implementation**
|
||||
Code implementation patterns, algorithms, logic flow
|
||||
|
||||
**Examples:**
|
||||
- "Uses async/await pattern for non-blocking database operations"
|
||||
- "Implements retry logic with exponential backoff"
|
||||
- "Uses memoization to cache expensive calculations"
|
||||
- "Implements pagination with cursor-based navigation"
|
||||
- "Uses builder pattern for complex object construction"
|
||||
|
||||
**Evidence types:** code, pattern
|
||||
|
||||
---
|
||||
|
||||
### 2. **error-handling**
|
||||
Exception handling, error propagation, recovery mechanisms
|
||||
|
||||
**Examples:**
|
||||
- "Generic catch block masks specific error types - consider typed error handling"
|
||||
- "Custom error classes with proper error codes and stack traces"
|
||||
- "Missing error handling for null/undefined cases"
|
||||
- "Proper error boundary implementation with fallback UI"
|
||||
- "Silently catches and ignores errors - may hide bugs"
|
||||
|
||||
**Evidence types:** code, pattern
|
||||
|
||||
---
|
||||
|
||||
### 3. **type-safety**
|
||||
Type definitions, generics, type guards, null safety
|
||||
|
||||
**Examples:**
|
||||
- "Uses strict null checks with proper type guards"
|
||||
- "Generic function with proper type constraints"
|
||||
- "Missing type annotation on public API - should be explicit"
|
||||
- "Type narrowing with discriminated unions for safe handling"
|
||||
- "Uses `any` type extensively - reduces type safety benefits"
|
||||
|
||||
**Evidence types:** code, pattern
|
||||
|
||||
---
|
||||
|
||||
### 4. **documentation**
|
||||
JSDoc, docstrings, inline comments, API documentation
|
||||
|
||||
**Examples:**
|
||||
- "Comprehensive JSDoc with @param, @returns, and @example"
|
||||
- "Missing documentation for complex algorithm - add explanatory comments"
|
||||
- "Inline comments explain business logic decisions"
|
||||
- "API endpoint documentation includes request/response examples"
|
||||
- "Outdated comments don't match current implementation"
|
||||
|
||||
**Evidence types:** documentation, code
|
||||
|
||||
---
|
||||
|
||||
### 5. **testing**
|
||||
Test coverage, testability, mocking concerns
|
||||
|
||||
**Examples:**
|
||||
- "90% test coverage with edge cases covered"
|
||||
- "Hard to test due to static dependencies - consider dependency injection"
|
||||
- "Proper use of dependency injection improves testability"
|
||||
- "Missing tests for error paths and edge cases"
|
||||
- "Test file exists but only covers happy path"
|
||||
|
||||
**Evidence types:** test, code
|
||||
|
||||
---
|
||||
|
||||
### 6. **complexity**
|
||||
Cyclomatic complexity, cognitive complexity, nesting depth
|
||||
|
||||
**Examples:**
|
||||
- "Cyclomatic complexity of 15 exceeds threshold (6) - extract methods"
|
||||
- "Deep nesting (5 levels) reduces readability - use guard clauses"
|
||||
- "Function has 8 parameters - consider parameter object pattern"
|
||||
- "Method is 150 LOC - split into smaller focused functions"
|
||||
- "Single method handles multiple responsibilities - violates SRP"
|
||||
|
||||
**Evidence types:** metric, code
|
||||
|
||||
---
|
||||
|
||||
### 7. **performance**
|
||||
Algorithm efficiency, memory usage, async patterns
|
||||
|
||||
**Examples:**
|
||||
- "O(n²) algorithm could be optimized to O(n log n)"
|
||||
- "Memory leak: event listener not removed on cleanup"
|
||||
- "Unnecessary database queries in loop - use batch query"
|
||||
- "Proper use of lazy loading for large data sets"
|
||||
- "Missing debounce on rapid event handler"
|
||||
|
||||
**Evidence types:** code, metric, pattern
|
||||
|
||||
---
|
||||
|
||||
### 8. **security**
|
||||
Input validation, sanitization, authentication, authorization
|
||||
|
||||
**Examples:**
|
||||
- "Missing input validation on user-provided data"
|
||||
- "SQL query properly parameterized against injection"
|
||||
- "Password stored with bcrypt hashing (cost factor 12)"
|
||||
- "Sensitive data logged in debug output - security risk"
|
||||
- "Authorization check missing before data access"
|
||||
|
||||
**Evidence types:** code, pattern
|
||||
|
||||
---
|
||||
|
||||
### 9. **concurrency**
|
||||
Async/await, promises, race conditions, thread safety
|
||||
|
||||
**Examples:**
|
||||
- "Potential race condition in concurrent state updates"
|
||||
- "Proper use of Promise.all for parallel independent requests"
|
||||
- "Missing await on async function call - returns Promise instead of value"
|
||||
- "Deadlock potential with multiple lock acquisitions"
|
||||
- "Uses mutex pattern for thread-safe resource access"
|
||||
|
||||
**Evidence types:** code, pattern
|
||||
|
||||
---
|
||||
|
||||
### 10. **patterns**
|
||||
Design patterns, code patterns, anti-patterns
|
||||
|
||||
**Examples:**
|
||||
- "Factory pattern used for creating validator instances"
|
||||
- "God object anti-pattern - class has too many responsibilities"
|
||||
- "Proper use of strategy pattern for payment processing"
|
||||
- "Singleton pattern ensures single database connection pool"
|
||||
- "Repository pattern cleanly separates data access concerns"
|
||||
|
||||
**Evidence types:** pattern, code
|
||||
|
||||
---
|
||||
|
||||
## Observation Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "obs-{element-id}-{category}-{number}",
|
||||
"category": "implementation|error-handling|type-safety|documentation|testing|complexity|performance|security|concurrency|patterns",
|
||||
"severity": "info|warning|critical",
|
||||
"description": "Clear, actionable description of the observation",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/path/to/file.ts:45-67",
|
||||
"type": "code|metric|pattern|test|documentation",
|
||||
"snippet": "Optional relevant code snippet"
|
||||
}
|
||||
],
|
||||
"tags": ["relevant", "searchable", "tags"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Severity Guidelines
|
||||
|
||||
### ℹ️ info
|
||||
Use for:
|
||||
- Best practices being followed
|
||||
- Interesting implementation details
|
||||
- Documentation notes
|
||||
- Positive observations
|
||||
|
||||
**Examples:**
|
||||
- "Uses dependency injection for loose coupling"
|
||||
- "Well-documented API with comprehensive JSDoc"
|
||||
- "Implements singleton pattern correctly"
|
||||
|
||||
---
|
||||
|
||||
### ⚠️ warning
|
||||
Use for:
|
||||
- Potential issues that should be addressed
|
||||
- Technical debt
|
||||
- Performance concerns
|
||||
- Missing tests
|
||||
- Minor security considerations
|
||||
|
||||
**Examples:**
|
||||
- "Cyclomatic complexity exceeds threshold"
|
||||
- "Missing input validation on internal API"
|
||||
- "No tests for edge cases"
|
||||
- "Consider using more specific error types"
|
||||
|
||||
---
|
||||
|
||||
### 🔴 critical
|
||||
Use for:
|
||||
- Security vulnerabilities
|
||||
- Breaking bugs
|
||||
- Data loss potential
|
||||
- Production-impacting issues
|
||||
- Immediate action required
|
||||
|
||||
**Examples:**
|
||||
- "SQL injection vulnerability - user input not sanitized"
|
||||
- "Unhandled promise rejection crashes application"
|
||||
- "Sensitive data exposed in logs"
|
||||
- "Race condition causes data corruption"
|
||||
|
||||
---
|
||||
|
||||
## Evidence Types
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| `code` | Code snippet or reference | `"snippet": "if (user.role === 'admin')"` |
|
||||
| `metric` | Calculated metric value | Complexity score, LOC count |
|
||||
| `pattern` | Design pattern identification | Factory, Singleton, Repository |
|
||||
| `test` | Test file or coverage info | Test file location |
|
||||
| `documentation` | Doc reference | JSDoc, README section |
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
```json
|
||||
{
|
||||
"observations": [
|
||||
{
|
||||
"id": "obs-auth-service-security-01",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"description": "Password comparison uses timing-vulnerable equality check. Use constant-time comparison to prevent timing attacks.",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/services/auth.ts:78",
|
||||
"type": "code",
|
||||
"snippet": "if (password === storedPassword)"
|
||||
}
|
||||
],
|
||||
"tags": ["security", "timing-attack", "authentication"]
|
||||
},
|
||||
{
|
||||
"id": "obs-auth-service-patterns-01",
|
||||
"category": "patterns",
|
||||
"severity": "info",
|
||||
"description": "Implements repository pattern for data access, providing clean separation between business logic and persistence.",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/services/auth.ts:15-20",
|
||||
"type": "pattern"
|
||||
}
|
||||
],
|
||||
"tags": ["repository-pattern", "clean-architecture"]
|
||||
},
|
||||
{
|
||||
"id": "obs-auth-service-complexity-01",
|
||||
"category": "complexity",
|
||||
"severity": "warning",
|
||||
"description": "Authenticate method has cyclomatic complexity of 12, exceeding recommended threshold of 6. Consider extracting validation and token generation into separate methods.",
|
||||
"evidence": [
|
||||
{
|
||||
"location": "src/services/auth.ts:45-120",
|
||||
"type": "metric"
|
||||
}
|
||||
],
|
||||
"tags": ["complexity", "refactoring-candidate"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Writing Good Observations
|
||||
|
||||
### ✅ DO:
|
||||
- Be specific and actionable
|
||||
- Include exact file paths and line numbers
|
||||
- Provide code snippets for context
|
||||
- Use appropriate severity levels
|
||||
- Include relevant tags for searchability
|
||||
- Suggest fixes for warnings/critical issues
|
||||
|
||||
### ❌ DON'T:
|
||||
- Be vague ("code is complex")
|
||||
- Skip evidence
|
||||
- Overuse critical severity
|
||||
- Write observations without actionable insight
|
||||
- Forget to tag important categories
|
||||
- Mix multiple issues in one observation
|
||||
|
||||
---
|
||||
|
||||
## Tags Reference
|
||||
|
||||
Common useful tags:
|
||||
|
||||
**Architecture:** `clean-architecture`, `hexagonal`, `layered`, `microservices`
|
||||
|
||||
**Patterns:** `singleton`, `factory`, `repository`, `strategy`, `observer`, `decorator`
|
||||
|
||||
**Anti-patterns:** `god-object`, `spaghetti-code`, `magic-numbers`, `primitive-obsession`
|
||||
|
||||
**Quality:** `refactoring-candidate`, `technical-debt`, `needs-review`
|
||||
|
||||
**Security:** `input-validation`, `authentication`, `authorization`, `sql-injection`, `xss`
|
||||
|
||||
**Performance:** `n-plus-one`, `memory-leak`, `optimization-candidate`
|
||||
|
||||
**Testing:** `needs-tests`, `integration-test`, `unit-test`, `edge-cases`
|
||||
442
skills/c4model-c4/relation-types-c4.md
Normal file
442
skills/c4model-c4/relation-types-c4.md
Normal file
@@ -0,0 +1,442 @@
|
||||
# Relation Types for C4 Code Elements
|
||||
|
||||
This guide provides comprehensive documentation of relationship types between code elements at the C4 Code level.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Relations describe how code elements interact with each other. Each relation has:
|
||||
- **target**: The code element being related to
|
||||
- **type**: The nature of the relationship
|
||||
- **description**: Active voice description of the relationship
|
||||
|
||||
---
|
||||
|
||||
## Code Flow Relations
|
||||
|
||||
### calls
|
||||
**Definition:** Invokes another function or method
|
||||
|
||||
**When to use:** When a function/method directly calls another
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function processOrder(order: Order) {
|
||||
validateOrder(order); // calls validateOrder
|
||||
calculateTotal(order); // calls calculateTotal
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "validate-order",
|
||||
"type": "calls",
|
||||
"description": "Calls validateOrder to validate order structure"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### awaits
|
||||
**Definition:** Awaits an async function
|
||||
|
||||
**When to use:** When async function awaits another async function
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
async function getUser(id: string) {
|
||||
const user = await userRepository.findById(id); // awaits findById
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-repository-find-by-id",
|
||||
"type": "awaits",
|
||||
"description": "Awaits UserRepository.findById for user lookup"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### returns
|
||||
**Definition:** Returns a specific type
|
||||
|
||||
**When to use:** When documenting what type a function returns
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function createUser(data: UserInput): User {
|
||||
return new User(data); // returns User
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-class",
|
||||
"type": "returns",
|
||||
"description": "Returns User instance with provided data"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### throws
|
||||
**Definition:** Throws an exception type
|
||||
|
||||
**When to use:** When function explicitly throws an exception
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function validateAge(age: number) {
|
||||
if (age < 0) {
|
||||
throw new ValidationError('Age cannot be negative'); // throws ValidationError
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "validation-error-class",
|
||||
"type": "throws",
|
||||
"description": "Throws ValidationError when age is negative"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structural Relations
|
||||
|
||||
### inherits
|
||||
**Definition:** Extends another class
|
||||
|
||||
**When to use:** When a class extends a parent class
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
class AdminUser extends User { // inherits from User
|
||||
permissions: string[];
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-class",
|
||||
"type": "inherits",
|
||||
"description": "Inherits from User base class"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### implements
|
||||
**Definition:** Implements an interface
|
||||
|
||||
**When to use:** When a class implements an interface contract
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
class UserService implements IUserService { // implements IUserService
|
||||
getUser(id: string): User { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "i-user-service-interface",
|
||||
"type": "implements",
|
||||
"description": "Implements IUserService interface contract"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### declares
|
||||
**Definition:** Declares a type or interface
|
||||
|
||||
**When to use:** When defining the shape of data used elsewhere
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
interface UserInput { // declares shape for createUser
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
function createUser(input: UserInput) { ... }
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "create-user-function",
|
||||
"type": "declares",
|
||||
"description": "Declares the input shape for createUser function"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### uses-type
|
||||
**Definition:** Uses a type in signature or body
|
||||
|
||||
**When to use:** When function uses a type for parameters, return, or internally
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function processPayment(payment: Payment): PaymentResult {
|
||||
// Uses Payment type for input
|
||||
// Uses PaymentResult type for output
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "payment-type",
|
||||
"type": "uses-type",
|
||||
"description": "Uses Payment type for input parameter"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Relations
|
||||
|
||||
### creates
|
||||
**Definition:** Instantiates a class
|
||||
|
||||
**When to use:** When function creates new instance of a class
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function createOrder(items: Item[]): Order {
|
||||
return new Order(items); // creates Order instance
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "order-class",
|
||||
"type": "creates",
|
||||
"description": "Creates new Order instance with provided items"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### mutates
|
||||
**Definition:** Modifies state or data
|
||||
|
||||
**When to use:** When function modifies object state
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function updateUser(user: User, data: Partial<User>) {
|
||||
Object.assign(user, data); // mutates user object
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-class",
|
||||
"type": "mutates",
|
||||
"description": "Mutates User instance with provided data"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### reads
|
||||
**Definition:** Reads from data source
|
||||
|
||||
**When to use:** When function reads data without modifying
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
function getUserName(user: User): string {
|
||||
return user.name; // reads from User
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-class",
|
||||
"type": "reads",
|
||||
"description": "Reads name property from User instance"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Relations
|
||||
|
||||
### imports
|
||||
**Definition:** Imports from another module
|
||||
|
||||
**When to use:** When code imports from another file/module
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
import { UserService } from './services/user'; // imports UserService
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-service-class",
|
||||
"type": "imports",
|
||||
"description": "Imports UserService from services module"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### depends-on
|
||||
**Definition:** General dependency relationship
|
||||
|
||||
**When to use:** When there's a dependency that doesn't fit other categories
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
class OrderService {
|
||||
constructor(
|
||||
private userService: UserService, // depends-on UserService
|
||||
private paymentService: PaymentService // depends-on PaymentService
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-service-class",
|
||||
"type": "depends-on",
|
||||
"description": "Depends on UserService for user operations"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### overrides
|
||||
**Definition:** Overrides parent class method
|
||||
|
||||
**When to use:** When method overrides a parent method
|
||||
|
||||
**Examples:**
|
||||
```typescript
|
||||
class AdminUser extends User {
|
||||
override toString(): string { // overrides User.toString
|
||||
return `Admin: ${this.name}`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**JSON:**
|
||||
```json
|
||||
{
|
||||
"target": "user-class-to-string",
|
||||
"type": "overrides",
|
||||
"description": "Overrides User.toString to include admin prefix"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Relation Type Summary
|
||||
|
||||
| Type | Category | Description |
|
||||
|------|----------|-------------|
|
||||
| `calls` | Code Flow | Invokes function/method |
|
||||
| `awaits` | Code Flow | Awaits async function |
|
||||
| `returns` | Code Flow | Returns specific type |
|
||||
| `throws` | Code Flow | Throws exception |
|
||||
| `inherits` | Structural | Extends class |
|
||||
| `implements` | Structural | Implements interface |
|
||||
| `declares` | Structural | Declares type/interface |
|
||||
| `uses-type` | Structural | Uses type in signature |
|
||||
| `creates` | Data | Instantiates class |
|
||||
| `mutates` | Data | Modifies state |
|
||||
| `reads` | Data | Reads data |
|
||||
| `imports` | Dependency | Imports from module |
|
||||
| `depends-on` | Dependency | General dependency |
|
||||
| `overrides` | Dependency | Overrides parent method |
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
```json
|
||||
{
|
||||
"relations": [
|
||||
{
|
||||
"target": "base-service-class",
|
||||
"type": "inherits",
|
||||
"description": "Inherits common service functionality from BaseService"
|
||||
},
|
||||
{
|
||||
"target": "i-user-service-interface",
|
||||
"type": "implements",
|
||||
"description": "Implements IUserService interface contract"
|
||||
},
|
||||
{
|
||||
"target": "user-repository",
|
||||
"type": "depends-on",
|
||||
"description": "Depends on UserRepository for data persistence"
|
||||
},
|
||||
{
|
||||
"target": "user-repository-find-by-id",
|
||||
"type": "awaits",
|
||||
"description": "Awaits UserRepository.findById for user lookup"
|
||||
},
|
||||
{
|
||||
"target": "user-class",
|
||||
"type": "returns",
|
||||
"description": "Returns User instance to caller"
|
||||
},
|
||||
{
|
||||
"target": "user-not-found-error",
|
||||
"type": "throws",
|
||||
"description": "Throws UserNotFoundError when user doesn't exist"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
- Use active voice in descriptions
|
||||
- Be specific about what is being called/used
|
||||
- Document all significant relationships
|
||||
- Use the most specific relation type
|
||||
|
||||
### ❌ DON'T:
|
||||
- Use passive voice ("is called by")
|
||||
- Skip obvious but important relations
|
||||
- Use generic descriptions
|
||||
- Mix relation types inappropriately
|
||||
|
||||
---
|
||||
|
||||
## Relation Direction
|
||||
|
||||
All relations are **outbound** from the source element:
|
||||
- Source element → **calls** → Target element
|
||||
- Source element → **inherits** → Target element
|
||||
- Source element → **depends-on** → Target element
|
||||
|
||||
Do NOT document reverse relations (e.g., "is called by"). The target element's incoming relations can be derived from the source elements' outbound relations.
|
||||
314
skills/c4model-c4/signature-analysis.md
Normal file
314
skills/c4model-c4/signature-analysis.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Signature Analysis Methodology
|
||||
|
||||
This guide provides methodology for extracting and documenting function, method, and interface signatures at the C4 Code level.
|
||||
|
||||
---
|
||||
|
||||
## Parameter Extraction
|
||||
|
||||
### Required Information
|
||||
|
||||
For each parameter, extract:
|
||||
|
||||
| Field | Description | Example |
|
||||
|-------|-------------|---------|
|
||||
| `name` | Parameter name (original case) | `userId`, `options` |
|
||||
| `type` | Full type including generics | `string`, `UserOptions<T>` |
|
||||
| `optional` | Whether parameter is optional | `true`, `false` |
|
||||
| `default` | Default value if any | `{}`, `null`, `10` |
|
||||
|
||||
### TypeScript Examples
|
||||
|
||||
```typescript
|
||||
// Required parameter
|
||||
function getUser(userId: string) { }
|
||||
// → { name: "userId", type: "string", optional: false }
|
||||
|
||||
// Optional parameter
|
||||
function getUser(userId: string, includeDeleted?: boolean) { }
|
||||
// → { name: "includeDeleted", type: "boolean", optional: true }
|
||||
|
||||
// Default parameter
|
||||
function getUsers(limit: number = 10) { }
|
||||
// → { name: "limit", type: "number", optional: true, default: "10" }
|
||||
|
||||
// Generic parameter
|
||||
function transform<T>(input: T[]): T { }
|
||||
// → { name: "input", type: "T[]", optional: false }
|
||||
|
||||
// Object destructuring
|
||||
function create({ name, age }: UserInput) { }
|
||||
// → { name: "{ name, age }", type: "UserInput", optional: false }
|
||||
|
||||
// Rest parameters
|
||||
function concat(...items: string[]) { }
|
||||
// → { name: "...items", type: "string[]", optional: false }
|
||||
```
|
||||
|
||||
### Python Examples
|
||||
|
||||
```python
|
||||
# Required parameter
|
||||
def get_user(user_id: str) -> User:
|
||||
# → { name: "user_id", type: "str", optional: false }
|
||||
|
||||
# Optional parameter (with default)
|
||||
def get_users(limit: int = 10) -> List[User]:
|
||||
# → { name: "limit", type: "int", optional: true, default: "10" }
|
||||
|
||||
# Optional type hint
|
||||
def find_user(user_id: Optional[str]) -> Optional[User]:
|
||||
# → { name: "user_id", type: "Optional[str]", optional: false }
|
||||
|
||||
# *args and **kwargs
|
||||
def call_api(*args, **kwargs):
|
||||
# → { name: "*args", type: "Any", optional: true }
|
||||
# → { name: "**kwargs", type: "Any", optional: true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Return Type Analysis
|
||||
|
||||
### TypeScript Return Types
|
||||
|
||||
```typescript
|
||||
// Simple return
|
||||
function getName(): string { }
|
||||
// → return_type: "string"
|
||||
|
||||
// Promise return (async)
|
||||
async function getUser(): Promise<User> { }
|
||||
// → return_type: "Promise<User>", async: true
|
||||
|
||||
// Void return
|
||||
function logMessage(msg: string): void { }
|
||||
// → return_type: "void"
|
||||
|
||||
// Union return
|
||||
function find(): User | null { }
|
||||
// → return_type: "User | null"
|
||||
|
||||
// Generic return
|
||||
function first<T>(arr: T[]): T | undefined { }
|
||||
// → return_type: "T | undefined"
|
||||
|
||||
// No explicit return (inferred)
|
||||
function calculate() { return 42; }
|
||||
// → return_type: "number" (inferred)
|
||||
```
|
||||
|
||||
### Python Return Types
|
||||
|
||||
```python
|
||||
# Simple return
|
||||
def get_name() -> str:
|
||||
# → return_type: "str"
|
||||
|
||||
# Optional return
|
||||
def find_user() -> Optional[User]:
|
||||
# → return_type: "Optional[User]"
|
||||
|
||||
# Async return
|
||||
async def get_user() -> User:
|
||||
# → return_type: "User", async: true
|
||||
|
||||
# No return type (None)
|
||||
def log_message(msg: str) -> None:
|
||||
# → return_type: "None"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Async Detection
|
||||
|
||||
### Patterns to Detect
|
||||
|
||||
| Language | Pattern | Example |
|
||||
|----------|---------|---------|
|
||||
| TypeScript | `async` keyword | `async function fetchData()` |
|
||||
| TypeScript | Returns `Promise<T>` | `function fetch(): Promise<Data>` |
|
||||
| Python | `async def` | `async def fetch_data():` |
|
||||
| Java | Returns `CompletableFuture<T>` | `CompletableFuture<Data> fetchData()` |
|
||||
|
||||
### Examples
|
||||
|
||||
```typescript
|
||||
// Explicit async
|
||||
async function fetchUser(id: string): Promise<User> { }
|
||||
// → async: true, return_type: "Promise<User>"
|
||||
|
||||
// Returns Promise but not async keyword
|
||||
function fetchUser(id: string): Promise<User> {
|
||||
return fetch(`/users/${id}`).then(r => r.json());
|
||||
}
|
||||
// → async: false, return_type: "Promise<User>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Generic Type Parameters
|
||||
|
||||
### Extracting Generics
|
||||
|
||||
```typescript
|
||||
// Single generic
|
||||
function identity<T>(value: T): T { }
|
||||
// → generic_params: ["T"]
|
||||
|
||||
// Multiple generics
|
||||
function map<T, U>(arr: T[], fn: (item: T) => U): U[] { }
|
||||
// → generic_params: ["T", "U"]
|
||||
|
||||
// Constrained generic
|
||||
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { }
|
||||
// → generic_params: ["T", "K extends keyof T"]
|
||||
|
||||
// Default generic
|
||||
function createArray<T = string>(length: number): T[] { }
|
||||
// → generic_params: ["T = string"]
|
||||
```
|
||||
|
||||
### Python Generics
|
||||
|
||||
```python
|
||||
from typing import TypeVar, Generic
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
def identity(value: T) -> T:
|
||||
return value
|
||||
# → generic_params: ["T"]
|
||||
|
||||
class Container(Generic[T]):
|
||||
def get(self) -> T: ...
|
||||
# → generic_params: ["T"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Decorator Extraction
|
||||
|
||||
### TypeScript/JavaScript Decorators
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
@Singleton()
|
||||
class UserService { }
|
||||
// → decorators: ["@Injectable()", "@Singleton()"]
|
||||
|
||||
@Get('/users/:id')
|
||||
@UseGuards(AuthGuard)
|
||||
async getUser(@Param('id') id: string) { }
|
||||
// → decorators: ["@Get('/users/:id')", "@UseGuards(AuthGuard)"]
|
||||
```
|
||||
|
||||
### Python Decorators
|
||||
|
||||
```python
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> 'User':
|
||||
# → decorators: ["@classmethod"]
|
||||
|
||||
@staticmethod
|
||||
def validate(data: dict) -> bool:
|
||||
# → decorators: ["@staticmethod"]
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
# → decorators: ["@property"]
|
||||
|
||||
@app.route('/users/<id>')
|
||||
@require_auth
|
||||
def get_user(id: str):
|
||||
# → decorators: ["@app.route('/users/<id>')", "@require_auth"]
|
||||
```
|
||||
|
||||
### Java Annotations
|
||||
|
||||
```java
|
||||
@Override
|
||||
public String toString() { }
|
||||
// → decorators: ["@Override"]
|
||||
|
||||
@GetMapping("/users/{id}")
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
public User getUser(@PathVariable String id) { }
|
||||
// → decorators: ["@GetMapping(\"/users/{id}\")", "@PreAuthorize(\"hasRole('USER')\")"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Visibility Modifiers
|
||||
|
||||
### TypeScript/JavaScript
|
||||
|
||||
| Modifier | Visibility |
|
||||
|----------|------------|
|
||||
| `public` | public |
|
||||
| `private` | private |
|
||||
| `protected` | protected |
|
||||
| `#field` (private field) | private |
|
||||
| (no modifier) | public |
|
||||
|
||||
### Python
|
||||
|
||||
| Pattern | Visibility |
|
||||
|---------|------------|
|
||||
| `_method` | internal (convention) |
|
||||
| `__method` | private (name mangling) |
|
||||
| (no prefix) | public |
|
||||
|
||||
### Java
|
||||
|
||||
| Modifier | Visibility |
|
||||
|----------|------------|
|
||||
| `public` | public |
|
||||
| `private` | private |
|
||||
| `protected` | protected |
|
||||
| (package-private) | internal |
|
||||
|
||||
---
|
||||
|
||||
## Complete Signature Example
|
||||
|
||||
```json
|
||||
{
|
||||
"signature": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"type": "GetUserOptions",
|
||||
"optional": true,
|
||||
"default": "{}"
|
||||
}
|
||||
],
|
||||
"return_type": "Promise<User>",
|
||||
"async": true,
|
||||
"generic_params": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
- Extract full type information including generics
|
||||
- Note optional parameters and defaults
|
||||
- Identify async functions correctly
|
||||
- Preserve exact decorator syntax
|
||||
- Document visibility modifiers
|
||||
|
||||
### ❌ DON'T:
|
||||
- Skip type information
|
||||
- Ignore generic parameters
|
||||
- Miss async/Promise patterns
|
||||
- Forget decorators that indicate behavior
|
||||
- Assume visibility without checking
|
||||
Reference in New Issue
Block a user