Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:17:07 +08:00
commit c0cd55ad8d
55 changed files with 15836 additions and 0 deletions

341
skills/c4model-c4/SKILL.md Normal file
View 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+

View 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

View 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

View 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`

View 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.

View 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