Initial commit
This commit is contained in:
126
skills/c4model-relations/SKILL.md
Normal file
126
skills/c4model-relations/SKILL.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
name: c4model-relations
|
||||
description: Use when documenting relations, dependencies, and communications between systems, containers, or components in C4 Model architecture. Invoke during dependency mapping, integration analysis, or when users mention "relations", "dependencies", "connections", "how systems communicate", "API calls", "integrations", "data flow", or need to understand inter-system/component relationships.
|
||||
---
|
||||
|
||||
# C4 Model - Relations Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
Document HOW systems, containers, and components communicate—what flows between them, in which direction, and through which protocols.
|
||||
|
||||
**Core Principle:** Relations describe communication and dependencies. Use level-appropriate types with active voice descriptions.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Documenting system-to-system communication (C1)
|
||||
- Mapping container interactions (C2)
|
||||
- Describing component dependencies (C3)
|
||||
- Integration analysis and dependency mapping
|
||||
|
||||
## When NOT to Use
|
||||
|
||||
- Documenting static properties → use c4model-observations
|
||||
- Describing internal implementation details
|
||||
- Non-architectural documentation
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Level | Key Fields | Common Types | Focus |
|
||||
|-------|------------|--------------|-------|
|
||||
| C1 | `direction`, `protocol` | http-rest, message-queue, authentication | Protocols between systems |
|
||||
| C2 | `protocol`, `isAsync` | database-read-write, cache-read | Container interactions |
|
||||
| C3 | `coupling` | uses, injects, implements, observes | Code-level dependencies |
|
||||
|
||||
**IMPORTANT:** `direction` is C1 ONLY. Never use `direction` for C2 or C3 relations.
|
||||
|
||||
**Type specificity:** Match type to actual operation:
|
||||
- `cache-read` for read-only, `cache-write` for write-only, `cache-read-write` for both
|
||||
- `database-query` for read-only, `database-read-write` for both
|
||||
|
||||
**Complete type definitions** → [types.md](./types.md)
|
||||
|
||||
---
|
||||
|
||||
## Relation Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-frontend-to-api",
|
||||
"target": "backend-api",
|
||||
"type": "http-rest",
|
||||
"description": "Sends HTTP requests to fetch user data"
|
||||
}
|
||||
```
|
||||
|
||||
**Required:** `id`, `target`, `type`, `description`
|
||||
**Optional:** `protocol`, `direction` (C1), `coupling` (C3), `isAsync`, `tags`
|
||||
|
||||
---
|
||||
|
||||
## Direction and Coupling
|
||||
|
||||
**Direction (C1 only):**
|
||||
- `outbound` - Source initiates (Frontend → API)
|
||||
- `inbound` - Target initiates (Webhook → Your system)
|
||||
- `bidirectional` - Both ways (WebSocket)
|
||||
|
||||
**Coupling (C3 only):**
|
||||
- `loose` - Easily replaceable (DI, interfaces)
|
||||
- `tight` - Hard to replace (inheritance, direct refs)
|
||||
|
||||
---
|
||||
|
||||
## Writing Descriptions
|
||||
|
||||
✅ Active voice, start with verb, be specific:
|
||||
- "Sends HTTP requests to fetch user profile"
|
||||
- "Reads customer records from PostgreSQL"
|
||||
- "Injects UserRepository via DI"
|
||||
|
||||
❌ Avoid:
|
||||
- "Data is sent" (passive)
|
||||
- "Connection" (vague)
|
||||
- "Talks to the API" (unspecific)
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
**C1:** `{ "type": "http-rest", "direction": "outbound", "protocol": "HTTP/REST" }`
|
||||
**C2:** `{ "type": "database-read-write", "protocol": "PostgreSQL Wire Protocol" }`
|
||||
**C3:** `{ "type": "uses", "coupling": "loose" }`
|
||||
|
||||
**45+ examples** → [examples.md](./examples.md)
|
||||
|
||||
---
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
1. **Wrong level types** - Use C1 types at C1, C3 types at C3
|
||||
2. **Using direction for C2/C3** - `direction` is C1 ONLY, never use for containers or components
|
||||
3. **Wrong access type** - Use `cache-read` for read-only, not `cache-read-write`
|
||||
4. **Missing direction/coupling** - Required for C1/C3 respectively
|
||||
5. **Passive voice** - Always use active voice descriptions
|
||||
6. **Generic types** - Use `http-rest` not `http`
|
||||
7. **Invalid targets** - Ensure target entity exists
|
||||
|
||||
---
|
||||
|
||||
## Integration
|
||||
|
||||
**Commands:** `/melly-c1-systems`, `/melly-c2-containers`, `/melly-c3-components`
|
||||
|
||||
**Output:** `systems[].relations[]`, `containers[].relations[]`, `components[].relations[]`
|
||||
|
||||
**Validation:** `python ${CLAUDE_PLUGIN_ROOT}/validation/scripts/validate-c{1,2,3}-*.py`
|
||||
|
||||
---
|
||||
|
||||
## Detailed Documentation
|
||||
|
||||
- [types.md](./types.md) - Complete type definitions
|
||||
- [reference.md](./reference.md) - Methodology and best practices
|
||||
- [examples.md](./examples.md) - 45+ real-world examples
|
||||
870
skills/c4model-relations/examples.md
Normal file
870
skills/c4model-relations/examples.md
Normal file
@@ -0,0 +1,870 @@
|
||||
# C4 Model Relations - Comprehensive Examples
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides comprehensive examples of relations across all three C4 Model levels, covering all major relation types.
|
||||
|
||||
**Usage:** Reference these examples when documenting your own architecture relations.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [C1 System Context Examples](#c1-system-context-examples)
|
||||
2. [C2 Container Examples](#c2-container-examples)
|
||||
3. [C3 Component Examples](#c3-component-examples)
|
||||
4. [Cross-Level Examples](#cross-level-examples)
|
||||
|
||||
---
|
||||
|
||||
## C1 System Context Examples
|
||||
|
||||
### Example 1: REST API Communication
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-webapp-to-api",
|
||||
"target": "backend-api",
|
||||
"type": "http-rest",
|
||||
"description": "Sends HTTP requests to fetch and update customer data",
|
||||
"protocol": "HTTP/REST",
|
||||
"direction": "outbound",
|
||||
"isAsync": true,
|
||||
"tags": ["api", "rest", "critical"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Web application calls backend API for all data operations
|
||||
**Direction:** Outbound (web app initiates requests)
|
||||
**Protocol:** RESTful HTTP
|
||||
|
||||
---
|
||||
|
||||
### Example 2: External Payment Gateway
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-payment",
|
||||
"target": "stripe-payment-gateway",
|
||||
"type": "external-api",
|
||||
"description": "Processes payments via Stripe API for customer transactions",
|
||||
"protocol": "HTTPS/REST",
|
||||
"direction": "bidirectional",
|
||||
"isAsync": true,
|
||||
"tags": ["payment", "external", "stripe", "critical"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** E-commerce system integrates with Stripe for payments
|
||||
**Direction:** Bidirectional (API calls Stripe, Stripe sends webhooks)
|
||||
**Protocol:** HTTPS with REST and webhook callbacks
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Message Queue Processing
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-worker-to-queue",
|
||||
"target": "rabbitmq",
|
||||
"type": "message-queue",
|
||||
"description": "Consumes background job messages for email notifications and data processing",
|
||||
"protocol": "AMQP",
|
||||
"direction": "inbound",
|
||||
"isAsync": true,
|
||||
"tags": ["async", "queue", "rabbitmq", "worker"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Worker service consumes messages from queue
|
||||
**Direction:** Inbound (queue pushes messages to worker)
|
||||
**Protocol:** AMQP (RabbitMQ)
|
||||
|
||||
---
|
||||
|
||||
### Example 4: OAuth Authentication
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-app-to-auth",
|
||||
"target": "auth0",
|
||||
"type": "authentication",
|
||||
"description": "Authenticates users via OAuth 2.0 with social login support",
|
||||
"protocol": "OAuth 2.0",
|
||||
"direction": "outbound",
|
||||
"isAsync": false,
|
||||
"tags": ["auth", "oauth", "security", "auth0"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Application uses Auth0 for user authentication
|
||||
**Direction:** Outbound (app redirects to Auth0)
|
||||
**Protocol:** OAuth 2.0
|
||||
|
||||
---
|
||||
|
||||
### Example 5: GraphQL API
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-mobile-to-graphql",
|
||||
"target": "graphql-api",
|
||||
"type": "http-graphql",
|
||||
"description": "Queries GraphQL API for flexible data fetching with nested relations",
|
||||
"protocol": "HTTP/GraphQL",
|
||||
"direction": "outbound",
|
||||
"isAsync": true,
|
||||
"tags": ["graphql", "api", "mobile"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Mobile app uses GraphQL for efficient data queries
|
||||
**Direction:** Outbound (mobile queries API)
|
||||
**Protocol:** GraphQL over HTTP
|
||||
|
||||
---
|
||||
|
||||
### Example 6: WebSocket Real-Time Communication
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-chat-to-websocket",
|
||||
"target": "websocket-server",
|
||||
"type": "websocket",
|
||||
"description": "Maintains persistent WebSocket connection for real-time chat messages",
|
||||
"protocol": "WebSocket (RFC 6455)",
|
||||
"direction": "bidirectional",
|
||||
"isAsync": true,
|
||||
"tags": ["websocket", "realtime", "chat"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Chat application uses WebSocket for real-time messaging
|
||||
**Direction:** Bidirectional (messages flow both ways)
|
||||
**Protocol:** WebSocket
|
||||
|
||||
---
|
||||
|
||||
### Example 7: gRPC Microservices
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-gateway-to-services",
|
||||
"target": "microservices-cluster",
|
||||
"type": "grpc",
|
||||
"description": "Communicates with microservices via gRPC for high-performance RPC calls",
|
||||
"protocol": "HTTP/2 gRPC",
|
||||
"direction": "outbound",
|
||||
"isAsync": false,
|
||||
"tags": ["grpc", "microservices", "rpc"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** API gateway calls microservices via gRPC
|
||||
**Direction:** Outbound (gateway calls services)
|
||||
**Protocol:** gRPC over HTTP/2
|
||||
|
||||
---
|
||||
|
||||
### Example 8: Event Stream Processing
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-analytics-to-kafka",
|
||||
"target": "kafka-cluster",
|
||||
"type": "event-stream",
|
||||
"description": "Consumes real-time clickstream events for analytics processing",
|
||||
"protocol": "Kafka Protocol",
|
||||
"direction": "inbound",
|
||||
"isAsync": true,
|
||||
"tags": ["kafka", "streaming", "analytics"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Analytics system processes events from Kafka
|
||||
**Direction:** Inbound (Kafka streams events to analytics)
|
||||
**Protocol:** Kafka streaming protocol
|
||||
|
||||
---
|
||||
|
||||
### Example 9: Database Connection
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-app-to-database",
|
||||
"target": "postgres-cluster",
|
||||
"type": "database-connection",
|
||||
"description": "Connects to PostgreSQL cluster for persistent data storage",
|
||||
"protocol": "PostgreSQL Wire Protocol",
|
||||
"direction": "outbound",
|
||||
"isAsync": false,
|
||||
"tags": ["database", "postgres", "storage"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Application system connects to database system
|
||||
**Direction:** Outbound (app queries database)
|
||||
**Protocol:** PostgreSQL protocol
|
||||
|
||||
---
|
||||
|
||||
### Example 10: Email Service Integration
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-notif-to-sendgrid",
|
||||
"target": "sendgrid",
|
||||
"type": "external-api",
|
||||
"description": "Sends transactional emails via SendGrid API",
|
||||
"protocol": "HTTPS/REST",
|
||||
"direction": "outbound",
|
||||
"isAsync": true,
|
||||
"tags": ["email", "sendgrid", "notifications"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Notification system sends emails via SendGrid
|
||||
**Direction:** Outbound (system calls SendGrid API)
|
||||
**Protocol:** HTTPS REST API
|
||||
|
||||
---
|
||||
|
||||
### Example 11: File Transfer
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-backup-to-s3",
|
||||
"target": "aws-s3",
|
||||
"type": "file-transfer",
|
||||
"description": "Transfers backup files to S3 for long-term storage",
|
||||
"protocol": "HTTPS S3 API",
|
||||
"direction": "outbound",
|
||||
"isAsync": true,
|
||||
"tags": ["backup", "s3", "storage"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Backup system uploads files to S3
|
||||
**Direction:** Outbound (backup pushes to S3)
|
||||
**Protocol:** S3 API over HTTPS
|
||||
|
||||
---
|
||||
|
||||
### Example 12: Read Replica Access
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-reporting-to-replica",
|
||||
"target": "postgres-read-replica",
|
||||
"type": "database-query",
|
||||
"description": "Queries read replica for reporting without impacting primary database",
|
||||
"protocol": "PostgreSQL Wire Protocol",
|
||||
"direction": "outbound",
|
||||
"isAsync": false,
|
||||
"tags": ["database", "reporting", "read-replica"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Reporting system queries read-only replica
|
||||
**Direction:** Outbound (reporting queries replica)
|
||||
**Protocol:** PostgreSQL (read-only)
|
||||
|
||||
---
|
||||
|
||||
## C2 Container Examples
|
||||
|
||||
### Example 1: SPA to API
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-spa-to-api",
|
||||
"target": "express-api",
|
||||
"type": "http-rest",
|
||||
"description": "Fetches user data and submits forms via REST API endpoints",
|
||||
"protocol": "HTTP/REST",
|
||||
"isAsync": true,
|
||||
"tags": ["rest", "ajax", "fetch", "spa"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** React SPA calls Express backend
|
||||
**Container Flow:** Browser (SPA) → Server (API)
|
||||
**Operations:** GET, POST, PUT, DELETE
|
||||
|
||||
---
|
||||
|
||||
### Example 2: API to PostgreSQL
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-postgres",
|
||||
"target": "postgres-container",
|
||||
"type": "database-read-write",
|
||||
"description": "Reads and writes application data using Sequelize ORM",
|
||||
"protocol": "PostgreSQL Wire Protocol",
|
||||
"isAsync": false,
|
||||
"tags": ["database", "postgres", "sql", "sequelize"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Express API accesses PostgreSQL database
|
||||
**Container Flow:** API Server → Database Container
|
||||
**Operations:** Full CRUD via ORM
|
||||
|
||||
---
|
||||
|
||||
### Example 3: API to Redis Cache
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-redis",
|
||||
"target": "redis-container",
|
||||
"type": "cache-read-write",
|
||||
"description": "Caches frequently accessed data to improve response times",
|
||||
"protocol": "Redis Protocol (RESP)",
|
||||
"isAsync": false,
|
||||
"tags": ["cache", "redis", "performance"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** API caches query results in Redis
|
||||
**Container Flow:** API Server → Cache Container
|
||||
**Operations:** GET, SET, DEL
|
||||
|
||||
---
|
||||
|
||||
### Example 4: Worker to Message Queue
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-worker-to-queue",
|
||||
"target": "rabbitmq-container",
|
||||
"type": "message-subscribe",
|
||||
"description": "Consumes email notification jobs from RabbitMQ queue",
|
||||
"protocol": "AMQP",
|
||||
"isAsync": true,
|
||||
"tags": ["queue", "worker", "email", "rabbitmq"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Worker consumes messages from RabbitMQ
|
||||
**Container Flow:** Worker Container ← Message Queue Container
|
||||
**Pattern:** Consumer (pull model)
|
||||
|
||||
---
|
||||
|
||||
### Example 5: API to Message Queue
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-queue",
|
||||
"target": "rabbitmq-container",
|
||||
"type": "message-publish",
|
||||
"description": "Publishes order completion events for async processing",
|
||||
"protocol": "AMQP",
|
||||
"isAsync": true,
|
||||
"tags": ["queue", "publisher", "async"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** API publishes events to queue
|
||||
**Container Flow:** API Server → Message Queue Container
|
||||
**Pattern:** Publisher (push model)
|
||||
|
||||
---
|
||||
|
||||
### Example 6: Frontend to GraphQL
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-frontend-to-graphql",
|
||||
"target": "graphql-server",
|
||||
"type": "http-graphql",
|
||||
"description": "Queries GraphQL API with Apollo Client for nested data fetching",
|
||||
"protocol": "HTTP/GraphQL",
|
||||
"isAsync": true,
|
||||
"tags": ["graphql", "apollo", "queries"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Next.js frontend uses GraphQL API
|
||||
**Container Flow:** Frontend Container → GraphQL Server Container
|
||||
**Operations:** Query, Mutation
|
||||
|
||||
---
|
||||
|
||||
### Example 7: API to S3 Storage
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-s3",
|
||||
"target": "aws-s3",
|
||||
"type": "file-write",
|
||||
"description": "Uploads user-generated images to S3 bucket",
|
||||
"protocol": "HTTPS S3 API",
|
||||
"isAsync": true,
|
||||
"tags": ["s3", "upload", "images"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** API uploads files to S3
|
||||
**Container Flow:** API Server → S3 Storage
|
||||
**Operations:** PutObject, DeleteObject
|
||||
|
||||
---
|
||||
|
||||
### Example 8: Worker Reading Files
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-worker-to-s3",
|
||||
"target": "aws-s3",
|
||||
"type": "file-read",
|
||||
"description": "Reads CSV files from S3 for batch processing",
|
||||
"protocol": "HTTPS S3 API",
|
||||
"isAsync": true,
|
||||
"tags": ["s3", "batch", "csv"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Background worker processes files from S3
|
||||
**Container Flow:** Worker Container → S3 Storage
|
||||
**Operations:** GetObject, ListObjects
|
||||
|
||||
---
|
||||
|
||||
### Example 9: Browser to CDN
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-browser-to-cdn",
|
||||
"target": "cloudfront-cdn",
|
||||
"type": "cdn-fetch",
|
||||
"description": "Fetches static assets (JS, CSS, images) from CDN",
|
||||
"protocol": "HTTPS",
|
||||
"isAsync": true,
|
||||
"tags": ["cdn", "static", "assets"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Browser loads assets from CloudFront
|
||||
**Container Flow:** Browser → CDN
|
||||
**Operations:** GET (cached assets)
|
||||
|
||||
---
|
||||
|
||||
### Example 10: WebSocket Server
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-client-to-websocket",
|
||||
"target": "websocket-server",
|
||||
"type": "websocket",
|
||||
"description": "Maintains WebSocket connection for real-time notifications",
|
||||
"protocol": "WebSocket Protocol",
|
||||
"isAsync": true,
|
||||
"tags": ["websocket", "realtime", "notifications"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Web client connects to WebSocket server
|
||||
**Container Flow:** Browser ↔ WebSocket Server (bidirectional)
|
||||
**Operations:** Send, Receive messages
|
||||
|
||||
---
|
||||
|
||||
### Example 11: Service to MySQL
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-service-to-mysql",
|
||||
"target": "mysql-container",
|
||||
"type": "database-connection",
|
||||
"description": "Connects to MySQL database for general data operations",
|
||||
"protocol": "MySQL Wire Protocol",
|
||||
"isAsync": false,
|
||||
"tags": ["database", "mysql", "generic"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Service container accesses MySQL
|
||||
**Container Flow:** Service Container → MySQL Container
|
||||
**Operations:** Mixed read/write
|
||||
|
||||
---
|
||||
|
||||
### Example 12: Auth Service to Session Cache
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-auth-to-cache",
|
||||
"target": "redis-container",
|
||||
"type": "cache-access",
|
||||
"description": "Accesses session cache for user authentication state",
|
||||
"protocol": "Redis Protocol",
|
||||
"isAsync": false,
|
||||
"tags": ["cache", "session", "auth"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Auth service stores sessions in Redis
|
||||
**Container Flow:** Auth Container → Redis Container
|
||||
**Operations:** Session management
|
||||
|
||||
---
|
||||
|
||||
## C3 Component Examples
|
||||
|
||||
### Example 1: Controller Uses Service
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-controller-to-service",
|
||||
"target": "user-service",
|
||||
"type": "uses",
|
||||
"description": "Delegates business logic operations to UserService",
|
||||
"coupling": "loose",
|
||||
"tags": ["service-layer", "delegation"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Layered architecture pattern
|
||||
**Component Flow:** UserController → UserService
|
||||
**Pattern:** Service layer delegation
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Service Injects Repository
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-service-to-repo",
|
||||
"target": "user-repository",
|
||||
"type": "injects",
|
||||
"description": "Injects UserRepository via dependency injection for data access",
|
||||
"coupling": "loose",
|
||||
"tags": ["di", "repository-pattern"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Dependency injection pattern
|
||||
**Component Flow:** UserService ← UserRepository (injected)
|
||||
**Pattern:** Constructor injection
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Auth Provides Context
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-auth-to-user",
|
||||
"target": "user-component",
|
||||
"type": "provides",
|
||||
"description": "Provides authenticated user information to consuming components",
|
||||
"coupling": "loose",
|
||||
"tags": ["auth", "context", "provider"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** React context provider pattern
|
||||
**Component Flow:** AuthProvider → Consumers
|
||||
**Pattern:** Provider/Consumer
|
||||
|
||||
---
|
||||
|
||||
### Example 4: Validator Extends Base
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-validator-extends-base",
|
||||
"target": "base-validator",
|
||||
"type": "inherits",
|
||||
"description": "Extends base validation logic with custom rules",
|
||||
"coupling": "tight",
|
||||
"tags": ["inheritance", "validation"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** OOP inheritance hierarchy
|
||||
**Component Flow:** CustomValidator extends BaseValidator
|
||||
**Pattern:** Classical inheritance
|
||||
|
||||
---
|
||||
|
||||
### Example 5: Payment Observes Order Events
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-payment-observes-order",
|
||||
"target": "order-component",
|
||||
"type": "observes",
|
||||
"description": "Listens to order completion events to trigger payment processing",
|
||||
"coupling": "loose",
|
||||
"tags": ["event", "observer-pattern", "payment"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Observer/subscriber pattern
|
||||
**Component Flow:** PaymentService ← OrderService (events)
|
||||
**Pattern:** Event-driven
|
||||
|
||||
---
|
||||
|
||||
### Example 6: Order Notifies Subscribers
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-order-notifies-payment",
|
||||
"target": "payment-component",
|
||||
"type": "notifies",
|
||||
"description": "Emits order completion events to registered subscribers",
|
||||
"coupling": "loose",
|
||||
"tags": ["event", "publisher", "orders"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Publisher pattern
|
||||
**Component Flow:** OrderService → Subscribers
|
||||
**Pattern:** Event emitter
|
||||
|
||||
---
|
||||
|
||||
### Example 7: Service Implements Interface
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-service-implements-interface",
|
||||
"target": "repository-interface",
|
||||
"type": "implements",
|
||||
"description": "Implements IUserRepository contract for data access abstraction",
|
||||
"coupling": "loose",
|
||||
"tags": ["interface", "contract", "di"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Interface-based programming
|
||||
**Component Flow:** UserRepository implements IUserRepository
|
||||
**Pattern:** Dependency inversion
|
||||
|
||||
---
|
||||
|
||||
### Example 8: Logger Subscribes to Errors
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-logger-subscribes-errors",
|
||||
"target": "error-handler",
|
||||
"type": "event-subscriber",
|
||||
"description": "Subscribes to error events for centralized logging",
|
||||
"coupling": "loose",
|
||||
"tags": ["event", "logging", "observer"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Error handling with observers
|
||||
**Component Flow:** Logger ← ErrorHandler (events)
|
||||
**Pattern:** Event subscription
|
||||
|
||||
---
|
||||
|
||||
### Example 9: Controller Calls Service Methods
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-controller-calls-service",
|
||||
"target": "order-service",
|
||||
"type": "calls",
|
||||
"description": "Invokes createOrder and getOrderById methods directly",
|
||||
"coupling": "tight",
|
||||
"tags": ["method-call", "direct-call"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Direct method invocation
|
||||
**Component Flow:** OrderController → OrderService.createOrder()
|
||||
**Pattern:** Direct coupling
|
||||
|
||||
---
|
||||
|
||||
### Example 10: Component Composes Others
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-order-composes-items",
|
||||
"target": "order-item",
|
||||
"type": "composes",
|
||||
"description": "Composes OrderItem instances as integral parts of Order",
|
||||
"coupling": "tight",
|
||||
"tags": ["composition", "has-a"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Object composition
|
||||
**Component Flow:** Order has OrderItem[]
|
||||
**Pattern:** Composition (strong has-a)
|
||||
|
||||
---
|
||||
|
||||
### Example 11: Component Aggregates References
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-cart-aggregates-products",
|
||||
"target": "product",
|
||||
"type": "aggregates",
|
||||
"description": "Aggregates Product references without owning them",
|
||||
"coupling": "moderate",
|
||||
"tags": ["aggregation", "reference"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Object aggregation
|
||||
**Component Flow:** ShoppingCart has Product[] (references)
|
||||
**Pattern:** Aggregation (weak has-a)
|
||||
|
||||
---
|
||||
|
||||
### Example 12: Component Imports Utilities
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-service-imports-utils",
|
||||
"target": "date-utils",
|
||||
"type": "imports",
|
||||
"description": "Imports date formatting utilities via ES6 import",
|
||||
"coupling": "tight",
|
||||
"tags": ["import", "utilities"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Module imports
|
||||
**Component Flow:** OrderService imports { formatDate } from './utils'
|
||||
**Pattern:** ES6 modules
|
||||
|
||||
---
|
||||
|
||||
### Example 13: Facade Delegates to Subsystems
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-facade-delegates",
|
||||
"target": "subsystems",
|
||||
"type": "delegates",
|
||||
"description": "Delegates complex operations to multiple subsystems",
|
||||
"coupling": "moderate",
|
||||
"tags": ["facade", "delegation"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Facade pattern
|
||||
**Component Flow:** OrderFacade → [PaymentService, InventoryService, ShippingService]
|
||||
**Pattern:** Facade
|
||||
|
||||
---
|
||||
|
||||
### Example 14: Component Extends Functionality
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-advanced-extends-basic",
|
||||
"target": "basic-search",
|
||||
"type": "extends",
|
||||
"description": "Extends basic search with advanced filtering and sorting",
|
||||
"coupling": "tight",
|
||||
"tags": ["inheritance", "extension"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** Feature extension via inheritance
|
||||
**Component Flow:** AdvancedSearch extends BasicSearch
|
||||
**Pattern:** Extension
|
||||
|
||||
---
|
||||
|
||||
### Example 15: Consumer Uses Context
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "rel-profile-consumes-auth",
|
||||
"target": "auth-context",
|
||||
"type": "consumes",
|
||||
"description": "Consumes authenticated user data from AuthContext",
|
||||
"coupling": "loose",
|
||||
"tags": ["context", "react", "consumer"]
|
||||
}
|
||||
```
|
||||
|
||||
**Context:** React context consumer
|
||||
**Component Flow:** UserProfile consumes AuthContext
|
||||
**Pattern:** Context API
|
||||
|
||||
---
|
||||
|
||||
## Cross-Level Examples
|
||||
|
||||
### Example: Full Stack Feature
|
||||
|
||||
**C1 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "mobile-app",
|
||||
"target": "backend-api",
|
||||
"type": "http-rest",
|
||||
"direction": "outbound"
|
||||
}
|
||||
```
|
||||
|
||||
**C2 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "react-native-app",
|
||||
"target": "express-api",
|
||||
"type": "http-rest"
|
||||
},
|
||||
{
|
||||
"source": "express-api",
|
||||
"target": "postgres-db",
|
||||
"type": "database-read-write"
|
||||
}
|
||||
```
|
||||
|
||||
**C3 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "user-controller",
|
||||
"target": "user-service",
|
||||
"type": "uses",
|
||||
"coupling": "loose"
|
||||
},
|
||||
{
|
||||
"source": "user-service",
|
||||
"target": "user-repository",
|
||||
"type": "injects",
|
||||
"coupling": "loose"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
These examples demonstrate:
|
||||
|
||||
- **C1 Relations:** System-to-system communication patterns
|
||||
- **C2 Relations:** Container-to-container interactions
|
||||
- **C3 Relations:** Component-level dependencies and design patterns
|
||||
|
||||
Each example includes:
|
||||
- Unique ID
|
||||
- Target entity
|
||||
- Relation type
|
||||
- Clear description
|
||||
- Appropriate metadata (direction, protocol, coupling)
|
||||
- Tags for categorization
|
||||
|
||||
Use these as templates for documenting your own architecture relations.
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-11-17
|
||||
421
skills/c4model-relations/reference.md
Normal file
421
skills/c4model-relations/reference.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# C4 Model Relations - Detailed Reference
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Protocol Documentation Guidelines](#protocol-documentation-guidelines)
|
||||
2. [Direction vs Coupling](#direction-vs-coupling)
|
||||
3. [Best Practices per Level](#best-practices-per-level)
|
||||
4. [Graph Validity Rules](#graph-validity-rules)
|
||||
5. [Common Patterns](#common-patterns)
|
||||
|
||||
---
|
||||
|
||||
## Relation Type Definitions
|
||||
|
||||
For complete type definitions for all C4 levels, see [types.md](./types.md).
|
||||
|
||||
---
|
||||
|
||||
## Protocol Documentation Guidelines
|
||||
|
||||
### When to Document Protocol
|
||||
|
||||
**Always include protocol for:**
|
||||
- C1 system-to-system communication
|
||||
- C2 container-to-container communication
|
||||
- External integrations
|
||||
- Any network communication
|
||||
|
||||
**Optional for:**
|
||||
- C3 code-level dependencies (unless calling external APIs)
|
||||
- In-process method calls
|
||||
|
||||
### Protocol Format
|
||||
|
||||
Use standard protocol names:
|
||||
|
||||
**Good:**
|
||||
- `HTTP/REST`
|
||||
- `HTTP/2 gRPC`
|
||||
- `PostgreSQL Wire Protocol`
|
||||
- `AMQP`
|
||||
- `OAuth 2.0`
|
||||
|
||||
**Bad:**
|
||||
- `rest` (too vague)
|
||||
- `http` (specify REST, GraphQL, etc.)
|
||||
- `database` (specify PostgreSQL, MySQL, etc.)
|
||||
|
||||
### Protocol Details to Include
|
||||
|
||||
For **HTTP-based protocols:**
|
||||
- HTTP version (HTTP/1.1, HTTP/2)
|
||||
- API style (REST, GraphQL, RPC)
|
||||
- Authentication method
|
||||
- Content type (JSON, XML, etc.)
|
||||
|
||||
For **Database protocols:**
|
||||
- Database type (PostgreSQL, MySQL, MongoDB)
|
||||
- Connection method (wire protocol, ORM)
|
||||
- Authentication method
|
||||
|
||||
For **Messaging protocols:**
|
||||
- Broker type (RabbitMQ, Kafka, SQS)
|
||||
- Protocol (AMQP, Kafka Protocol)
|
||||
- Pattern (pub-sub, work queue)
|
||||
|
||||
---
|
||||
|
||||
## Direction vs Coupling
|
||||
|
||||
### Direction (C1 Level)
|
||||
|
||||
**Purpose:** Describes the flow of communication between systems
|
||||
|
||||
#### outbound
|
||||
**Definition:** Source system initiates communication
|
||||
**Example:** Frontend makes HTTP requests to API
|
||||
**Use when:** Source actively calls, queries, or requests from target
|
||||
|
||||
#### inbound
|
||||
**Definition:** Target system initiates communication
|
||||
**Example:** External webhook calls your API
|
||||
**Use when:** Target pushes data, calls back, or triggers source
|
||||
|
||||
#### bidirectional
|
||||
**Definition:** Communication flows both ways
|
||||
**Example:** WebSocket connection with messages in both directions
|
||||
**Use when:** True two-way communication (avoid overusing)
|
||||
|
||||
**Best Practice:** Prefer outbound/inbound over bidirectional for clarity. Create two separate relations if needed.
|
||||
|
||||
### Coupling (C3 Level)
|
||||
|
||||
**Purpose:** Describes strength of dependency between components
|
||||
|
||||
#### loose
|
||||
**Definition:** Minimal dependency, easily replaceable
|
||||
**Characteristics:**
|
||||
- Components interact through interfaces or abstractions
|
||||
- Easy to test (can use mocks)
|
||||
- Easy to swap implementations
|
||||
- Changes in one component don't force changes in another
|
||||
|
||||
**Examples:**
|
||||
- Dependency injection
|
||||
- Interface-based dependencies
|
||||
- Event-driven communication
|
||||
- Plugin architectures
|
||||
|
||||
#### tight
|
||||
**Definition:** Strong dependency, hard to replace
|
||||
**Characteristics:**
|
||||
- Direct class references
|
||||
- Hard to test without real implementation
|
||||
- Hard to swap implementations
|
||||
- Changes cascade between components
|
||||
|
||||
**Examples:**
|
||||
- Direct class instantiation
|
||||
- Class inheritance
|
||||
- Static method calls
|
||||
- Global state dependencies
|
||||
|
||||
**Best Practice:** Prefer loose coupling. Document tight coupling as potential refactoring opportunity.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices per Level
|
||||
|
||||
### C1 System Context Best Practices
|
||||
|
||||
1. **Focus on protocols**
|
||||
- Always specify communication protocol
|
||||
- Include authentication method for external relations
|
||||
- Document sync vs async nature
|
||||
|
||||
2. **Specify direction**
|
||||
- Use outbound for active calls (API requests, queries)
|
||||
- Use inbound for passive receives (webhooks, callbacks)
|
||||
- Avoid bidirectional unless truly necessary
|
||||
|
||||
3. **Document external integrations**
|
||||
- Mark external services clearly
|
||||
- Include vendor name (Stripe, SendGrid, etc.)
|
||||
- Note criticality for business operations
|
||||
|
||||
4. **Group similar relations**
|
||||
- One relation for "Frontend → API" covering all endpoints
|
||||
- Don't create separate relations for each API endpoint
|
||||
|
||||
### C2 Container Best Practices
|
||||
|
||||
1. **Be specific about API style**
|
||||
- Use `http-rest` not just `http`
|
||||
- Use `http-graphql` for GraphQL
|
||||
- Distinguish between REST and RPC
|
||||
|
||||
2. **Differentiate read vs write**
|
||||
- Use `database-query` for read-only
|
||||
- Use `database-write` for write-only
|
||||
- Use `database-read-write` for both
|
||||
|
||||
3. **Document cache patterns**
|
||||
- Specify cache operations (read, write, both)
|
||||
- Include eviction strategy if relevant
|
||||
- Note cache hit/miss criticality
|
||||
|
||||
4. **Show message patterns**
|
||||
- Use `message-publish` for producers
|
||||
- Use `message-subscribe` for consumers
|
||||
- Document topic/queue names in description
|
||||
|
||||
### C3 Component Best Practices
|
||||
|
||||
1. **Assess coupling**
|
||||
- Always include coupling field
|
||||
- Prefer loose coupling
|
||||
- Document tight coupling as technical debt
|
||||
|
||||
2. **Document design patterns**
|
||||
- Use `injects` for DI
|
||||
- Use `observes`/`notifies` for Observer pattern
|
||||
- Use `implements` for Strategy/Interface patterns
|
||||
|
||||
3. **Show dependency direction**
|
||||
- High-level → low-level (Controller → Service → Repository)
|
||||
- Abstract → concrete (Interface ← Implementation)
|
||||
- Stable → volatile
|
||||
|
||||
4. **Highlight circular dependencies**
|
||||
- Flag as warning in observations
|
||||
- Consider refactoring
|
||||
- Document workaround if intentional
|
||||
|
||||
---
|
||||
|
||||
## Graph Validity Rules
|
||||
|
||||
### Referential Integrity
|
||||
|
||||
**Rule:** All relation targets must reference valid entity IDs
|
||||
|
||||
**Validation:**
|
||||
```python
|
||||
# Pseudo-code
|
||||
for relation in entity.relations:
|
||||
if relation.target not in valid_entity_ids:
|
||||
raise ValidationError(f"Invalid target: {relation.target}")
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
✅ Valid:
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-db",
|
||||
"target": "postgres-db", // postgres-db exists in containers list
|
||||
"type": "database-read-write"
|
||||
}
|
||||
```
|
||||
|
||||
❌ Invalid:
|
||||
```json
|
||||
{
|
||||
"id": "rel-api-to-db",
|
||||
"target": "mysql-db", // mysql-db doesn't exist
|
||||
"type": "database-read-write"
|
||||
}
|
||||
```
|
||||
|
||||
### No Self-References
|
||||
|
||||
**Rule:** Source cannot equal target
|
||||
|
||||
✅ Valid:
|
||||
```json
|
||||
{ "source": "api-service", "target": "database" }
|
||||
```
|
||||
|
||||
❌ Invalid:
|
||||
```json
|
||||
{ "source": "api-service", "target": "api-service" }
|
||||
```
|
||||
|
||||
### Cross-Level References
|
||||
|
||||
**Rule:** Relations can reference entities at same or different levels
|
||||
|
||||
**C1 → C1:** System to system ✅
|
||||
**C2 → C2:** Container to container within same system ✅
|
||||
**C2 → C1:** Container to external system ✅
|
||||
**C3 → C3:** Component to component within same container ✅
|
||||
**C3 → C2:** Component to external container ✅
|
||||
|
||||
### Bidirectional Relations
|
||||
|
||||
**Rule:** If bidirectional, both entities should document the relation
|
||||
|
||||
**Best Practice:** Prefer two unidirectional relations over one bidirectional
|
||||
|
||||
✅ Preferred:
|
||||
```json
|
||||
// In entity A
|
||||
{ "target": "B", "type": "http-rest", "direction": "outbound" }
|
||||
// In entity B
|
||||
{ "target": "A", "type": "websocket", "direction": "inbound" }
|
||||
```
|
||||
|
||||
❌ Less clear:
|
||||
```json
|
||||
// In entity A
|
||||
{ "target": "B", "type": "http-rest", "direction": "bidirectional" }
|
||||
// No corresponding relation in B
|
||||
```
|
||||
|
||||
### Dangling References
|
||||
|
||||
**Rule:** All targets should eventually resolve to a documented entity
|
||||
|
||||
**Exceptions:**
|
||||
- External systems not in your control
|
||||
- Mark these clearly in description
|
||||
- Use `external-api` or similar type
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Frontend-Backend Pattern
|
||||
|
||||
**C1 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "web-application",
|
||||
"target": "backend-api",
|
||||
"type": "http-rest",
|
||||
"direction": "outbound",
|
||||
"protocol": "HTTP/REST"
|
||||
}
|
||||
```
|
||||
|
||||
**C2 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "react-spa",
|
||||
"target": "express-api",
|
||||
"type": "http-rest",
|
||||
"protocol": "HTTP/REST",
|
||||
"isAsync": true
|
||||
}
|
||||
```
|
||||
|
||||
### API-Database Pattern
|
||||
|
||||
**C2 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "express-api",
|
||||
"target": "postgres-db",
|
||||
"type": "database-read-write",
|
||||
"protocol": "PostgreSQL Wire Protocol",
|
||||
"isAsync": false
|
||||
}
|
||||
```
|
||||
|
||||
### Event-Driven Pattern
|
||||
|
||||
**C1 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "order-service",
|
||||
"target": "message-queue",
|
||||
"type": "message-queue",
|
||||
"direction": "outbound",
|
||||
"protocol": "AMQP",
|
||||
"isAsync": true
|
||||
}
|
||||
```
|
||||
|
||||
**C2 Level:**
|
||||
```json
|
||||
{
|
||||
"source": "order-container",
|
||||
"target": "rabbitmq",
|
||||
"type": "message-publish",
|
||||
"protocol": "AMQP"
|
||||
},
|
||||
{
|
||||
"source": "notification-worker",
|
||||
"target": "rabbitmq",
|
||||
"type": "message-subscribe",
|
||||
"protocol": "AMQP"
|
||||
}
|
||||
```
|
||||
|
||||
### Layered Architecture Pattern (C3)
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "user-controller",
|
||||
"target": "user-service",
|
||||
"type": "uses",
|
||||
"coupling": "loose"
|
||||
},
|
||||
{
|
||||
"source": "user-service",
|
||||
"target": "user-repository",
|
||||
"type": "injects",
|
||||
"coupling": "loose"
|
||||
}
|
||||
```
|
||||
|
||||
### Observer Pattern (C3)
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "order-service",
|
||||
"target": "order-events",
|
||||
"type": "notifies",
|
||||
"coupling": "loose"
|
||||
},
|
||||
{
|
||||
"source": "payment-service",
|
||||
"target": "order-events",
|
||||
"type": "observes",
|
||||
"coupling": "loose"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Before finalizing relations documentation:
|
||||
|
||||
- [ ] All relation IDs are unique
|
||||
- [ ] All targets reference valid entity IDs
|
||||
- [ ] No self-references (source ≠ target)
|
||||
- [ ] Direction specified for C1 relations
|
||||
- [ ] Coupling specified for C3 relations
|
||||
- [ ] Protocol documented for network communication
|
||||
- [ ] Descriptions in active voice
|
||||
- [ ] Types match C4 level (C1 types at C1, etc.)
|
||||
- [ ] isAsync set appropriately
|
||||
- [ ] Tags use lowercase kebab-case
|
||||
- [ ] Critical relations tagged appropriately
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **Type Definitions:** [types.md](./types.md)
|
||||
- **Examples:** [examples.md](./examples.md)
|
||||
- **Main Skill:** [SKILL.md](./SKILL.md)
|
||||
- **Validation Scripts:** `${CLAUDE_PLUGIN_ROOT}/validation/scripts/`
|
||||
- **Schema Documentation:** `/docs/observations-relations-schema.md`
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-11-17
|
||||
498
skills/c4model-relations/types.md
Normal file
498
skills/c4model-relations/types.md
Normal file
@@ -0,0 +1,498 @@
|
||||
# C4 Model Relation Types - Complete Reference
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides comprehensive definitions for all relation types across C1, C2, and C3 levels of the C4 Model.
|
||||
|
||||
**Usage:** Reference this document when choosing the appropriate relation type for your architecture documentation.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [C1 System Context Relation Types](#c1-system-context-relation-types)
|
||||
2. [C2 Container Relation Types](#c2-container-relation-types)
|
||||
3. [C3 Component Relation Types](#c3-component-relation-types)
|
||||
4. [Type Selection Guidelines](#type-selection-guidelines)
|
||||
|
||||
---
|
||||
|
||||
## C1 System Context Relation Types
|
||||
|
||||
### Network Communication Types
|
||||
|
||||
#### http / https / http-rest
|
||||
**Description:** HTTP/HTTPS communication, typically RESTful APIs
|
||||
**When to use:** REST APIs, web requests, standard HTTP communication
|
||||
**Protocols:** HTTP/1.1, HTTP/2, HTTP/3
|
||||
**Direction:** Usually outbound (client calls server)
|
||||
**Example:** Web application calls backend REST API for data
|
||||
|
||||
#### http-graphql
|
||||
**Description:** GraphQL API communication over HTTP
|
||||
**When to use:** GraphQL queries and mutations
|
||||
**Protocols:** HTTP with GraphQL
|
||||
**Direction:** Usually outbound (client queries server)
|
||||
**Example:** Frontend queries GraphQL API for flexible data fetching
|
||||
|
||||
#### grpc
|
||||
**Description:** gRPC remote procedure calls
|
||||
**When to use:** High-performance RPC, microservice communication
|
||||
**Protocols:** HTTP/2 with Protocol Buffers
|
||||
**Direction:** Usually outbound (client calls service)
|
||||
**Example:** Microservices communicate via gRPC for low latency
|
||||
|
||||
#### graphql
|
||||
**Description:** GraphQL protocol (alternative to http-graphql)
|
||||
**When to use:** When emphasizing GraphQL over HTTP transport
|
||||
**Example:** Same as http-graphql
|
||||
|
||||
#### websocket
|
||||
**Description:** Bidirectional real-time communication
|
||||
**When to use:** Live updates, chat, real-time notifications
|
||||
**Protocols:** WebSocket Protocol (RFC 6455)
|
||||
**Direction:** Bidirectional
|
||||
**Example:** Chat application maintains persistent WebSocket connection
|
||||
|
||||
#### rpc
|
||||
**Description:** Generic remote procedure call
|
||||
**When to use:** Custom RPC protocols, legacy RPC systems
|
||||
**Example:** XML-RPC, JSON-RPC communication
|
||||
|
||||
#### soap
|
||||
**Description:** SOAP web services
|
||||
**When to use:** Enterprise integrations, legacy systems
|
||||
**Protocols:** SOAP over HTTP
|
||||
**Example:** Integration with enterprise ERP system
|
||||
|
||||
### Messaging Types
|
||||
|
||||
#### message-queue
|
||||
**Description:** Asynchronous messaging via message broker
|
||||
**When to use:** Event-driven architectures, async processing, decoupled systems
|
||||
**Protocols:** AMQP, Kafka Protocol, SQS API
|
||||
**Direction:** Outbound (publish) or Inbound (consume)
|
||||
**Example:** Order service publishes events to RabbitMQ for async processing
|
||||
|
||||
#### event-stream
|
||||
**Description:** Event streaming platforms
|
||||
**When to use:** Real-time data pipelines, event sourcing, log aggregation
|
||||
**Protocols:** Kafka, Amazon Kinesis, Azure Event Hubs
|
||||
**Example:** Analytics system consumes clickstream events from Kafka
|
||||
|
||||
### Data Access Types
|
||||
|
||||
#### database-connection
|
||||
**Description:** Direct database access at system level
|
||||
**When to use:** System-to-database communication, primary database
|
||||
**Protocols:** PostgreSQL, MySQL, MongoDB protocols
|
||||
**Direction:** Outbound (system queries database)
|
||||
**Example:** Application system connects to PostgreSQL database
|
||||
|
||||
#### database-query
|
||||
**Description:** Read-only database access
|
||||
**When to use:** Read replicas, reporting systems, analytics
|
||||
**Protocols:** SQL protocols (SELECT only)
|
||||
**Direction:** Outbound
|
||||
**Example:** Analytics dashboard queries PostgreSQL read replica
|
||||
|
||||
### Integration Types
|
||||
|
||||
#### authentication
|
||||
**Description:** Authentication and authorization flows
|
||||
**When to use:** Login flows, SSO, OAuth integrations
|
||||
**Protocols:** OAuth 2.0, SAML, OpenID Connect
|
||||
**Direction:** Outbound (system authenticates with provider)
|
||||
**Example:** Web application authenticates users via Auth0
|
||||
|
||||
#### external-api
|
||||
**Description:** Third-party API integration
|
||||
**When to use:** Payment gateways, SaaS services, external data providers
|
||||
**Protocols:** REST, SOAP, GraphQL, proprietary
|
||||
**Direction:** Outbound (your system calls external API)
|
||||
**Example:** E-commerce system processes payments via Stripe API
|
||||
|
||||
### Other Types
|
||||
|
||||
#### file-transfer
|
||||
**Description:** File transfer protocols
|
||||
**When to use:** File uploads, downloads, FTP, SFTP
|
||||
**Protocols:** FTP, SFTP, SCP, HTTP multipart
|
||||
**Example:** Backup system transfers files to remote storage via SFTP
|
||||
|
||||
#### smtp
|
||||
**Description:** Email protocol
|
||||
**When to use:** Email sending
|
||||
**Protocols:** SMTP
|
||||
**Example:** System sends transactional emails via SMTP
|
||||
|
||||
---
|
||||
|
||||
## C2 Container Relation Types
|
||||
|
||||
### API Communication Types
|
||||
|
||||
#### http-rest
|
||||
**Description:** RESTful HTTP API calls between containers
|
||||
**When to use:** Frontend to backend, service-to-service REST communication
|
||||
**Methods:** GET, POST, PUT, DELETE, PATCH
|
||||
**Typical containers:** SPA → API, API → Microservice
|
||||
**Example:** React SPA calls Express API endpoints
|
||||
|
||||
#### http-graphql
|
||||
**Description:** GraphQL queries between containers
|
||||
**When to use:** Frontend GraphQL queries, flexible data fetching
|
||||
**Methods:** Query, Mutation, Subscription
|
||||
**Typical containers:** Apollo Client → GraphQL Server
|
||||
**Example:** Next.js app queries GraphQL API
|
||||
|
||||
#### grpc
|
||||
**Description:** gRPC calls between containers
|
||||
**When to use:** High-performance inter-service communication
|
||||
**Typical containers:** Microservice → Microservice
|
||||
**Example:** Order service calls Inventory service via gRPC
|
||||
|
||||
#### websocket
|
||||
**Description:** Real-time bidirectional communication
|
||||
**When to use:** Live updates, real-time collaboration, push notifications
|
||||
**Typical containers:** Browser → WebSocket Server
|
||||
**Example:** Chat client maintains WebSocket connection to server
|
||||
|
||||
### Database Access Types
|
||||
|
||||
#### database-query
|
||||
**Description:** Read-only database operations
|
||||
**When to use:** SELECT queries, read replicas, reporting
|
||||
**Operations:** SELECT
|
||||
**Typical containers:** API → Read Replica, Analytics → Database
|
||||
**Example:** API container reads user data from PostgreSQL read replica
|
||||
|
||||
#### database-write
|
||||
**Description:** Write-only database operations
|
||||
**When to use:** INSERT, UPDATE, DELETE operations, write-specific workers
|
||||
**Operations:** INSERT, UPDATE, DELETE
|
||||
**Typical containers:** Worker → Database
|
||||
**Example:** Log aggregator writes logs to database
|
||||
|
||||
#### database-read-write
|
||||
**Description:** Full database access (read and write)
|
||||
**When to use:** Primary API servers, application logic containers
|
||||
**Operations:** SELECT, INSERT, UPDATE, DELETE
|
||||
**Typical containers:** API → Primary Database
|
||||
**Example:** Express API reads and writes to PostgreSQL primary
|
||||
|
||||
#### database-connection
|
||||
**Description:** Generic database connection (use specific types above when possible)
|
||||
**When to use:** When access pattern is unclear or mixed
|
||||
**Example:** General database connectivity
|
||||
|
||||
### Cache Access Types
|
||||
|
||||
#### cache-read
|
||||
**Description:** Read-only cache access
|
||||
**When to use:** Cache lookups, GET operations
|
||||
**Operations:** GET, EXISTS, TTL
|
||||
**Typical containers:** API → Cache
|
||||
**Example:** API reads session data from Redis
|
||||
|
||||
#### cache-write
|
||||
**Description:** Write-only cache operations
|
||||
**When to use:** Cache updates, background cache warmers
|
||||
**Operations:** SET, SETEX, DEL
|
||||
**Typical containers:** Worker → Cache
|
||||
**Example:** Cache warmer updates frequently accessed data in Redis
|
||||
|
||||
#### cache-read-write
|
||||
**Description:** Full cache access
|
||||
**When to use:** Typical caching patterns, read-through/write-through
|
||||
**Operations:** GET, SET, DEL, INCR, DECR
|
||||
**Typical containers:** API → Redis
|
||||
**Example:** API caches database query results in Redis
|
||||
|
||||
#### cache-access
|
||||
**Description:** Generic cache access (use specific types above when possible)
|
||||
**When to use:** When access pattern is unclear
|
||||
**Example:** General cache connectivity
|
||||
|
||||
### Message Queue Types
|
||||
|
||||
#### message-publish
|
||||
**Description:** Publishes messages to queue or topic
|
||||
**When to use:** Event producers, async job creators
|
||||
**Patterns:** Pub-sub, work queue
|
||||
**Typical containers:** API → Queue, Service → Event Bus
|
||||
**Example:** Order API publishes order-created events to RabbitMQ
|
||||
|
||||
#### message-subscribe / message-consumer
|
||||
**Description:** Consumes messages from queue or topic
|
||||
**When to use:** Event consumers, background workers
|
||||
**Patterns:** Pub-sub, work queue
|
||||
**Typical containers:** Worker → Queue
|
||||
**Example:** Email worker consumes notification jobs from SQS
|
||||
**Note:** `message-consumer` is an alias for `message-subscribe`
|
||||
|
||||
### Storage Types
|
||||
|
||||
#### file-read
|
||||
**Description:** Reads files from storage system
|
||||
**When to use:** File processing, data import, asset loading
|
||||
**Typical containers:** Worker → S3, API → File Storage
|
||||
**Example:** Image processor reads uploaded files from S3
|
||||
|
||||
#### file-write
|
||||
**Description:** Writes files to storage system
|
||||
**When to use:** File uploads, data export, log writing
|
||||
**Typical containers:** API → S3, Worker → File Storage
|
||||
**Example:** API uploads user profile images to S3
|
||||
|
||||
#### cdn-fetch
|
||||
**Description:** Fetches static assets from CDN
|
||||
**When to use:** Asset delivery, static resource loading
|
||||
**Typical containers:** Browser → CDN
|
||||
**Example:** Web app fetches CSS/JS/images from CloudFront
|
||||
|
||||
### Other Types
|
||||
|
||||
#### stream
|
||||
**Description:** Streaming data transfer
|
||||
**When to use:** Video/audio streaming, large file transfers
|
||||
**Example:** Video player streams content from media server
|
||||
|
||||
---
|
||||
|
||||
## C3 Component Relation Types
|
||||
|
||||
### Dependency Types
|
||||
|
||||
#### dependency
|
||||
**Description:** General dependency relationship
|
||||
**When to use:** Component depends on another for functionality
|
||||
**Coupling:** Varies (document as loose or tight)
|
||||
**Typical usage:** Any component dependency
|
||||
**Example:** Controller depends on Service for business logic
|
||||
|
||||
#### uses
|
||||
**Description:** Uses another component's functionality
|
||||
**When to use:** Component actively uses another's methods or features
|
||||
**Coupling:** Loose to moderate
|
||||
**Typical usage:** Service uses Repository, Controller uses Service
|
||||
**Example:** UserController uses UserService for user operations
|
||||
|
||||
#### calls
|
||||
**Description:** Directly invokes methods on another component
|
||||
**When to use:** Direct method calls, function invocation
|
||||
**Coupling:** Tight
|
||||
**Typical usage:** Any direct method invocation
|
||||
**Example:** Service calls specific repository methods
|
||||
|
||||
### Object-Oriented Types
|
||||
|
||||
#### inherits / extends
|
||||
**Description:** Class inheritance (is-a relationship)
|
||||
**When to use:** OOP inheritance hierarchies
|
||||
**Coupling:** Tight
|
||||
**Typical usage:** Class extends base class
|
||||
**Example:** UserController extends BaseController
|
||||
**Note:** Both `inherits` and `extends` are valid
|
||||
|
||||
#### implements / interface-implementation
|
||||
**Description:** Implements an interface or contract
|
||||
**When to use:** Interface implementation, polymorphism
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** Class implements interface
|
||||
**Example:** UserRepository implements IUserRepository
|
||||
**Note:** Both `implements` and `interface-implementation` are valid
|
||||
|
||||
#### composes
|
||||
**Description:** Composition relationship (has-a, strong)
|
||||
**When to use:** Component contains another as integral part
|
||||
**Coupling:** Tight
|
||||
**Typical usage:** Object composition
|
||||
**Example:** Order composes OrderItem instances
|
||||
|
||||
#### aggregates
|
||||
**Description:** Aggregation relationship (has-a, weak)
|
||||
**When to use:** Component references another but doesn't own it
|
||||
**Coupling:** Moderate
|
||||
**Typical usage:** Object aggregation
|
||||
**Example:** ShoppingCart aggregates Product references
|
||||
|
||||
### Dependency Injection Types
|
||||
|
||||
#### injects
|
||||
**Description:** Dependency injection
|
||||
**When to use:** DI frameworks, constructor/setter injection
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** Service receives dependencies via DI container
|
||||
**Example:** UserService receives UserRepository via constructor injection
|
||||
|
||||
#### provides
|
||||
**Description:** Provides data or functionality to consumers
|
||||
**When to use:** Provider pattern, dependency providers
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** DI providers, context providers
|
||||
**Example:** AuthProvider provides authenticated user context
|
||||
|
||||
#### consumes
|
||||
**Description:** Consumes data or functionality from provider
|
||||
**When to use:** Consumer pattern, dependency consumers
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** Component consumes from provider
|
||||
**Example:** UserProfile consumes auth context from AuthProvider
|
||||
|
||||
### Event-Driven Types
|
||||
|
||||
#### observes / event-subscriber
|
||||
**Description:** Observer pattern - listens to events
|
||||
**When to use:** Event listeners, subscribers, reactive patterns
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** Event-driven architectures
|
||||
**Example:** Logger observes error events from ErrorHandler
|
||||
**Note:** Both `observes` and `event-subscriber` are valid
|
||||
|
||||
#### notifies / event-publisher
|
||||
**Description:** Publishes events or notifications
|
||||
**When to use:** Event emitters, publishers, observable patterns
|
||||
**Coupling:** Loose
|
||||
**Typical usage:** Event-driven architectures
|
||||
**Example:** OrderService notifies subscribers when order is placed
|
||||
**Note:** Both `notifies` and `event-publisher` are valid
|
||||
|
||||
### Other Types
|
||||
|
||||
#### imports
|
||||
**Description:** Direct ES6/CommonJS module import
|
||||
**When to use:** JavaScript/TypeScript module imports
|
||||
**Coupling:** Tight
|
||||
**Typical usage:** Any module import
|
||||
**Example:** Component imports utility functions
|
||||
|
||||
#### delegates
|
||||
**Description:** Delegates operations to another component
|
||||
**When to use:** Delegation pattern, facades
|
||||
**Coupling:** Moderate
|
||||
**Typical usage:** Facade pattern, delegation
|
||||
**Example:** UserFacade delegates operations to multiple subsystems
|
||||
|
||||
---
|
||||
|
||||
## Type Selection Guidelines
|
||||
|
||||
### Choosing Between Similar Types
|
||||
|
||||
#### http vs http-rest vs http-graphql
|
||||
- Use **`http-rest`** for RESTful APIs (preferred)
|
||||
- Use **`http-graphql`** for GraphQL APIs (preferred)
|
||||
- Use **`http`** only when protocol is unclear (avoid if possible)
|
||||
|
||||
#### database-connection vs database-query vs database-read-write
|
||||
- Use **`database-query`** for read-only access (SELECT)
|
||||
- Use **`database-write`** for write-only access (INSERT/UPDATE/DELETE)
|
||||
- Use **`database-read-write`** for full access (most common)
|
||||
- Use **`database-connection`** only as fallback
|
||||
|
||||
#### cache-access vs cache-read vs cache-write
|
||||
- Use **`cache-read`** for read-only (GET operations)
|
||||
- Use **`cache-write`** for write-only (SET operations)
|
||||
- Use **`cache-read-write`** for both (most common)
|
||||
- Use **`cache-access`** only as fallback
|
||||
|
||||
#### message-subscribe vs message-consumer
|
||||
- Both are valid (aliases)
|
||||
- Use **`message-subscribe`** for clarity (preferred)
|
||||
- Use **`message-consumer`** if it reads better in your context
|
||||
|
||||
#### implements vs interface-implementation
|
||||
- Both are valid
|
||||
- Use **`implements`** for brevity (preferred)
|
||||
- Use **`interface-implementation`** if you need to be explicit
|
||||
|
||||
#### observes vs event-subscriber
|
||||
- Both are valid
|
||||
- Use **`observes`** for brevity (preferred)
|
||||
- Use **`event-subscriber`** if you need to be explicit
|
||||
|
||||
#### notifies vs event-publisher
|
||||
- Both are valid
|
||||
- Use **`notifies`** for brevity (preferred)
|
||||
- Use **`event-publisher`** if you need to be explicit
|
||||
|
||||
### Level-Specific Guidelines
|
||||
|
||||
#### C1 System Context
|
||||
**Focus:** Communication protocols between systems
|
||||
**Prefer:** Specific types (`http-rest` over `http`)
|
||||
**Always include:** `direction` and `protocol` fields
|
||||
|
||||
#### C2 Container
|
||||
**Focus:** Container-to-container interactions
|
||||
**Prefer:** Access-specific types (`database-read-write` over `database-connection`)
|
||||
**Always include:** `protocol` and `isAsync` fields
|
||||
|
||||
#### C3 Component
|
||||
**Focus:** Code-level dependencies and patterns
|
||||
**Prefer:** Pattern-specific types (`injects` over `dependency`)
|
||||
**Always include:** `coupling` field
|
||||
|
||||
---
|
||||
|
||||
## Examples by Level
|
||||
|
||||
### C1 Examples
|
||||
```json
|
||||
{ "type": "http-rest", "description": "Fetches data via REST API" }
|
||||
{ "type": "grpc", "description": "High-performance RPC calls" }
|
||||
{ "type": "message-queue", "description": "Publishes events to AMQP queue" }
|
||||
{ "type": "authentication", "description": "Authenticates via OAuth 2.0" }
|
||||
```
|
||||
|
||||
### C2 Examples
|
||||
```json
|
||||
{ "type": "http-rest", "description": "REST API calls from SPA to backend" }
|
||||
{ "type": "database-read-write", "description": "Full database access via ORM" }
|
||||
{ "type": "cache-read-write", "description": "Caches query results in Redis" }
|
||||
{ "type": "message-publish", "description": "Publishes order events to queue" }
|
||||
```
|
||||
|
||||
### C3 Examples
|
||||
```json
|
||||
{ "type": "uses", "description": "Uses service for business logic" }
|
||||
{ "type": "injects", "description": "Injects repository via DI" }
|
||||
{ "type": "implements", "description": "Implements repository interface" }
|
||||
{ "type": "observes", "description": "Listens to order completion events" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Rules
|
||||
|
||||
### All Levels
|
||||
- Type must be from the appropriate level enum
|
||||
- Description must be in active voice
|
||||
- ID must match pattern: `^rel-[a-z0-9-]+$`
|
||||
|
||||
### C1 Specific
|
||||
- Must include `direction` field
|
||||
- Should include `protocol` for network communication
|
||||
|
||||
### C2 Specific
|
||||
- Should include `protocol` for network communication
|
||||
- Should include `isAsync` for messaging/async operations
|
||||
|
||||
### C3 Specific
|
||||
- Must include `coupling` field
|
||||
- Focus on code-level patterns
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **Detailed Reference:** [reference.md](./reference.md)
|
||||
- **Examples:** [examples.md](./examples.md)
|
||||
- **Main Skill:** [SKILL.md](./SKILL.md)
|
||||
- **Type Schema:** `${CLAUDE_PLUGIN_ROOT}/validation/templates/types-relations.json`
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-11-17
|
||||
Reference in New Issue
Block a user