Initial commit
This commit is contained in:
231
skills/c4model-c3/SKILL.md
Normal file
231
skills/c4model-c3/SKILL.md
Normal file
@@ -0,0 +1,231 @@
|
||||
---
|
||||
name: c4model-c3
|
||||
description: Expert methodology for C4 Model Level 3 (Component) analysis - identifying code-level components, their responsibilities, dependencies, and design patterns within containers. Use when analyzing component architecture, mapping code structure, detecting design patterns, identifying component boundaries and responsibilities, analyzing coupling and cohesion, or documenting components after C2 container identification. Essential for c3-abstractor agent during component identification phase.
|
||||
---
|
||||
|
||||
# C4 Model - Level 3: Component Methodology
|
||||
|
||||
## Overview
|
||||
|
||||
You are an expert in the C4 Model's Level 3 (Component) methodology. This skill provides comprehensive knowledge for identifying and documenting software components at the code-level architectural abstraction.
|
||||
|
||||
**Your Mission:** Help identify WHAT code components exist within containers, WHAT responsibilities they have, and HOW they interact - with focus on design patterns and code structure.
|
||||
|
||||
### C3 Level Definition
|
||||
|
||||
The Component level shows the **internal structure** of containers - the major code building blocks:
|
||||
|
||||
- **Components** - Code modules, classes, packages with clear responsibilities
|
||||
- **Responsibilities** - What each component does (single responsibility)
|
||||
- **Dependencies** - How components depend on each other
|
||||
- **Patterns** - Design patterns and architectural patterns used
|
||||
- **Boundaries** - Package boundaries, module boundaries, layer boundaries
|
||||
|
||||
**At C3, we focus on:** Component identification and naming, responsibilities (single responsibility), dependencies and coupling, design patterns and architectural patterns, code organization, layer boundaries, component interactions.
|
||||
|
||||
**At C3, we do NOT focus on:** Individual functions/methods (C4), line-by-line code (C4), variable names and implementation details (C4), deployment details (C2).
|
||||
|
||||
---
|
||||
|
||||
## Detailed References
|
||||
|
||||
For comprehensive guidance on specific aspects of C3 component analysis, see:
|
||||
|
||||
- **[Component Identification](./component-identification.md)** - Component types, detection rules, boundaries, file structure patterns, responsibility analysis
|
||||
- **[Dependency Analysis](./dependency-analysis.md)** - Dependency types, coupling analysis, circular dependencies, metrics, direction validation
|
||||
- **[Pattern Detection](./pattern-detection.md)** - Design patterns (Singleton, Factory, Repository, etc.) and architectural patterns (MVC, Hexagonal, CQRS, etc.)
|
||||
- **[Observation Guide](./observation-guide.md)** - Observation categories, severity levels, structure, evidence collection, quality metrics
|
||||
- **[Technology Examples](./technology-examples.md)** - NestJS, Django, Spring Boot, React implementation examples and patterns
|
||||
- **[Component Template](./templates/c3-component-template.json)** - JSON template for c3-components.json output
|
||||
|
||||
These references are loaded progressively when needed for detailed analysis.
|
||||
|
||||
---
|
||||
|
||||
## Component Identification Summary
|
||||
|
||||
A **component** at C3 level is a cohesive code module with clear responsibility - such as a collection of related classes/functions, an architectural building block, or a distinct layer/subsystem. Components include Controllers (HTTP handlers), Services (business logic), Repositories (data access), Models (data structures), Middleware (request processing), Utilities (helpers), DTOs (data transfer objects), and Adapters (external integrations).
|
||||
|
||||
**Key principles:** Focus on significant modules (>200 LOC or architecturally important), one primary responsibility per component (Single Responsibility Principle), group related code together (packages, modules, directories), avoid listing every file.
|
||||
|
||||
For complete methodology, see [component-identification.md](./component-identification.md).
|
||||
|
||||
---
|
||||
|
||||
## Dependency Analysis Summary
|
||||
|
||||
Component dependencies reveal the architecture's coupling and maintainability. Analyze internal dependencies (within container), external dependencies (libraries, frameworks), and framework dependencies. Validate dependency direction follows proper layering (Controllers → Services → Repositories → Models).
|
||||
|
||||
**Key metrics:** Afferent Coupling (Ca), Efferent Coupling (Ce), Instability (I = Ce / (Ca + Ce)), Circular Dependencies.
|
||||
|
||||
For complete methodology, see [dependency-analysis.md](./dependency-analysis.md).
|
||||
|
||||
---
|
||||
|
||||
## Pattern Detection Summary
|
||||
|
||||
Design patterns indicate architectural decisions and code quality. Detect Singleton, Factory, Repository, Dependency Injection, Observer, Strategy, Decorator, and Adapter patterns. Architectural patterns include MVC, Layered Architecture, Hexagonal, CQRS, Microkernel, and Event-Driven.
|
||||
|
||||
For complete methodology, see [pattern-detection.md](./pattern-detection.md).
|
||||
|
||||
---
|
||||
|
||||
## Observation Categories
|
||||
|
||||
Document findings using these categories: code-structure, design-patterns, dependencies, complexity, coupling, cohesion, testing, documentation.
|
||||
|
||||
**Severity levels:** ℹ️ info (informational), ⚠️ warning (potential issue), 🔴 critical (critical issue).
|
||||
|
||||
For complete guide, see [observation-guide.md](./observation-guide.md).
|
||||
|
||||
---
|
||||
|
||||
## Integration with Melly Workflow
|
||||
|
||||
### When This Skill is Used
|
||||
|
||||
This skill is activated during **Phase 3: C3 Component Identification** (`/melly-c3-components`) for component identification, responsibility analysis, dependency mapping, and pattern detection. Also used in **Phase 5: Documentation** (`/melly-doc-c4model`) for markdown generation.
|
||||
|
||||
### Input Expectations
|
||||
|
||||
Expects data from `c2-containers.json` with container details including id, name, type, system_id, path, technology (runtime, framework, language), and structure (entry_point, source_directory, build_output).
|
||||
|
||||
### Output Format
|
||||
|
||||
Generates `c3-components.json` with metadata (schema_version, generator, timestamp, parent_timestamp), components array (id, name, type, container_id, path, description, responsibilities, layer, dependencies, observations, relations, metrics), and summary (total_components, by_type, by_layer).
|
||||
|
||||
### Validation
|
||||
|
||||
Generated output must pass: Schema validation, timestamp ordering (metadata.timestamp > parent_timestamp), referential integrity (all dependency targets exist), required fields, ID format (kebab-case), container reference validation.
|
||||
|
||||
Validation script:
|
||||
```bash
|
||||
python ${CLAUDE_PLUGIN_ROOT}/validation/scripts/validate-c3-components.py c3-components.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Workflow
|
||||
|
||||
### Systematic Approach for c3-abstractor Agent
|
||||
|
||||
**Step 1: Load Input Data**
|
||||
```bash
|
||||
cat c2-containers.json | jq '.containers'
|
||||
```
|
||||
|
||||
**Step 2: Analyze Each Container**
|
||||
Navigate to container path, understand directory structure, identify organization pattern (feature-based, layer-based, domain-driven).
|
||||
|
||||
**Step 3: Identify Components**
|
||||
Analyze files/directories, determine component type, extract responsibilities, identify dependencies.
|
||||
|
||||
**Step 4: Map Dependencies**
|
||||
Find internal dependencies (within container), external dependencies (npm packages), document relationships.
|
||||
|
||||
**Step 5: Detect Patterns**
|
||||
Search for design patterns (Singleton, Factory, Repository, Dependency Injection), identify architectural pattern.
|
||||
|
||||
**Step 6: Generate Observations**
|
||||
Document code structure, design patterns, dependencies, complexity, and quality findings.
|
||||
|
||||
**Step 7: Calculate Metrics**
|
||||
Count lines of code, cyclomatic complexity, dependency count, public methods count.
|
||||
|
||||
**Step 8: Validate Output**
|
||||
Check component IDs (kebab-case, unique), container references, dependencies (all targets exist), timestamps (child > parent), run validation script.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
|
||||
1. **Identify significant components only** - Focus on major building blocks, avoid listing every file
|
||||
2. **Use clear component names** - "User Service" not "userService.ts"
|
||||
3. **Define single responsibility** - Each component has one clear purpose
|
||||
4. **Document dependencies clearly** - Internal vs external, purpose of each
|
||||
5. **Detect design patterns** - Singleton, Factory, Repository, etc.
|
||||
6. **Analyze code structure** - Feature-based? Layer-based?
|
||||
7. **Calculate metrics** - LOC, complexity, dependency count
|
||||
8. **Check for layer violations** - Controllers should not call Repositories directly
|
||||
9. **Identify circular dependencies** - Use tools, document as warnings
|
||||
10. **Provide evidence in observations** - Code snippets, file paths, metrics
|
||||
|
||||
### ❌ DON'T:
|
||||
|
||||
1. **Don't list every file as a component** - Significant modules only
|
||||
2. **Don't use file names as component names** - Focus on responsibility
|
||||
3. **Don't ignore component responsibilities** - Always define purpose
|
||||
4. **Don't skip dependency analysis** - Dependencies reveal architecture
|
||||
5. **Don't overlook design patterns** - Patterns indicate architectural decisions
|
||||
6. **Don't ignore metrics** - Metrics help identify refactoring needs
|
||||
7. **Don't document test files as components** - Tests verify, aren't components
|
||||
8. **Don't mix abstraction levels** - Keep C3 focused on components, not functions (C4)
|
||||
9. **Don't skip validation** - Always validate generated JSON
|
||||
10. **Don't ignore circular dependencies** - Flag and document
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Too Many Components:** Focus on significant components - group small utilities, combine related files, use LOC threshold (>200 LOC).
|
||||
|
||||
**Can't Determine Type:** Analyze behavior - HTTP requests → Controller, business logic → Service, database access → Repository.
|
||||
|
||||
**Circular Dependencies:** Document as warning, suggest refactoring (extract shared logic, use events, remove circular reference).
|
||||
|
||||
**Missing Responsibilities:** Read public methods, check method names (create/update/delete), analyze dependencies, read comments.
|
||||
|
||||
**No Patterns Detected:** Look for dependency injection, repository pattern, factory pattern, singleton pattern - use grep commands.
|
||||
|
||||
**Can't Calculate Metrics:** Use simple LOC counting, count methods manually, count dependencies, document what you can measure.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Component Types
|
||||
controller, service, repository, model, middleware, utility, dto, adapter, factory, validator, facade, guard
|
||||
|
||||
### Layers
|
||||
presentation (Controllers, Middleware, DTOs), business (Services, Domain Models, Validators), data (Repositories, Database Models), integration (Adapters, External Service Clients)
|
||||
|
||||
### Design Patterns
|
||||
Singleton, Factory, Repository, Dependency Injection, Observer, Strategy, Decorator, Adapter
|
||||
|
||||
### Architectural Patterns
|
||||
MVC, Layered (3-tier), Hexagonal (Ports & Adapters), CQRS, Microkernel, Event-Driven
|
||||
|
||||
### Observation Categories
|
||||
code-structure, design-patterns, dependencies, complexity, coupling, cohesion, testing, documentation
|
||||
|
||||
### Metrics
|
||||
Lines of Code (LOC), Cyclomatic Complexity, Number of Dependencies, Number of Public Methods, Afferent Coupling (Ca), Efferent Coupling (Ce), Instability (I = Ce / (Ca + Ce))
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
You now have comprehensive knowledge of C4 Model Level 3 (Component) methodology. When invoked:
|
||||
|
||||
1. **Load input data** from `c2-containers.json`
|
||||
2. **Analyze each container** to understand structure
|
||||
3. **Identify components** using file structure and code analysis
|
||||
4. **Classify components** by type (controller, service, repository, etc.)
|
||||
5. **Define responsibilities** for each component
|
||||
6. **Map dependencies** between components
|
||||
7. **Detect patterns** (design patterns and architectural patterns)
|
||||
8. **Generate observations** with evidence
|
||||
9. **Calculate metrics** (LOC, complexity, dependencies)
|
||||
10. **Validate output** before finalizing
|
||||
|
||||
Remember: **C3 is about code structure.** Focus on WHAT code components exist, WHAT they do, and HOW they interact - not the implementation details of individual functions (that's C4).
|
||||
|
||||
For detailed methodology on specific aspects, refer to the documentation files listed in the "Detailed References" section above.
|
||||
|
||||
---
|
||||
|
||||
**Skill Version**: 1.0.0
|
||||
**Last Updated**: 2025-11-17
|
||||
**Compatibility**: Melly 1.0.0+
|
||||
511
skills/c4model-c3/component-identification.md
Normal file
511
skills/c4model-c3/component-identification.md
Normal file
@@ -0,0 +1,511 @@
|
||||
# Component Identification Methodology
|
||||
|
||||
This guide provides comprehensive methodology for identifying components at the C3 (Component) level of the C4 Model.
|
||||
|
||||
---
|
||||
|
||||
## Component Identification Methodology
|
||||
|
||||
### Step 1: Understand Container Structure
|
||||
|
||||
Start by analyzing the containers from `c2-containers.json`:
|
||||
|
||||
**Questions to ask:**
|
||||
1. What containers exist in this system?
|
||||
2. What is the technology stack for each container?
|
||||
3. What is the directory structure?
|
||||
4. What is the entry point?
|
||||
|
||||
**Container-to-Component Mapping:**
|
||||
- **Backend API** → Controllers, Services, Repositories, Models
|
||||
- **Web Frontend** → Pages, Components, Services, State Management
|
||||
- **Mobile App** → Screens, ViewModels, Services, Repositories
|
||||
- **Worker Service** → Jobs, Handlers, Processors, Queues
|
||||
- **Library** → Modules, Utilities, Helpers
|
||||
|
||||
### Step 2: Apply Component Identification Rules
|
||||
|
||||
A **component** at C3 level is:
|
||||
|
||||
#### ✅ A Component IS:
|
||||
|
||||
1. **A cohesive code module with clear responsibility**
|
||||
- Has one primary purpose (Single Responsibility Principle)
|
||||
- Encapsulates related functionality
|
||||
- Example: `UserAuthenticationService`, `OrderRepository`, `PaymentController`
|
||||
|
||||
2. **A collection of related classes/functions**
|
||||
- Groups related code together
|
||||
- Organized in a package, module, or directory
|
||||
- Example: `authentication/` module with auth-related classes
|
||||
|
||||
3. **An architectural building block**
|
||||
- Represents a significant piece of functionality
|
||||
- Has well-defined interface/API
|
||||
- Example: `EmailNotificationService`, `DatabaseConnection`
|
||||
|
||||
4. **A layer or subsystem**
|
||||
- Distinct architectural layer
|
||||
- Clear boundary from other layers
|
||||
- Example: `data-access-layer/`, `business-logic-layer/`
|
||||
|
||||
#### ❌ A Component is NOT:
|
||||
|
||||
1. **Individual functions** (too granular - that's C4)
|
||||
- ❌ `validateEmail()` function
|
||||
- ❌ `calculateTotal()` function
|
||||
- ✅ `ValidationService` (collection of validation functions)
|
||||
|
||||
2. **Single classes unless architecturally significant**
|
||||
- ❌ `EmailValidator` class (too small)
|
||||
- ✅ `AuthenticationService` class (significant)
|
||||
- Rule: If class > 200 LOC or has major role, it's a component
|
||||
|
||||
3. **Configuration files**
|
||||
- ❌ `config.json`
|
||||
- ❌ `.env`
|
||||
- These are not components, but configuration
|
||||
|
||||
4. **Test files**
|
||||
- ❌ `UserService.test.ts`
|
||||
- Tests verify components but aren't components themselves
|
||||
|
||||
### Step 3: Analyze File Structure
|
||||
|
||||
Use file system structure to identify components:
|
||||
|
||||
**Common patterns:**
|
||||
|
||||
#### Pattern 1: Directory-based Components (Recommended)
|
||||
```
|
||||
src/
|
||||
├── authentication/ # → Component: Authentication
|
||||
│ ├── AuthService.ts
|
||||
│ ├── AuthController.ts
|
||||
│ ├── TokenManager.ts
|
||||
│ └── index.ts
|
||||
├── users/ # → Component: User Management
|
||||
│ ├── UserService.ts
|
||||
│ ├── UserRepository.ts
|
||||
│ ├── User.model.ts
|
||||
│ └── index.ts
|
||||
└── payments/ # → Component: Payment Processing
|
||||
├── PaymentService.ts
|
||||
├── PaymentGateway.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
#### Pattern 2: Layered Components
|
||||
```
|
||||
src/
|
||||
├── controllers/ # → Component Layer: Controllers
|
||||
│ ├── UserController.ts
|
||||
│ ├── OrderController.ts
|
||||
│ └── ProductController.ts
|
||||
├── services/ # → Component Layer: Services
|
||||
│ ├── UserService.ts
|
||||
│ ├── OrderService.ts
|
||||
│ └── ProductService.ts
|
||||
└── repositories/ # → Component Layer: Repositories
|
||||
├── UserRepository.ts
|
||||
├── OrderRepository.ts
|
||||
└── ProductRepository.ts
|
||||
```
|
||||
|
||||
#### Pattern 3: Feature-based Components
|
||||
```
|
||||
src/
|
||||
├── features/
|
||||
│ ├── user-management/ # → Component: User Management
|
||||
│ │ ├── components/
|
||||
│ │ ├── services/
|
||||
│ │ └── models/
|
||||
│ ├── order-management/ # → Component: Order Management
|
||||
│ │ ├── components/
|
||||
│ │ ├── services/
|
||||
│ │ └── models/
|
||||
```
|
||||
|
||||
**Detection commands:**
|
||||
```bash
|
||||
# Find directories with code files
|
||||
find src -type d -not -path "*/node_modules/*" -not -path "*/.git/*"
|
||||
|
||||
# List files by directory
|
||||
ls -la src/*/
|
||||
|
||||
# Count files per directory
|
||||
find src -type f \( -name "*.ts" -o -name "*.js" \) | xargs dirname | sort | uniq -c
|
||||
```
|
||||
|
||||
### Step 4: Detect Component Types
|
||||
|
||||
Classify each component by type:
|
||||
|
||||
**Component Types:**
|
||||
|
||||
1. **controller** - HTTP request handlers
|
||||
- Handles incoming requests
|
||||
- Routes to services
|
||||
- Returns responses
|
||||
- Example: `UserController`, `OrderController`
|
||||
|
||||
2. **service** - Business logic
|
||||
- Core business logic
|
||||
- Orchestrates operations
|
||||
- Encapsulates domain logic
|
||||
- Example: `UserService`, `PaymentService`
|
||||
|
||||
3. **repository** - Data access
|
||||
- Database operations
|
||||
- Data persistence
|
||||
- Query abstraction
|
||||
- Example: `UserRepository`, `OrderRepository`
|
||||
|
||||
4. **model** - Data models
|
||||
- Entity definitions
|
||||
- Data structures
|
||||
- Domain objects
|
||||
- Example: `User`, `Order`, `Product`
|
||||
|
||||
5. **middleware** - Request/response processing
|
||||
- Authentication middleware
|
||||
- Logging middleware
|
||||
- Validation middleware
|
||||
- Example: `AuthMiddleware`, `LoggingMiddleware`
|
||||
|
||||
6. **utility** - Helper functions
|
||||
- Shared utilities
|
||||
- Common helpers
|
||||
- Cross-cutting concerns
|
||||
- Example: `DateUtils`, `StringUtils`
|
||||
|
||||
7. **dto** - Data transfer objects
|
||||
- Request/response schemas
|
||||
- API contracts
|
||||
- Validation schemas
|
||||
- Example: `CreateUserDto`, `LoginResponseDto`
|
||||
|
||||
8. **adapter** - External integrations
|
||||
- Third-party API clients
|
||||
- External service wrappers
|
||||
- Protocol adapters
|
||||
- Example: `StripeAdapter`, `SendGridAdapter`
|
||||
|
||||
9. **factory** - Object creation
|
||||
- Complex object construction
|
||||
- Dependency creation
|
||||
- Example: `UserFactory`, `OrderFactory`
|
||||
|
||||
10. **validator** - Validation logic
|
||||
- Input validation
|
||||
- Business rule validation
|
||||
- Example: `EmailValidator`, `OrderValidator`
|
||||
|
||||
11. **facade** - Simplified interfaces
|
||||
- Simplifies complex subsystems
|
||||
- Provides unified interface
|
||||
- Example: `PaymentFacade`, `NotificationFacade`
|
||||
|
||||
12. **guard** - Authorization/authentication
|
||||
- Access control
|
||||
- Route protection
|
||||
- Example: `AuthGuard`, `RoleGuard`
|
||||
|
||||
### Step 5: Define Component Boundaries
|
||||
|
||||
For each component, define:
|
||||
|
||||
#### 1. Package/Module Boundary
|
||||
- What package or module does it belong to?
|
||||
- What is the namespace?
|
||||
- What is the import path?
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Component: Authentication Service
|
||||
// Package: @app/authentication
|
||||
// Module: src/authentication/AuthService.ts
|
||||
// Import: import { AuthService } from '@app/authentication';
|
||||
```
|
||||
|
||||
#### 2. Layer Boundary
|
||||
- What architectural layer?
|
||||
- Presentation, Business Logic, Data Access?
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Presentation Layer: Controllers, Middleware, DTOs
|
||||
Business Logic Layer: Services, Domain Models, Validators
|
||||
Data Access Layer: Repositories, Database Models, Adapters
|
||||
```
|
||||
|
||||
#### 3. Responsibility Boundary
|
||||
- What is the single responsibility?
|
||||
- What does it do?
|
||||
- What does it NOT do?
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"id": "user-service",
|
||||
"name": "User Service",
|
||||
"responsibility": "Manages user lifecycle operations including registration, profile updates, and account deletion",
|
||||
"does": [
|
||||
"Validate user input",
|
||||
"Create new users",
|
||||
"Update user profiles",
|
||||
"Delete user accounts"
|
||||
],
|
||||
"does_not": [
|
||||
"Handle HTTP requests (Controller's job)",
|
||||
"Access database directly (Repository's job)",
|
||||
"Send emails (Email Service's job)"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Identify Component Responsibilities
|
||||
|
||||
For each component, determine its responsibilities:
|
||||
|
||||
**Questions to ask:**
|
||||
1. What is the primary purpose?
|
||||
2. What operations does it perform?
|
||||
3. What data does it manage?
|
||||
4. What services does it provide?
|
||||
5. What dependencies does it have?
|
||||
|
||||
**Analysis techniques:**
|
||||
|
||||
#### Technique 1: Analyze Public Methods
|
||||
```typescript
|
||||
// UserService.ts
|
||||
export class UserService {
|
||||
// Public interface reveals responsibilities:
|
||||
async createUser(data: CreateUserDto): Promise<User>
|
||||
async updateUser(id: string, data: UpdateUserDto): Promise<User>
|
||||
async deleteUser(id: string): Promise<void>
|
||||
async getUserById(id: string): Promise<User>
|
||||
async getUserByEmail(email: string): Promise<User>
|
||||
}
|
||||
|
||||
// Responsibilities:
|
||||
// - User creation
|
||||
// - User updates
|
||||
// - User deletion
|
||||
// - User retrieval by ID
|
||||
// - User retrieval by email
|
||||
```
|
||||
|
||||
#### Technique 2: Analyze Dependencies
|
||||
```typescript
|
||||
// PaymentService.ts depends on:
|
||||
import { PaymentGateway } from './PaymentGateway';
|
||||
import { OrderRepository } from '../orders/OrderRepository';
|
||||
import { EmailService } from '../notifications/EmailService';
|
||||
|
||||
// Responsibilities indicated by dependencies:
|
||||
// - Processes payments (PaymentGateway)
|
||||
// - Updates order status (OrderRepository)
|
||||
// - Sends payment confirmations (EmailService)
|
||||
```
|
||||
|
||||
#### Technique 3: Analyze File Content
|
||||
```bash
|
||||
# Count methods in a class (using extended regex)
|
||||
grep -E '^\s+(public|private|protected|async)\s+\w+\s*\(' UserService.ts
|
||||
|
||||
# Find key operations
|
||||
grep -E '(create|update|delete|get|find|save)' UserService.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code Structure Analysis
|
||||
|
||||
### Directory Structure Patterns
|
||||
|
||||
#### Pattern 1: Feature-based Structure
|
||||
```
|
||||
src/
|
||||
├── users/
|
||||
│ ├── user.controller.ts # Component: User Controller
|
||||
│ ├── user.service.ts # Component: User Service
|
||||
│ ├── user.repository.ts # Component: User Repository
|
||||
│ ├── user.model.ts # Component: User Model
|
||||
│ ├── dto/
|
||||
│ │ ├── create-user.dto.ts
|
||||
│ │ └── update-user.dto.ts
|
||||
│ └── index.ts
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- Clear feature boundaries
|
||||
- Easy to locate related code
|
||||
- Good for domain-driven design
|
||||
|
||||
**Component detection:**
|
||||
```bash
|
||||
# List all feature directories
|
||||
ls -d src/*/
|
||||
|
||||
# Count components per feature
|
||||
find src \( -name "*.service.ts" -o -name "*.controller.ts" -o -name "*.repository.ts" \) | xargs dirname | sort | uniq -c
|
||||
```
|
||||
|
||||
#### Pattern 2: Layer-based Structure
|
||||
```
|
||||
src/
|
||||
├── controllers/
|
||||
│ ├── user.controller.ts
|
||||
│ ├── order.controller.ts
|
||||
│ └── product.controller.ts
|
||||
├── services/
|
||||
│ ├── user.service.ts
|
||||
│ ├── order.service.ts
|
||||
│ └── product.service.ts
|
||||
├── repositories/
|
||||
│ ├── user.repository.ts
|
||||
│ ├── order.repository.ts
|
||||
│ └── product.repository.ts
|
||||
└── models/
|
||||
├── user.model.ts
|
||||
├── order.model.ts
|
||||
└── product.model.ts
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- Clear layer separation
|
||||
- Easy to enforce layer rules
|
||||
- Good for traditional MVC
|
||||
|
||||
**Component detection:**
|
||||
```bash
|
||||
# Count components per layer
|
||||
wc -l controllers/*.ts services/*.ts repositories/*.ts
|
||||
```
|
||||
|
||||
#### Pattern 3: Domain-Driven Design (DDD)
|
||||
```
|
||||
src/
|
||||
├── domain/
|
||||
│ ├── user/
|
||||
│ │ ├── User.entity.ts # Component: User Entity
|
||||
│ │ ├── UserRepository.ts # Component: User Repository
|
||||
│ │ └── UserService.ts # Component: User Domain Service
|
||||
│ └── order/
|
||||
│ ├── Order.entity.ts
|
||||
│ ├── OrderRepository.ts
|
||||
│ └── OrderService.ts
|
||||
├── application/
|
||||
│ ├── user/
|
||||
│ │ ├── CreateUserUseCase.ts # Component: Create User Use Case
|
||||
│ │ ├── UpdateUserUseCase.ts # Component: Update User Use Case
|
||||
│ └── order/
|
||||
│ ├── PlaceOrderUseCase.ts
|
||||
│ └── CancelOrderUseCase.ts
|
||||
└── infrastructure/
|
||||
├── database/
|
||||
│ ├── UserRepositoryImpl.ts # Component: User Repository Implementation
|
||||
│ └── OrderRepositoryImpl.ts
|
||||
└── http/
|
||||
├── UserController.ts # Component: User Controller
|
||||
└── OrderController.ts
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- Clear domain boundaries
|
||||
- Separation of concerns
|
||||
- Testable use cases
|
||||
|
||||
### Export Pattern Analysis
|
||||
|
||||
Analyze how components expose their APIs:
|
||||
|
||||
#### Pattern 1: Named Exports
|
||||
```typescript
|
||||
// authentication/index.ts
|
||||
export { AuthService } from './AuthService';
|
||||
export { AuthController } from './AuthController';
|
||||
export { TokenManager } from './TokenManager';
|
||||
export * from './dto';
|
||||
|
||||
// Component: Authentication Module
|
||||
// Public API: AuthService, AuthController, TokenManager, DTOs
|
||||
```
|
||||
|
||||
#### Pattern 2: Default Exports
|
||||
```typescript
|
||||
// UserService.ts
|
||||
export default class UserService { ... }
|
||||
|
||||
// Component: User Service
|
||||
// Import: import UserService from './UserService';
|
||||
```
|
||||
|
||||
#### Pattern 3: Facade Exports
|
||||
```typescript
|
||||
// payment/index.ts
|
||||
import { PaymentService } from './PaymentService';
|
||||
import { PaymentGateway } from './PaymentGateway';
|
||||
import { PaymentValidator } from './PaymentValidator';
|
||||
|
||||
// Facade pattern - single entry point
|
||||
export class PaymentFacade {
|
||||
constructor(
|
||||
private service: PaymentService,
|
||||
private gateway: PaymentGateway,
|
||||
private validator: PaymentValidator
|
||||
) {}
|
||||
|
||||
// Simplified API
|
||||
async processPayment(data: PaymentDto): Promise<PaymentResult> { ... }
|
||||
}
|
||||
|
||||
// Component: Payment Facade
|
||||
// Hides internal complexity
|
||||
```
|
||||
|
||||
### Code Metrics Analysis
|
||||
|
||||
Use metrics to identify significant components:
|
||||
|
||||
#### Metric 1: Lines of Code (LOC)
|
||||
```bash
|
||||
# Count lines per file
|
||||
find src -name "*.ts" -print0 | xargs -0 -r wc -l | sort -rn
|
||||
|
||||
# Components with > 200 LOC are significant
|
||||
find src -name "*.ts" -print0 | xargs -0 -r wc -l | awk '$1 > 200 { print $2, $1 }'
|
||||
```
|
||||
|
||||
**Guidelines:**
|
||||
- **< 100 LOC**: Small component or helper
|
||||
- **100-300 LOC**: Typical component
|
||||
- **300-500 LOC**: Large component (consider splitting)
|
||||
- **> 500 LOC**: Very large (definitely a component, likely needs refactoring)
|
||||
|
||||
#### Metric 2: Cyclomatic Complexity
|
||||
```bash
|
||||
# Use complexity tools
|
||||
find src -name "*.ts" -print0 | xargs -0 -r npx ts-complexity
|
||||
|
||||
# High complexity (>10) indicates important component
|
||||
```
|
||||
|
||||
#### Metric 3: Dependency Count
|
||||
```bash
|
||||
# Count imports per file
|
||||
find src -name "*.ts" -print0 | xargs -0 -r grep -cH "^import" 2>/dev/null | sort -t: -k2 -rn
|
||||
|
||||
# Files with many imports are often important orchestrators (Services)
|
||||
```
|
||||
|
||||
#### Metric 4: Export Count
|
||||
```bash
|
||||
# Count exports per file
|
||||
find src -name "*.ts" -print0 | xargs -0 -r grep -cH "^export" 2>/dev/null | sort -t: -k2 -rn
|
||||
|
||||
# Files with many exports are often facades or utility modules
|
||||
```
|
||||
163
skills/c4model-c3/dependency-analysis.md
Normal file
163
skills/c4model-c3/dependency-analysis.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# Dependency Analysis
|
||||
|
||||
This guide provides comprehensive methodology for analyzing component dependencies at the C3 level.
|
||||
|
||||
---
|
||||
|
||||
## Dependency Analysis
|
||||
|
||||
### Dependency Types
|
||||
|
||||
#### 1. Internal Dependencies (Within Container)
|
||||
```typescript
|
||||
// UserService.ts
|
||||
import { UserRepository } from './UserRepository'; // Same feature
|
||||
import { EmailService } from '../email/EmailService'; // Different feature
|
||||
import { ValidationUtil } from '../utils/validation'; // Utility
|
||||
|
||||
// Dependencies:
|
||||
// - UserRepository (direct dependency)
|
||||
// - EmailService (cross-feature dependency)
|
||||
// - ValidationUtil (utility dependency)
|
||||
```
|
||||
|
||||
#### 2. External Dependencies (Outside Container)
|
||||
```typescript
|
||||
// PaymentService.ts
|
||||
import Stripe from 'stripe'; // External library
|
||||
import { Logger } from '@nestjs/common'; // Framework
|
||||
import axios from 'axios'; // HTTP client
|
||||
|
||||
// External dependencies:
|
||||
// - Stripe SDK
|
||||
// - NestJS framework
|
||||
// - Axios library
|
||||
```
|
||||
|
||||
#### 3. Framework Dependencies
|
||||
```typescript
|
||||
// UserController.ts
|
||||
import { Controller, Get, Post, Body } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
|
||||
// Framework dependencies:
|
||||
// - NestJS decorators
|
||||
// - Swagger decorators
|
||||
```
|
||||
|
||||
### Dependency Direction
|
||||
|
||||
Analyze the flow of dependencies:
|
||||
|
||||
**Recommended flow (Dependency Inversion):**
|
||||
```
|
||||
Controllers → Services → Repositories → Models
|
||||
↓ ↓ ↓
|
||||
(HTTP) (Business) (Data)
|
||||
```
|
||||
|
||||
**Anti-pattern (Skip layers):**
|
||||
```
|
||||
Controllers → Repositories ❌ (skips business logic layer)
|
||||
```
|
||||
|
||||
**Example: Good Dependency Direction**
|
||||
```typescript
|
||||
// Good: Controller depends on Service
|
||||
@Controller('users')
|
||||
export class UserController {
|
||||
constructor(private userService: UserService) {}
|
||||
|
||||
@Post()
|
||||
createUser(@Body() dto: CreateUserDto) {
|
||||
return this.userService.createUser(dto);
|
||||
}
|
||||
}
|
||||
|
||||
// Good: Service depends on Repository
|
||||
export class UserService {
|
||||
constructor(private userRepo: UserRepository) {}
|
||||
|
||||
async createUser(dto: CreateUserDto) {
|
||||
// Business logic here
|
||||
return this.userRepo.save(user);
|
||||
}
|
||||
}
|
||||
|
||||
// Good: Repository depends on Model
|
||||
export class UserRepository {
|
||||
async save(user: User) {
|
||||
// Data access here
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Coupling Analysis
|
||||
|
||||
**Types of coupling:**
|
||||
|
||||
#### 1. Tight Coupling (Bad)
|
||||
```typescript
|
||||
// Bad: Direct instantiation
|
||||
export class UserService {
|
||||
private emailService = new EmailService(); // ❌ Tightly coupled
|
||||
|
||||
async createUser(data: CreateUserDto) {
|
||||
const user = await this.saveUser(data);
|
||||
this.emailService.sendWelcome(user); // Can't mock in tests
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Loose Coupling (Good)
|
||||
```typescript
|
||||
// Good: Dependency injection
|
||||
export class UserService {
|
||||
constructor(private emailService: EmailService) {} // ✅ Loosely coupled
|
||||
|
||||
async createUser(data: CreateUserDto) {
|
||||
const user = await this.saveUser(data);
|
||||
this.emailService.sendWelcome(user); // Easy to mock
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Coupling metrics:**
|
||||
- **Afferent Coupling (Ca)**: Number of components that depend on this component
|
||||
- **Efferent Coupling (Ce)**: Number of components this component depends on
|
||||
- **Instability (I)**: Ce / (Ca + Ce)
|
||||
- I = 0: Very stable (many dependents, no dependencies)
|
||||
- I = 1: Very unstable (no dependents, many dependencies)
|
||||
|
||||
**Detection:**
|
||||
```bash
|
||||
# Find components with many imports (high efferent coupling)
|
||||
while IFS= read -r -d '' file; do
|
||||
count=$(grep -c '^import' "$file" 2>/dev/null || echo 0)
|
||||
printf "%d %s\n" "$count" "$file"
|
||||
done < <(find src -name "*.ts" -print0) | sort -rn | head -20
|
||||
|
||||
# Find components imported by many others (high afferent coupling)
|
||||
grep -rE "from ['\"](\.\./)+[^'\"]+['\"]" src/ | cut -d: -f2 | cut -d"'" -d'"' -f2 | sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
### Circular Dependency Detection
|
||||
|
||||
**Anti-pattern: Circular dependencies**
|
||||
```
|
||||
UserService → OrderService → UserService ❌
|
||||
```
|
||||
|
||||
**Detection:**
|
||||
```bash
|
||||
# Use madge for Node.js projects
|
||||
npx madge --circular src/
|
||||
|
||||
# Use dependency-cruiser
|
||||
npx depcruise --validate .dependency-cruiser.js src/
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
- Extract shared logic to third component
|
||||
- Use events instead of direct calls
|
||||
- Refactor to remove circular reference
|
||||
126
skills/c4model-c3/observation-guide.md
Normal file
126
skills/c4model-c3/observation-guide.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Observation Guide for C3 Components
|
||||
|
||||
This guide provides comprehensive methodology for documenting observations at the C3 level.
|
||||
|
||||
---
|
||||
|
||||
## Observation Categories for C3
|
||||
|
||||
### Observation Categories
|
||||
|
||||
When documenting components, capture these observation categories:
|
||||
|
||||
#### 1. **code-structure**
|
||||
Code organization patterns and file structure
|
||||
|
||||
**Examples:**
|
||||
- "Feature-based structure with users/, orders/, products/ directories"
|
||||
- "Layered architecture with controllers/, services/, repositories/ separation"
|
||||
- "Domain-driven design with domain/, application/, infrastructure/ layers"
|
||||
- "Monolithic structure - all code in single src/ directory"
|
||||
|
||||
#### 2. **design-patterns**
|
||||
Design patterns identified in code
|
||||
|
||||
**Examples:**
|
||||
- "Singleton pattern for DatabaseConnection ensures single instance"
|
||||
- "Repository pattern abstracts data access across all entities"
|
||||
- "Factory pattern used for creating different user types"
|
||||
- "Dependency injection via NestJS @Injectable decorators"
|
||||
- "Observer pattern for event-driven order processing"
|
||||
|
||||
#### 3. **dependencies**
|
||||
Component dependencies and coupling
|
||||
|
||||
**Examples:**
|
||||
- "UserService depends on UserRepository, EmailService, and ValidationUtil"
|
||||
- "High coupling between OrderService and PaymentService (7 method calls)"
|
||||
- "Circular dependency detected: UserService ↔ OrderService"
|
||||
- "Controllers depend only on Services (proper layering)"
|
||||
|
||||
#### 4. **complexity**
|
||||
Code complexity metrics
|
||||
|
||||
**Examples:**
|
||||
- "OrderService has cyclomatic complexity of 24 (high risk)"
|
||||
- "UserController is 450 LOC (consider splitting)"
|
||||
- "PaymentService has 12 public methods (large interface)"
|
||||
- "Average complexity across services: 8 (acceptable)"
|
||||
|
||||
#### 5. **coupling**
|
||||
Coupling and cohesion analysis
|
||||
|
||||
**Examples:**
|
||||
- "Tight coupling: UserService directly instantiates EmailService (no DI)"
|
||||
- "Loose coupling: All dependencies injected via constructor"
|
||||
- "High afferent coupling: UserModel imported by 15 components"
|
||||
- "Low cohesion: UtilityService has unrelated helper methods"
|
||||
|
||||
#### 6. **cohesion**
|
||||
Component cohesion and single responsibility
|
||||
|
||||
**Examples:**
|
||||
- "UserService has high cohesion - all methods relate to user management"
|
||||
- "UtilityService has low cohesion - contains unrelated helpers"
|
||||
- "OrderController violates SRP - handles both orders and payments"
|
||||
- "Each repository focused on single entity (good cohesion)"
|
||||
|
||||
#### 7. **testing**
|
||||
Test coverage and testability
|
||||
|
||||
**Examples:**
|
||||
- "UserService has 95% test coverage with 24 unit tests"
|
||||
- "PaymentGateway untestable - uses hardcoded external URLs"
|
||||
- "All services use dependency injection for easy mocking"
|
||||
- "Controllers have integration tests covering main flows"
|
||||
|
||||
#### 8. **documentation**
|
||||
Code documentation quality
|
||||
|
||||
**Examples:**
|
||||
- "All public methods have JSDoc comments"
|
||||
- "UserService missing documentation for complex methods"
|
||||
- "README.md in authentication/ explains module architecture"
|
||||
- "Inline comments explain business logic in PaymentService"
|
||||
|
||||
### Observation Structure for C3
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "obs-repo-pattern-all-entities",
|
||||
"title": "Repository pattern used for all entity data access",
|
||||
"category": "design-patterns",
|
||||
"severity": "info",
|
||||
"pattern": "repository",
|
||||
"description": "All entities (User, Order, Product, Payment) have dedicated repository classes that abstract database operations using the Repository pattern. Repositories provide methods like findById, findAll, save, delete.",
|
||||
"evidence": [
|
||||
{
|
||||
"type": "pattern",
|
||||
"location": "src/users/UserRepository.ts",
|
||||
"snippet": "export class UserRepository { async findById(id: string): Promise<User> { ... } }"
|
||||
},
|
||||
{
|
||||
"type": "pattern",
|
||||
"location": "src/orders/OrderRepository.ts",
|
||||
"snippet": "export class OrderRepository { async findById(id: string): Promise<Order> { ... } }"
|
||||
}
|
||||
],
|
||||
"impact": {
|
||||
"maintainability": "high",
|
||||
"testability": "high",
|
||||
"scalability": "medium"
|
||||
},
|
||||
"tags": ["repository-pattern", "data-access", "abstraction"]
|
||||
}
|
||||
```
|
||||
|
||||
### Observation Severity Levels
|
||||
|
||||
- **info** - Informational observation (neutral)
|
||||
- **warning** - Potential issue requiring attention
|
||||
- **critical** - Critical issue requiring immediate action
|
||||
|
||||
**Examples:**
|
||||
- ℹ️ **info**: "Repository pattern used for data access abstraction"
|
||||
- ⚠️ **warning**: "Circular dependency between UserService and OrderService"
|
||||
- 🔴 **critical**: "No input validation in UserController endpoints"
|
||||
522
skills/c4model-c3/pattern-detection.md
Normal file
522
skills/c4model-c3/pattern-detection.md
Normal file
@@ -0,0 +1,522 @@
|
||||
# Pattern Detection
|
||||
|
||||
This guide provides comprehensive methodology for detecting design patterns and architectural patterns at the C3 level.
|
||||
|
||||
---
|
||||
|
||||
## Pattern Detection
|
||||
|
||||
### Design Patterns
|
||||
|
||||
#### Pattern 1: Singleton Pattern
|
||||
|
||||
**Description:** Ensures a class has only one instance
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Singleton pattern indicators
|
||||
export class DatabaseConnection {
|
||||
private static instance: DatabaseConnection;
|
||||
|
||||
private constructor() {} // Private constructor
|
||||
|
||||
static getInstance(): DatabaseConnection {
|
||||
if (!this.instance) {
|
||||
this.instance = new DatabaseConnection();
|
||||
}
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -r "private static.*instance" src/
|
||||
grep -r "private constructor" src/
|
||||
grep -r "getInstance()" src/
|
||||
```
|
||||
|
||||
**Observation:**
|
||||
```json
|
||||
{
|
||||
"id": "obs-singleton-database",
|
||||
"title": "Singleton pattern for database connection",
|
||||
"category": "design-patterns",
|
||||
"severity": "info",
|
||||
"pattern": "singleton",
|
||||
"description": "DatabaseConnection uses Singleton pattern to ensure single instance across application"
|
||||
}
|
||||
```
|
||||
|
||||
#### Pattern 2: Factory Pattern
|
||||
|
||||
**Description:** Creates objects without specifying exact class
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Factory pattern indicators
|
||||
export class UserFactory {
|
||||
static createUser(type: string, data: any): User {
|
||||
switch (type) {
|
||||
case 'admin':
|
||||
return new AdminUser(data);
|
||||
case 'customer':
|
||||
return new CustomerUser(data);
|
||||
default:
|
||||
return new GuestUser(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -r "Factory" src/
|
||||
grep -r "static create" src/
|
||||
```
|
||||
|
||||
#### Pattern 3: Repository Pattern
|
||||
|
||||
**Description:** Abstracts data access logic
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Repository pattern indicators
|
||||
export class UserRepository {
|
||||
async findById(id: string): Promise<User> { ... }
|
||||
async findAll(): Promise<User[]> { ... }
|
||||
async save(user: User): Promise<User> { ... }
|
||||
async delete(id: string): Promise<void> { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -r "Repository" src/
|
||||
grep -rE "findById|findAll|save.*Promise" src/
|
||||
```
|
||||
|
||||
#### Pattern 4: Dependency Injection
|
||||
|
||||
**Description:** Dependencies provided externally
|
||||
|
||||
**Detection in NestJS:**
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@Inject(UserRepository) private userRepo: UserRepository,
|
||||
@Inject(EmailService) private emailService: EmailService
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
**Detection in Spring (Java):**
|
||||
```java
|
||||
@Service
|
||||
public class UserService {
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
private EmailService emailService;
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
# NestJS
|
||||
grep -rE "@Injectable|@Inject" src/
|
||||
|
||||
# Spring
|
||||
grep -rE "@Service|@Autowired|@Component" src/
|
||||
|
||||
# Constructor injection
|
||||
grep -r "constructor(" src/ | grep "private"
|
||||
```
|
||||
|
||||
#### Pattern 5: Observer Pattern (Event-Driven)
|
||||
|
||||
**Description:** Publish-subscribe mechanism
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Observer pattern indicators
|
||||
export class OrderService {
|
||||
async createOrder(data: CreateOrderDto) {
|
||||
const order = await this.orderRepo.save(data);
|
||||
|
||||
// Emit event
|
||||
this.eventEmitter.emit('order.created', order);
|
||||
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
// Observers
|
||||
export class EmailService {
|
||||
@OnEvent('order.created')
|
||||
handleOrderCreated(order: Order) {
|
||||
this.sendOrderConfirmation(order);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -rE "\.emit|\.on|@OnEvent|subscribe|publish" src/
|
||||
```
|
||||
|
||||
#### Pattern 6: Strategy Pattern
|
||||
|
||||
**Description:** Select algorithm at runtime
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Strategy pattern
|
||||
interface PaymentStrategy {
|
||||
pay(amount: number): Promise<PaymentResult>;
|
||||
}
|
||||
|
||||
class CreditCardPayment implements PaymentStrategy {
|
||||
async pay(amount: number) { ... }
|
||||
}
|
||||
|
||||
class PayPalPayment implements PaymentStrategy {
|
||||
async pay(amount: number) { ... }
|
||||
}
|
||||
|
||||
class PaymentContext {
|
||||
constructor(private strategy: PaymentStrategy) {}
|
||||
|
||||
async executePayment(amount: number) {
|
||||
return this.strategy.pay(amount);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -rE "implements.*Strategy|Strategy.*interface" src/
|
||||
```
|
||||
|
||||
#### Pattern 7: Decorator Pattern
|
||||
|
||||
**Description:** Add behavior dynamically
|
||||
|
||||
**Detection in TypeScript:**
|
||||
```typescript
|
||||
// Decorator pattern (using TypeScript decorators)
|
||||
@Controller('users')
|
||||
@UseGuards(AuthGuard) // Decorator
|
||||
@UseInterceptors(LoggingInterceptor) // Decorator
|
||||
export class UserController {
|
||||
@Get()
|
||||
@Roles('admin') // Decorator
|
||||
findAll() { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -rE "^@\w+\(" src/
|
||||
```
|
||||
|
||||
#### Pattern 8: Adapter Pattern
|
||||
|
||||
**Description:** Converts interface to another interface
|
||||
|
||||
**Detection:**
|
||||
```typescript
|
||||
// Adapter pattern
|
||||
export class StripeAdapter {
|
||||
constructor(private stripeClient: Stripe) {}
|
||||
|
||||
// Adapt Stripe API to internal interface
|
||||
async processPayment(payment: PaymentDto): Promise<PaymentResult> {
|
||||
const stripePayment = this.convertToStripeFormat(payment);
|
||||
const result = await this.stripeClient.charges.create(stripePayment);
|
||||
return this.convertFromStripeFormat(result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Grep detection:**
|
||||
```bash
|
||||
grep -r "Adapter" src/
|
||||
grep -r "convert.*Format" src/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Architecture Patterns
|
||||
|
||||
### Pattern 1: MVC (Model-View-Controller)
|
||||
|
||||
**Description:** Separates concerns into Model, View, Controller
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── models/ # Models (Data)
|
||||
│ ├── User.ts
|
||||
│ ├── Order.ts
|
||||
│ └── Product.ts
|
||||
├── views/ # Views (Presentation) - if server-rendered
|
||||
│ ├── user-list.ejs
|
||||
│ └── order-detail.ejs
|
||||
└── controllers/ # Controllers (Logic)
|
||||
├── UserController.ts
|
||||
├── OrderController.ts
|
||||
└── ProductController.ts
|
||||
```
|
||||
|
||||
**Components identified:**
|
||||
- **Controllers**: UserController, OrderController, ProductController
|
||||
- **Models**: User, Order, Product
|
||||
- **Views**: (if applicable)
|
||||
|
||||
**Observation:**
|
||||
```json
|
||||
{
|
||||
"id": "obs-mvc-pattern",
|
||||
"title": "MVC pattern with controllers and models",
|
||||
"category": "architectural-pattern",
|
||||
"pattern": "mvc",
|
||||
"description": "Application follows MVC pattern with clear separation between controllers (request handling) and models (data representation)"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pattern 2: Layered Architecture (3-Tier)
|
||||
|
||||
**Description:** Separates into Presentation, Business Logic, Data Access layers
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── presentation/ # Presentation Layer
|
||||
│ ├── controllers/
|
||||
│ │ ├── UserController.ts
|
||||
│ │ └── OrderController.ts
|
||||
│ └── middleware/
|
||||
│ ├── AuthMiddleware.ts
|
||||
│ └── ValidationMiddleware.ts
|
||||
├── business/ # Business Logic Layer
|
||||
│ ├── services/
|
||||
│ │ ├── UserService.ts
|
||||
│ │ └── OrderService.ts
|
||||
│ └── validators/
|
||||
│ ├── UserValidator.ts
|
||||
│ └── OrderValidator.ts
|
||||
└── data/ # Data Access Layer
|
||||
├── repositories/
|
||||
│ ├── UserRepository.ts
|
||||
│ └── OrderRepository.ts
|
||||
└── models/
|
||||
├── User.model.ts
|
||||
└── Order.model.ts
|
||||
```
|
||||
|
||||
**Layer rules:**
|
||||
- Presentation → Business Logic → Data Access (one direction only)
|
||||
- No skipping layers (Controller can't call Repository directly)
|
||||
|
||||
**Components identified:**
|
||||
- **Presentation**: UserController, OrderController, AuthMiddleware
|
||||
- **Business Logic**: UserService, OrderService, UserValidator
|
||||
- **Data Access**: UserRepository, OrderRepository, User Model, Order Model
|
||||
|
||||
**Detection:**
|
||||
```bash
|
||||
# Check for layer violations
|
||||
grep -r "Repository" src/controllers/ # ❌ Controller calling Repository directly
|
||||
|
||||
# Verify proper layering
|
||||
grep -r "Service" src/controllers/ # ✅ Controller calling Service
|
||||
grep -r "Repository" src/services/ # ✅ Service calling Repository
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pattern 3: Hexagonal Architecture (Ports & Adapters)
|
||||
|
||||
**Description:** Core business logic isolated from external concerns
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── domain/ # Core Domain (Business Logic)
|
||||
│ ├── user/
|
||||
│ │ ├── User.entity.ts
|
||||
│ │ ├── UserService.ts
|
||||
│ │ └── ports/
|
||||
│ │ ├── UserRepository.port.ts # Interface
|
||||
│ │ └── EmailService.port.ts # Interface
|
||||
│ └── order/
|
||||
│ ├── Order.entity.ts
|
||||
│ └── OrderService.ts
|
||||
├── application/ # Application Services (Use Cases)
|
||||
│ ├── CreateUserUseCase.ts
|
||||
│ ├── PlaceOrderUseCase.ts
|
||||
│ └── ProcessPaymentUseCase.ts
|
||||
└── infrastructure/ # Infrastructure (Adapters)
|
||||
├── database/
|
||||
│ └── UserRepositoryImpl.ts # Implementation
|
||||
├── email/
|
||||
│ └── EmailServiceImpl.ts # Implementation
|
||||
└── http/
|
||||
├── UserController.ts # HTTP Adapter
|
||||
└── OrderController.ts # HTTP Adapter
|
||||
```
|
||||
|
||||
**Key concepts:**
|
||||
- **Ports**: Interfaces defined by domain (UserRepository.port.ts)
|
||||
- **Adapters**: Implementations in infrastructure (UserRepositoryImpl.ts)
|
||||
- **Dependency Inversion**: Domain defines interfaces, infrastructure implements
|
||||
|
||||
**Components identified:**
|
||||
- **Domain**: User, Order, UserService, OrderService
|
||||
- **Ports**: UserRepository (interface), EmailService (interface)
|
||||
- **Adapters**: UserRepositoryImpl, EmailServiceImpl, UserController
|
||||
- **Use Cases**: CreateUserUseCase, PlaceOrderUseCase
|
||||
|
||||
**Observation:**
|
||||
```json
|
||||
{
|
||||
"id": "obs-hexagonal-arch",
|
||||
"title": "Hexagonal architecture with ports and adapters",
|
||||
"category": "architectural-pattern",
|
||||
"pattern": "hexagonal",
|
||||
"description": "Application uses hexagonal architecture. Domain defines port interfaces (UserRepository.port.ts), infrastructure provides adapter implementations (UserRepositoryImpl.ts). Business logic isolated from external dependencies."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pattern 4: CQRS (Command Query Responsibility Segregation)
|
||||
|
||||
**Description:** Separate read and write operations
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── commands/ # Write side (Commands)
|
||||
│ ├── CreateUserCommand.ts
|
||||
│ ├── UpdateUserCommand.ts
|
||||
│ └── handlers/
|
||||
│ ├── CreateUserHandler.ts
|
||||
│ └── UpdateUserHandler.ts
|
||||
├── queries/ # Read side (Queries)
|
||||
│ ├── GetUserQuery.ts
|
||||
│ ├── ListUsersQuery.ts
|
||||
│ └── handlers/
|
||||
│ ├── GetUserHandler.ts
|
||||
│ └── ListUsersHandler.ts
|
||||
└── models/
|
||||
├── write/ # Write models
|
||||
│ └── User.entity.ts
|
||||
└── read/ # Read models (often denormalized)
|
||||
└── UserView.ts
|
||||
```
|
||||
|
||||
**Key concepts:**
|
||||
- **Commands**: Change state (CreateUser, UpdateUser)
|
||||
- **Queries**: Read state (GetUser, ListUsers)
|
||||
- **Separate models**: Write model vs Read model
|
||||
|
||||
**Components identified:**
|
||||
- **Commands**: CreateUserCommand, UpdateUserCommand
|
||||
- **Command Handlers**: CreateUserHandler, UpdateUserHandler
|
||||
- **Queries**: GetUserQuery, ListUsersQuery
|
||||
- **Query Handlers**: GetUserHandler, ListUsersHandler
|
||||
- **Write Models**: User (entity)
|
||||
- **Read Models**: UserView
|
||||
|
||||
**Detection:**
|
||||
```bash
|
||||
grep -rE "Command|Handler" src/
|
||||
grep -rE "Query|Handler" src/
|
||||
grep -rE "@CommandHandler|@QueryHandler" src/ # NestJS CQRS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pattern 5: Microkernel (Plugin Architecture)
|
||||
|
||||
**Description:** Core system with pluggable modules
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── core/ # Core System
|
||||
│ ├── Application.ts
|
||||
│ ├── PluginManager.ts
|
||||
│ └── interfaces/
|
||||
│ └── Plugin.interface.ts
|
||||
└── plugins/ # Plugins
|
||||
├── authentication/
|
||||
│ ├── AuthPlugin.ts
|
||||
│ └── AuthService.ts
|
||||
├── logging/
|
||||
│ ├── LoggingPlugin.ts
|
||||
│ └── Logger.ts
|
||||
└── cache/
|
||||
├── CachePlugin.ts
|
||||
└── CacheService.ts
|
||||
```
|
||||
|
||||
**Key concepts:**
|
||||
- **Core**: Minimal core system
|
||||
- **Plugins**: Optional modules that extend core
|
||||
- **Plugin Interface**: Contract for plugins
|
||||
|
||||
**Components identified:**
|
||||
- **Core**: Application, PluginManager
|
||||
- **Plugins**: AuthPlugin, LoggingPlugin, CachePlugin
|
||||
- **Plugin Interface**: Plugin.interface.ts
|
||||
|
||||
---
|
||||
|
||||
### Pattern 6: Event-Driven Architecture
|
||||
|
||||
**Description:** Components communicate via events
|
||||
|
||||
**Component structure:**
|
||||
```
|
||||
src/
|
||||
├── events/ # Event Definitions
|
||||
│ ├── UserCreatedEvent.ts
|
||||
│ ├── OrderPlacedEvent.ts
|
||||
│ └── PaymentProcessedEvent.ts
|
||||
├── publishers/ # Event Publishers
|
||||
│ ├── UserEventPublisher.ts
|
||||
│ └── OrderEventPublisher.ts
|
||||
└── subscribers/ # Event Subscribers
|
||||
├── EmailSubscriber.ts
|
||||
├── AnalyticsSubscriber.ts
|
||||
└── NotificationSubscriber.ts
|
||||
```
|
||||
|
||||
**Component flow:**
|
||||
```
|
||||
UserService → publishes UserCreatedEvent
|
||||
↓
|
||||
[Event Bus / Message Queue]
|
||||
↓
|
||||
EmailSubscriber receives event → sends welcome email
|
||||
AnalyticsSubscriber receives event → tracks user registration
|
||||
```
|
||||
|
||||
**Components identified:**
|
||||
- **Event Publishers**: UserEventPublisher, OrderEventPublisher
|
||||
- **Event Subscribers**: EmailSubscriber, AnalyticsSubscriber, NotificationSubscriber
|
||||
- **Events**: UserCreatedEvent, OrderPlacedEvent, PaymentProcessedEvent
|
||||
- **Event Bus**: EventEmitter, Message Queue
|
||||
|
||||
**Detection:**
|
||||
```bash
|
||||
grep -rE "Event|emit|publish|subscribe" src/
|
||||
grep -rE "@OnEvent|@Subscribe" src/ # Framework decorators
|
||||
```
|
||||
198
skills/c4model-c3/technology-examples.md
Normal file
198
skills/c4model-c3/technology-examples.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# Technology-Specific Examples
|
||||
|
||||
This guide provides technology-specific examples for component identification at the C3 level.
|
||||
|
||||
---
|
||||
|
||||
## Technology-Specific Examples
|
||||
|
||||
### NestJS Example
|
||||
|
||||
**Component identification in NestJS backend:**
|
||||
|
||||
```typescript
|
||||
// src/users/user.controller.ts
|
||||
@Controller('users')
|
||||
export class UserController { // Component: User Controller (controller)
|
||||
constructor(private userService: UserService) {}
|
||||
|
||||
@Post()
|
||||
create(@Body() dto: CreateUserDto) {
|
||||
return this.userService.create(dto);
|
||||
}
|
||||
}
|
||||
|
||||
// src/users/user.service.ts
|
||||
@Injectable()
|
||||
export class UserService { // Component: User Service (service)
|
||||
constructor(private userRepo: UserRepository) {}
|
||||
|
||||
async create(dto: CreateUserDto) {
|
||||
return this.userRepo.save(dto);
|
||||
}
|
||||
}
|
||||
|
||||
// src/users/user.repository.ts
|
||||
@Injectable()
|
||||
export class UserRepository { // Component: User Repository (repository)
|
||||
constructor(@InjectRepository(User) private repo: Repository<User>) {}
|
||||
|
||||
async save(data: CreateUserDto) {
|
||||
return this.repo.save(data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Components:**
|
||||
1. **User Controller** (controller) - Handles HTTP requests
|
||||
2. **User Service** (service) - Business logic
|
||||
3. **User Repository** (repository) - Data access
|
||||
|
||||
**Patterns:**
|
||||
- Dependency Injection (@Injectable, constructor injection)
|
||||
- Repository Pattern (UserRepository)
|
||||
- Layered Architecture (Controller → Service → Repository)
|
||||
|
||||
---
|
||||
|
||||
### Django Example (Python)
|
||||
|
||||
**Component identification in Django backend:**
|
||||
|
||||
```python
|
||||
# users/views.py
|
||||
class UserViewSet(viewsets.ModelViewSet): # Component: User ViewSet (controller)
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
|
||||
def create(self, request):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
user = UserService.create_user(serializer.validated_data)
|
||||
return Response(UserSerializer(user).data)
|
||||
|
||||
# users/services.py
|
||||
class UserService: # Component: User Service (service)
|
||||
@staticmethod
|
||||
def create_user(data):
|
||||
# Business logic
|
||||
user = User.objects.create(**data)
|
||||
EmailService.send_welcome(user)
|
||||
return user
|
||||
|
||||
# users/models.py
|
||||
class User(models.Model): # Component: User Model (model)
|
||||
email = models.EmailField(unique=True)
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
db_table = 'users'
|
||||
```
|
||||
|
||||
**Components:**
|
||||
1. **User ViewSet** (controller) - Handles HTTP requests
|
||||
2. **User Service** (service) - Business logic
|
||||
3. **User Model** (model) - Data model
|
||||
|
||||
---
|
||||
|
||||
### Spring Boot Example (Java)
|
||||
|
||||
**Component identification in Spring Boot backend:**
|
||||
|
||||
```java
|
||||
// UserController.java
|
||||
@RestController
|
||||
@RequestMapping("/users")
|
||||
public class UserController { // Component: User Controller (controller)
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<User> createUser(@RequestBody CreateUserDto dto) {
|
||||
User user = userService.createUser(dto);
|
||||
return ResponseEntity.ok(user);
|
||||
}
|
||||
}
|
||||
|
||||
// UserService.java
|
||||
@Service
|
||||
public class UserService { // Component: User Service (service)
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
private EmailService emailService;
|
||||
|
||||
public User createUser(CreateUserDto dto) {
|
||||
User user = new User(dto);
|
||||
userRepository.save(user);
|
||||
emailService.sendWelcome(user);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// UserRepository.java
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<User, Long> { // Component: User Repository (repository)
|
||||
Optional<User> findByEmail(String email);
|
||||
}
|
||||
```
|
||||
|
||||
**Components:**
|
||||
1. **User Controller** (controller) - HTTP request handling
|
||||
2. **User Service** (service) - Business logic
|
||||
3. **User Repository** (repository) - Data access
|
||||
|
||||
**Patterns:**
|
||||
- Dependency Injection (@Autowired)
|
||||
- Repository Pattern (Spring Data JPA)
|
||||
- Layered Architecture
|
||||
|
||||
---
|
||||
|
||||
### React Example (Frontend)
|
||||
|
||||
**Component identification in React frontend:**
|
||||
|
||||
```typescript
|
||||
// src/features/users/UserList.tsx
|
||||
export function UserList() { // Component: User List (page/screen)
|
||||
const { users, loading } = useUsers();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{users.map(user => <UserCard key={user.id} user={user} />)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// src/features/users/hooks/useUsers.ts
|
||||
export function useUsers() { // Component: User Hook (state management)
|
||||
const [users, setUsers] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
UserService.fetchUsers().then(setUsers);
|
||||
}, []);
|
||||
|
||||
return { users, loading };
|
||||
}
|
||||
|
||||
// src/services/UserService.ts
|
||||
export class UserService { // Component: User Service (service)
|
||||
static async fetchUsers() {
|
||||
const response = await api.get('/users');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
static async createUser(data: CreateUserDto) {
|
||||
const response = await api.post('/users', data);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Components:**
|
||||
1. **User List** (page) - UI component
|
||||
2. **useUsers Hook** (state-management) - State management
|
||||
3. **User Service** (service) - API client
|
||||
246
skills/c4model-c3/templates/c3-component-template.json
Normal file
246
skills/c4model-c3/templates/c3-component-template.json
Normal file
@@ -0,0 +1,246 @@
|
||||
{
|
||||
"metadata": {
|
||||
"schema_version": "1.0.0",
|
||||
"generator": "melly-workflow",
|
||||
"generated_by": "c3-abstractor",
|
||||
"timestamp": "2025-11-17T10:30:00.000Z",
|
||||
"melly_version": "1.0.0",
|
||||
"parent_timestamp": "2025-11-17T10:20:00.000Z"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"id": "user-controller",
|
||||
"name": "User Controller",
|
||||
"type": "controller",
|
||||
"container_id": "backend-api",
|
||||
"path": "src/users/user.controller.ts",
|
||||
"description": "Handles HTTP requests for user management operations",
|
||||
"responsibilities": [
|
||||
"Validate incoming HTTP requests",
|
||||
"Route requests to UserService",
|
||||
"Transform service responses to HTTP responses",
|
||||
"Handle authentication and authorization"
|
||||
],
|
||||
"layer": "presentation",
|
||||
"dependencies": [
|
||||
{
|
||||
"target": "user-service",
|
||||
"type": "internal",
|
||||
"purpose": "Delegates business logic to UserService"
|
||||
}
|
||||
],
|
||||
"observations": [
|
||||
{
|
||||
"id": "obs-controller-rest-api",
|
||||
"title": "RESTful API design for user endpoints",
|
||||
"category": "design-patterns",
|
||||
"severity": "info",
|
||||
"description": "UserController follows RESTful conventions with standard HTTP methods (GET, POST, PUT, DELETE) for CRUD operations",
|
||||
"evidence": [
|
||||
{
|
||||
"type": "code",
|
||||
"location": "src/users/user.controller.ts",
|
||||
"snippet": "@Get() findAll() { ... }\n@Post() create(@Body() dto: CreateUserDto) { ... }"
|
||||
}
|
||||
],
|
||||
"impact": {
|
||||
"maintainability": "high",
|
||||
"testability": "high",
|
||||
"scalability": "medium"
|
||||
},
|
||||
"tags": ["rest-api", "http", "design-pattern"]
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"id": "rel-controller-to-service",
|
||||
"source_id": "user-controller",
|
||||
"target_id": "user-service",
|
||||
"type": "depends-on",
|
||||
"protocol": "method-call",
|
||||
"description": "UserController delegates business logic to UserService",
|
||||
"bidirectional": false
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"lines_of_code": 150,
|
||||
"cyclomatic_complexity": 6,
|
||||
"public_methods": 5,
|
||||
"dependencies_count": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "user-service",
|
||||
"name": "User Service",
|
||||
"type": "service",
|
||||
"container_id": "backend-api",
|
||||
"path": "src/users/user.service.ts",
|
||||
"description": "Manages user lifecycle operations including registration, updates, and deletion",
|
||||
"responsibilities": [
|
||||
"Validate user business rules",
|
||||
"Orchestrate user operations",
|
||||
"Coordinate between repositories and external services",
|
||||
"Implement user domain logic"
|
||||
],
|
||||
"layer": "business",
|
||||
"dependencies": [
|
||||
{
|
||||
"target": "user-repository",
|
||||
"type": "internal",
|
||||
"purpose": "Persists user data to database"
|
||||
},
|
||||
{
|
||||
"target": "email-service",
|
||||
"type": "internal",
|
||||
"purpose": "Sends user-related email notifications"
|
||||
}
|
||||
],
|
||||
"observations": [
|
||||
{
|
||||
"id": "obs-service-dependency-injection",
|
||||
"title": "Dependency injection pattern for loose coupling",
|
||||
"category": "design-patterns",
|
||||
"severity": "info",
|
||||
"description": "UserService uses constructor-based dependency injection for all dependencies, enabling loose coupling and easy testing",
|
||||
"evidence": [
|
||||
{
|
||||
"type": "code",
|
||||
"location": "src/users/user.service.ts",
|
||||
"snippet": "constructor(private userRepo: UserRepository, private emailService: EmailService) {}"
|
||||
}
|
||||
],
|
||||
"impact": {
|
||||
"maintainability": "high",
|
||||
"testability": "high",
|
||||
"scalability": "high"
|
||||
},
|
||||
"tags": ["dependency-injection", "loose-coupling", "testability"]
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"id": "rel-service-to-repository",
|
||||
"source_id": "user-service",
|
||||
"target_id": "user-repository",
|
||||
"type": "depends-on",
|
||||
"protocol": "method-call",
|
||||
"description": "UserService delegates data persistence to UserRepository",
|
||||
"bidirectional": false
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"lines_of_code": 280,
|
||||
"cyclomatic_complexity": 12,
|
||||
"public_methods": 8,
|
||||
"dependencies_count": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "user-repository",
|
||||
"name": "User Repository",
|
||||
"type": "repository",
|
||||
"container_id": "backend-api",
|
||||
"path": "src/users/user.repository.ts",
|
||||
"description": "Abstracts data access operations for User entity",
|
||||
"responsibilities": [
|
||||
"Execute database queries for user data",
|
||||
"Map database rows to User entities",
|
||||
"Handle database transaction management",
|
||||
"Provide query abstraction layer"
|
||||
],
|
||||
"layer": "data",
|
||||
"dependencies": [
|
||||
{
|
||||
"target": "user-model",
|
||||
"type": "internal",
|
||||
"purpose": "Defines the User entity structure"
|
||||
}
|
||||
],
|
||||
"observations": [
|
||||
{
|
||||
"id": "obs-repository-pattern",
|
||||
"title": "Repository pattern for data access abstraction",
|
||||
"category": "design-patterns",
|
||||
"severity": "info",
|
||||
"description": "UserRepository implements the Repository pattern, providing standard methods (findById, findAll, save, delete) to abstract database operations",
|
||||
"evidence": [
|
||||
{
|
||||
"type": "pattern",
|
||||
"location": "src/users/user.repository.ts",
|
||||
"snippet": "async findById(id: string): Promise<User>\nasync findAll(): Promise<User[]>\nasync save(user: User): Promise<User>\nasync delete(id: string): Promise<void>"
|
||||
}
|
||||
],
|
||||
"impact": {
|
||||
"maintainability": "high",
|
||||
"testability": "high",
|
||||
"scalability": "medium"
|
||||
},
|
||||
"tags": ["repository-pattern", "data-access", "abstraction"]
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"id": "rel-repository-to-model",
|
||||
"source_id": "user-repository",
|
||||
"target_id": "user-model",
|
||||
"type": "uses",
|
||||
"protocol": "type-reference",
|
||||
"description": "UserRepository uses User model for entity definition",
|
||||
"bidirectional": false
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"lines_of_code": 120,
|
||||
"cyclomatic_complexity": 4,
|
||||
"public_methods": 6,
|
||||
"dependencies_count": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total_components": 3,
|
||||
"by_type": {
|
||||
"controller": 1,
|
||||
"service": 1,
|
||||
"repository": 1,
|
||||
"model": 0,
|
||||
"middleware": 0,
|
||||
"utility": 0,
|
||||
"dto": 0,
|
||||
"adapter": 0,
|
||||
"factory": 0,
|
||||
"validator": 0,
|
||||
"facade": 0,
|
||||
"guard": 0
|
||||
},
|
||||
"by_layer": {
|
||||
"presentation": 1,
|
||||
"business": 1,
|
||||
"data": 1,
|
||||
"integration": 0
|
||||
},
|
||||
"patterns_detected": [
|
||||
"repository-pattern",
|
||||
"dependency-injection",
|
||||
"layered-architecture"
|
||||
],
|
||||
"observations_summary": {
|
||||
"total": 3,
|
||||
"by_category": {
|
||||
"design-patterns": 3,
|
||||
"code-structure": 0,
|
||||
"dependencies": 0,
|
||||
"complexity": 0,
|
||||
"coupling": 0,
|
||||
"cohesion": 0,
|
||||
"testing": 0,
|
||||
"documentation": 0
|
||||
},
|
||||
"by_severity": {
|
||||
"info": 3,
|
||||
"warning": 0,
|
||||
"critical": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user