Initial commit
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user