464 lines
14 KiB
YAML
464 lines
14 KiB
YAML
# Design Document Schema
|
|
# The source of truth for system design - all tasks derive from this
|
|
# Created during DESIGNING phase, approved before IMPLEMENTING
|
|
|
|
# ============================================================================
|
|
# DOCUMENT METADATA
|
|
# ============================================================================
|
|
design_document:
|
|
# Links to workflow
|
|
workflow_version: string # e.g., v001
|
|
feature: string # Feature being implemented
|
|
|
|
# Timestamps
|
|
created_at: timestamp
|
|
updated_at: timestamp
|
|
approved_at: timestamp | null
|
|
|
|
# Design status
|
|
status: draft | review | approved | rejected
|
|
|
|
# Revision tracking
|
|
revision: integer # Increments on changes
|
|
revision_notes: string # What changed in this revision
|
|
|
|
# ============================================================================
|
|
# LAYER 1: DATA MODELS (ER Diagram)
|
|
# ============================================================================
|
|
data_models:
|
|
description: "Database entities and their relationships"
|
|
|
|
model_schema:
|
|
# Identity
|
|
id: string # model_<name> (e.g., model_user, model_post)
|
|
name: string # PascalCase entity name (e.g., User, Post)
|
|
description: string # What this model represents
|
|
|
|
# Table/Collection info
|
|
table_name: string # snake_case (e.g., users, posts)
|
|
|
|
# Fields
|
|
fields:
|
|
- name: string # snake_case field name
|
|
type: enum # string | integer | boolean | datetime | uuid | json | text | float | decimal | enum
|
|
constraints: [enum] # primary_key | foreign_key | unique | not_null | indexed | auto_increment | default
|
|
default: any # Default value if constraint includes 'default'
|
|
enum_values: [string] # If type is 'enum', list valid values
|
|
description: string # Field purpose
|
|
|
|
# Relations to other models
|
|
relations:
|
|
- type: enum # has_one | has_many | belongs_to | many_to_many
|
|
target: string # Target model_id (e.g., model_post)
|
|
foreign_key: string # FK field name
|
|
through: string # Junction table for many_to_many
|
|
on_delete: enum # cascade | set_null | restrict | no_action
|
|
|
|
# Indexes
|
|
indexes:
|
|
- fields: [string] # Fields in index
|
|
unique: boolean # Is unique index
|
|
name: string # Index name
|
|
|
|
# Timestamps (common pattern)
|
|
timestamps: boolean # Auto-add created_at, updated_at
|
|
soft_delete: boolean # Add deleted_at for soft deletes
|
|
|
|
# Validation rules (business logic)
|
|
validations:
|
|
- field: string # Field to validate
|
|
rule: string # Validation rule (e.g., "email", "min:8", "max:100")
|
|
message: string # Error message
|
|
|
|
# Example
|
|
example_model:
|
|
id: model_user
|
|
name: User
|
|
description: "Application user account"
|
|
table_name: users
|
|
fields:
|
|
- name: id
|
|
type: uuid
|
|
constraints: [primary_key]
|
|
description: "Unique identifier"
|
|
- name: email
|
|
type: string
|
|
constraints: [unique, not_null, indexed]
|
|
description: "User email address"
|
|
- name: name
|
|
type: string
|
|
constraints: [not_null]
|
|
description: "Display name"
|
|
- name: password_hash
|
|
type: string
|
|
constraints: [not_null]
|
|
description: "Bcrypt hashed password"
|
|
- name: role
|
|
type: enum
|
|
enum_values: [user, admin, moderator]
|
|
constraints: [not_null, default]
|
|
default: user
|
|
description: "User role for authorization"
|
|
relations:
|
|
- type: has_many
|
|
target: model_post
|
|
foreign_key: user_id
|
|
on_delete: cascade
|
|
timestamps: true
|
|
soft_delete: false
|
|
validations:
|
|
- field: email
|
|
rule: email
|
|
message: "Invalid email format"
|
|
- field: password_hash
|
|
rule: min:60
|
|
message: "Invalid password hash"
|
|
|
|
# ============================================================================
|
|
# LAYER 2: API ENDPOINTS
|
|
# ============================================================================
|
|
api_endpoints:
|
|
description: "REST API endpoints with request/response contracts"
|
|
|
|
endpoint_schema:
|
|
# Identity
|
|
id: string # api_<verb>_<resource> (e.g., api_create_user)
|
|
|
|
# HTTP
|
|
method: enum # GET | POST | PUT | PATCH | DELETE
|
|
path: string # URL path (e.g., /api/users/:id)
|
|
|
|
# Description
|
|
summary: string # Short description
|
|
description: string # Detailed description
|
|
|
|
# Tags for grouping
|
|
tags: [string] # e.g., [users, authentication]
|
|
|
|
# Path parameters
|
|
path_params:
|
|
- name: string # Parameter name (e.g., id)
|
|
type: string # Data type
|
|
description: string
|
|
|
|
# Query parameters (for GET)
|
|
query_params:
|
|
- name: string # Parameter name
|
|
type: string # Data type
|
|
required: boolean
|
|
default: any
|
|
description: string
|
|
|
|
# Request body (for POST/PUT/PATCH)
|
|
request_body:
|
|
content_type: string # application/json
|
|
schema:
|
|
type: object | array
|
|
properties:
|
|
- name: string
|
|
type: string
|
|
required: boolean
|
|
validations: [string] # Validation rules
|
|
description: string
|
|
example: object # Example request body
|
|
|
|
# Response schemas by status code
|
|
responses:
|
|
- status: integer # HTTP status code
|
|
description: string
|
|
schema:
|
|
type: object | array
|
|
properties:
|
|
- name: string
|
|
type: string
|
|
example: object
|
|
|
|
# Dependencies
|
|
depends_on_models: [string] # model_ids this endpoint uses
|
|
depends_on_apis: [string] # api_ids this endpoint calls (internal)
|
|
|
|
# Authentication/Authorization
|
|
auth:
|
|
required: boolean
|
|
roles: [string] # Required roles (empty = any authenticated)
|
|
|
|
# Rate limiting
|
|
rate_limit:
|
|
requests: integer # Max requests
|
|
window: string # Time window (e.g., "1m", "1h")
|
|
|
|
# Example
|
|
example_endpoint:
|
|
id: api_create_user
|
|
method: POST
|
|
path: /api/users
|
|
summary: "Create a new user"
|
|
description: "Register a new user account with email and password"
|
|
tags: [users, authentication]
|
|
request_body:
|
|
content_type: application/json
|
|
schema:
|
|
type: object
|
|
properties:
|
|
- name: email
|
|
type: string
|
|
required: true
|
|
validations: [email]
|
|
description: "User email address"
|
|
- name: name
|
|
type: string
|
|
required: true
|
|
validations: [min:1, max:100]
|
|
description: "Display name"
|
|
- name: password
|
|
type: string
|
|
required: true
|
|
validations: [min:8]
|
|
description: "Password (will be hashed)"
|
|
example:
|
|
email: "user@example.com"
|
|
name: "John Doe"
|
|
password: "securepass123"
|
|
responses:
|
|
- status: 201
|
|
description: "User created successfully"
|
|
schema:
|
|
type: object
|
|
properties:
|
|
- name: id
|
|
type: uuid
|
|
- name: email
|
|
type: string
|
|
- name: name
|
|
type: string
|
|
- name: created_at
|
|
type: datetime
|
|
example:
|
|
id: "550e8400-e29b-41d4-a716-446655440000"
|
|
email: "user@example.com"
|
|
name: "John Doe"
|
|
created_at: "2025-01-16T10:00:00Z"
|
|
- status: 400
|
|
description: "Validation error"
|
|
schema:
|
|
type: object
|
|
properties:
|
|
- name: error
|
|
type: string
|
|
- name: details
|
|
type: array
|
|
example:
|
|
error: "Validation failed"
|
|
details: ["Email is invalid", "Password too short"]
|
|
- status: 409
|
|
description: "Email already exists"
|
|
schema:
|
|
type: object
|
|
properties:
|
|
- name: error
|
|
type: string
|
|
example:
|
|
error: "Email already registered"
|
|
depends_on_models: [model_user]
|
|
depends_on_apis: []
|
|
auth:
|
|
required: false
|
|
roles: []
|
|
|
|
# ============================================================================
|
|
# LAYER 3: UI PAGES
|
|
# ============================================================================
|
|
pages:
|
|
description: "Application pages/routes"
|
|
|
|
page_schema:
|
|
# Identity
|
|
id: string # page_<name> (e.g., page_users, page_user_detail)
|
|
name: string # Human-readable name
|
|
|
|
# Routing
|
|
path: string # URL path (e.g., /users, /users/[id])
|
|
layout: string # Layout component to use
|
|
|
|
# Data requirements
|
|
data_needs:
|
|
- api_id: string # API endpoint to call
|
|
purpose: string # Why this data is needed
|
|
on_load: boolean # Fetch on page load
|
|
|
|
# Components used
|
|
components: [string] # component_ids used on this page
|
|
|
|
# SEO
|
|
seo:
|
|
title: string
|
|
description: string
|
|
|
|
# Auth requirements
|
|
auth:
|
|
required: boolean
|
|
roles: [string]
|
|
redirect: string # Where to redirect if not authorized
|
|
|
|
# State management
|
|
state:
|
|
local: [string] # Local state variables
|
|
global: [string] # Global state dependencies
|
|
|
|
# Example
|
|
example_page:
|
|
id: page_users
|
|
name: "Users List"
|
|
path: /users
|
|
layout: layout_dashboard
|
|
data_needs:
|
|
- api_id: api_list_users
|
|
purpose: "Display user list"
|
|
on_load: true
|
|
components: [component_user_list, component_user_card, component_pagination]
|
|
seo:
|
|
title: "Users"
|
|
description: "View all users"
|
|
auth:
|
|
required: true
|
|
roles: [admin]
|
|
redirect: /login
|
|
|
|
# ============================================================================
|
|
# LAYER 3: UI COMPONENTS
|
|
# ============================================================================
|
|
components:
|
|
description: "Reusable UI components"
|
|
|
|
component_schema:
|
|
# Identity
|
|
id: string # component_<name> (e.g., component_user_card)
|
|
name: string # PascalCase component name
|
|
|
|
# Props (input)
|
|
props:
|
|
- name: string # Prop name
|
|
type: string # TypeScript type
|
|
required: boolean
|
|
default: any
|
|
description: string
|
|
|
|
# Events (output)
|
|
events:
|
|
- name: string # Event name (e.g., onClick, onSubmit)
|
|
payload: string # Payload type
|
|
description: string
|
|
|
|
# API calls (if component fetches data)
|
|
uses_apis: [string] # api_ids this component calls directly
|
|
|
|
# Child components
|
|
uses_components: [string] # component_ids used inside this component
|
|
|
|
# State
|
|
internal_state: [string] # Internal state variables
|
|
|
|
# Styling
|
|
variants: [string] # Style variants (e.g., primary, secondary)
|
|
|
|
# Example
|
|
example_component:
|
|
id: component_user_card
|
|
name: UserCard
|
|
props:
|
|
- name: user
|
|
type: User
|
|
required: true
|
|
description: "User object to display"
|
|
- name: showActions
|
|
type: boolean
|
|
required: false
|
|
default: true
|
|
description: "Show edit/delete buttons"
|
|
events:
|
|
- name: onEdit
|
|
payload: "User"
|
|
description: "Fired when edit button clicked"
|
|
- name: onDelete
|
|
payload: "string"
|
|
description: "Fired when delete confirmed, payload is user ID"
|
|
uses_apis: []
|
|
uses_components: [component_avatar, component_button]
|
|
internal_state: [isDeleting]
|
|
variants: [default, compact]
|
|
|
|
# ============================================================================
|
|
# DEPENDENCY GRAPH (Auto-generated from above)
|
|
# ============================================================================
|
|
dependency_graph:
|
|
description: "Execution order based on dependencies - auto-generated"
|
|
|
|
# Layers for parallel execution
|
|
layers:
|
|
- layer: 1
|
|
name: "Data Models"
|
|
description: "Database schema - no dependencies"
|
|
items:
|
|
- id: string # Entity ID
|
|
type: model # model | api | page | component
|
|
dependencies: [] # Empty for layer 1
|
|
|
|
- layer: 2
|
|
name: "API Endpoints"
|
|
description: "Backend APIs - depend on models"
|
|
items:
|
|
- id: string
|
|
type: api
|
|
dependencies: [string] # model_ids
|
|
|
|
- layer: 3
|
|
name: "UI Layer"
|
|
description: "Pages and components - depend on APIs"
|
|
items:
|
|
- id: string
|
|
type: page | component
|
|
dependencies: [string] # api_ids, component_ids
|
|
|
|
# Full dependency map for visualization
|
|
dependency_map:
|
|
model_user:
|
|
depends_on: []
|
|
depended_by: [api_create_user, api_list_users, api_get_user]
|
|
api_create_user:
|
|
depends_on: [model_user]
|
|
depended_by: [page_user_create, component_user_form]
|
|
page_users:
|
|
depends_on: [api_list_users, component_user_list]
|
|
depended_by: []
|
|
|
|
# ============================================================================
|
|
# DESIGN VALIDATION RULES
|
|
# ============================================================================
|
|
validation_rules:
|
|
models:
|
|
- "Every model must have a primary_key field"
|
|
- "Foreign keys must reference existing models"
|
|
- "Relation targets must exist in data_models"
|
|
- "Enum types must have enum_values defined"
|
|
|
|
apis:
|
|
- "Every API must have at least one response defined"
|
|
- "POST/PUT/PATCH must have request_body"
|
|
- "depends_on_models must reference existing models"
|
|
- "Path params must match :param patterns in path"
|
|
|
|
pages:
|
|
- "data_needs must reference existing api_ids"
|
|
- "components must reference existing component_ids"
|
|
- "auth.redirect must be a valid path"
|
|
|
|
components:
|
|
- "uses_apis must reference existing api_ids"
|
|
- "uses_components must reference existing component_ids"
|
|
- "No circular component dependencies"
|
|
|
|
graph:
|
|
- "No circular dependencies in dependency_graph"
|
|
- "All entities must be assigned to a layer"
|
|
- "Layer N items can only depend on Layer < N items"
|