design-principles.md 11 KB

Technical Design Rules and Principles

Core Design Principles

1. Type Safety is Mandatory

  • NEVER use any type in TypeScript interfaces
  • Define explicit types for all parameters and returns
  • Use discriminated unions for error handling
  • Specify generic constraints clearly

2. Design vs Implementation

  • Focus on WHAT, not HOW
  • Define interfaces and contracts, not code
  • Specify behavior through pre/post conditions
  • Document architectural decisions, not algorithms

3. Visual Communication

  • Simple features: Basic component diagram or none
  • Medium complexity: Architecture + data flow
  • High complexity: Multiple diagrams (architecture, sequence, state)
  • Always pure Mermaid: No styling, just structure

4. Component Design Rules

  • Single Responsibility: One clear purpose per component
  • Clear Boundaries: Explicit domain ownership
  • Dependency Direction: Follow architectural layers
  • Interface Segregation: Minimal, focused interfaces
  • Team-safe Interfaces: Design boundaries that allow parallel implementation without merge conflicts
  • Research Traceability: Record boundary decisions and rationale in research.md

5. Data Modeling Standards

  • Domain First: Start with business concepts
  • Consistency Boundaries: Clear aggregate roots
  • Normalization: Balance between performance and integrity
  • Evolution: Plan for schema changes

6. Error Handling Philosophy

  • Fail Fast: Validate early and clearly
  • Graceful Degradation: Partial functionality over complete failure
  • User Context: Actionable error messages
  • Observability: Comprehensive logging and monitoring

7. Integration Patterns

  • Loose Coupling: Minimize dependencies
  • Contract First: Define interfaces before implementation
  • Versioning: Plan for API evolution
  • Idempotency: Design for retry safety
  • Contract Visibility: Surface API and event contracts in design.md while linking extended details from research.md

Documentation Standards

Language and Tone

  • Declarative: "The system authenticates users" not "The system should authenticate"
  • Precise: Specific technical terms over vague descriptions
  • Concise: Essential information only
  • Formal: Professional technical writing

Structure Requirements

  • Hierarchical: Clear section organization
  • Traceable: Requirements to components mapping
  • Complete: All aspects covered for implementation
  • Consistent: Uniform terminology throughout
  • Focused: Keep design.md centered on architecture and contracts; move investigation logs and lengthy comparisons to research.md

Section Authoring Guidance

Global Ordering

  • Default flow: Overview → Goals/Non-Goals → Requirements Traceability → Architecture → Technology Stack → System Flows → Components & Interfaces → Data Models → Optional sections.
  • Teams may swap Traceability earlier or place Data Models nearer Architecture when it improves clarity, but keep section headings intact.
  • Within each section, follow Summary → Scope → Decisions → Impacts/Risks so reviewers can scan consistently.

Requirement IDs

  • Reference requirements as 2.1, 2.3 without prefixes (no “Requirement 2.1”).
  • All requirements MUST have numeric IDs. If a requirement lacks a numeric ID, stop and fix requirements.md before continuing.
  • Use N.M-style numeric IDs where N is the top-level requirement number from requirements.md (for example, Requirement 1 → 1.1, 1.2; Requirement 2 → 2.1, 2.2).
  • Every component, task, and traceability row must reference the same canonical numeric ID.

Technology Stack

  • Include ONLY layers impacted by this feature (frontend, backend, data, messaging, infra).
  • For each layer specify tool/library + version + the role it plays; push extended rationale, comparisons, or benchmarks to research.md.
  • When extending an existing system, highlight deviations from the current stack and list new dependencies.

System Flows

  • Add diagrams only when they clarify behavior:
    • Sequence for multi-step interactions
    • Process/State for branching rules or lifecycle
    • Data/Event for pipelines or async patterns
  • Always use pure Mermaid. If no complex flow exists, omit the entire section.

Requirements Traceability

  • Use the standard table (Requirement | Summary | Components | Interfaces | Flows) to prove coverage.
  • Collapse to bullet form only when a single requirement maps 1:1 to a component.
  • Prefer the component summary table for simple mappings; reserve the full traceability table for complex or compliance-sensitive requirements.
  • Re-run this mapping whenever requirements or components change to avoid drift.

Components & Interfaces Authoring

  • Group components by domain/layer and provide one block per component.
  • Begin with a summary table listing Component, Domain, Intent, Requirement coverage, key dependencies, and selected contracts.
  • Table fields: Intent (one line), Requirements (2.1, 2.3), Owner/Reviewers (optional).
  • Dependencies table must mark each entry as Inbound/Outbound/External and assign Criticality (P0 blocking, P1 high-risk, P2 informational).
  • Summaries of external dependency research stay here; detailed investigation (API signatures, rate limits, migration notes) belongs in research.md.
  • design.md must remain a self-contained reviewer artifact. Reference research.md only for background, and restate any conclusions or decisions here.
  • Contracts: tick only the relevant types (Service/API/Event/Batch/State). Unchecked types should not appear later in the component section.
  • Service interfaces must declare method signatures, inputs/outputs, and error envelopes. API/Event/Batch contracts require schema tables or bullet lists covering trigger, payload, delivery, idempotency.
  • Use Integration & Migration Notes, Validation Hooks, and Open Questions / Risks to document rollout strategy, observability, and unresolved decisions.
  • Detail density rules:
    • Full block: components introducing new boundaries (logic hooks, shared services, external integrations, data layers).
    • Summary-only: presentational/UI components with no new boundaries (plus a short Implementation Note if needed).
  • Implementation Notes must combine Integration / Validation / Risks into a single bulleted subsection to reduce repetition.
  • Prefer lists or inline descriptors for short data (dependencies, contract selections). Use tables only when comparing multiple items.

Shared Interfaces & Props

  • Define a base interface (e.g., BaseUIPanelProps) for recurring UI components and extend it per component to capture only the deltas.
  • Hooks, utilities, and integration adapters that introduce new contracts should still include full TypeScript signatures.
  • When reusing a base contract, reference it explicitly (e.g., “Extends BaseUIPanelProps with onSubmitAnswer callback”) instead of duplicating the code block.

Data Models

  • Domain Model covers aggregates, entities, value objects, domain events, and invariants. Add Mermaid diagrams only when relationships are non-trivial.
  • Logical Data Model should articulate structure, indexing, sharding, and storage-specific considerations (event store, KV/wide-column) relevant to the change.
  • Data Contracts & Integration section documents API payloads, event schemas, and cross-service synchronization patterns when the feature crosses boundaries.
  • Lengthy type definitions or vendor-specific option objects should be placed in the Supporting References section within design.md, linked from the relevant section. Investigation notes stay in research.md.
  • Supporting References usage is optional; only create it when keeping the content in the main body would reduce readability. All decisions must still appear in the main sections so design.md stands alone.

Error/Testing/Security/Performance Sections

  • Record only feature-specific decisions or deviations. Link or reference organization-wide standards (steering) for baseline practices instead of restating them.

Diagram & Text Deduplication

  • Do not restate diagram content verbatim in prose. Use the text to highlight key decisions, trade-offs, or impacts that are not obvious from the visual.
  • When a decision is fully captured in the diagram annotations, a short “Key Decisions” bullet is sufficient.

General Deduplication

  • Avoid repeating the same information across Overview, Architecture, and Components. Reference earlier sections when context is identical.
  • If a requirement/component relationship is captured in the summary table, do not rewrite it elsewhere unless extra nuance is added.

Diagram Guidelines

When to include a diagram

  • Architecture: Use a structural diagram when 3+ components or external systems interact.
  • Sequence: Draw a sequence diagram when calls/handshakes span multiple steps.
  • State / Flow: Capture complex state machines or business flows in a dedicated diagram.
  • ER: Provide an entity-relationship diagram for non-trivial data models.
  • Skip: Minor one-component changes generally do not need diagrams.

Mermaid requirements

graph TB
    Client --> ApiGateway
    ApiGateway --> ServiceA
    ApiGateway --> ServiceB
    ServiceA --> Database
  • Plain Mermaid only – avoid custom styling or unsupported syntax.
  • Node IDs – alphanumeric plus underscores only (e.g., Client, ServiceA). Do not use @, /, or leading -.
  • Labels – simple words. Do not embed parentheses (), square brackets [], quotes ", or slashes /.
    • DnD[@dnd-kit/core] → invalid ID (@).
    • UI[KanbanBoard(React)] → invalid label (()).
    • DndKit[dnd-kit core] → use plain text in labels, keep technology details in the accompanying description.
    • ℹ️ Mermaid strict-mode will otherwise fail with errors like Expecting 'SQE' ... got 'PS'; remove punctuation from labels before rendering.
  • Edges – show data or control flow direction.
  • Groups – using Mermaid subgraphs to cluster related components is allowed; use it sparingly for clarity.

Quality Metrics

Design Completeness Checklist

  • All requirements addressed
  • No implementation details leaked
  • Clear component boundaries
  • Explicit error handling
  • Comprehensive test strategy
  • Security considered
  • Performance targets defined
  • Migration path clear (if applicable)

Common Anti-patterns to Avoid

❌ Mixing design with implementation ❌ Vague interface definitions ❌ Missing error scenarios ❌ Ignored non-functional requirements ❌ Overcomplicated architectures ❌ Tight coupling between components ❌ Missing data consistency strategy ❌ Incomplete dependency analysis