writing-technical-design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Writing Technical Design Documents

编写技术设计文档

Create technical design documents that map architecture decisions to the right context management layers. Agents load design information only when making implementation choices.
Use this skill when designing how to build a feature, documenting architecture decisions, defining component interfaces, or specifying data models.
Supporting files: CONTEXT-LAYERS.md for layer mapping details, EXAMPLES.md for complete examples.
创建可将架构决策映射到对应上下文管理层的技术设计文档。Agent仅在做实现选择时才加载设计信息。
适用场景:设计功能实现方式、记录架构决策、定义组件接口或指定数据模型时。
支持文件CONTEXT-LAYERS.md 包含层映射详情,EXAMPLES.md 包含完整示例。

Context Layer Distribution

上下文层分布

Technical design information spans multiple context layers:
Layer   What goes here              File location
======================================================================
L1      Tech stack + feature ref    CLAUDE.md / AGENTS.md (constitution)
        "Go 1.23, Echo v4, PostgreSQL 16, sqlc"
        "specs/design-notifications.md - Notification architecture"

L2      Component-local patterns    .claude/rules/ or .github/instructions/
        "Handlers in this dir use async sender interface"
        "Repository pattern: no business logic in DB layer"

L3      Design body (this doc)      specs/design-{feature}.md
        Decision summary, component overview, interfaces

L4      Deep reference              specs/design-{feature}.md (lower sections)
        Alternatives considered, migration plan, ADR rationale
======================================================================
技术设计信息涵盖多个上下文层:
层级   内容范围                     文件位置
======================================================================
L1      技术栈 + 功能参考           CLAUDE.md / AGENTS.md (constitution)
        "Go 1.23, Echo v4, PostgreSQL 16, sqlc"
        "specs/design-notifications.md - 通知架构"

L2      组件本地模式                .claude/rules/ 或 .github/instructions/
        "此目录下的处理器使用异步发送器接口"
        "仓库模式:数据库层不包含业务逻辑"

L3      设计主体(本文档)          specs/design-{feature}.md
        决策摘要、组件概览、接口定义

L4      深度参考内容                specs/design-{feature}.md(下方章节)
        备选方案考量、迁移计划、ADR依据
======================================================================

Template:
specs/design-{feature-name}.md

模板:
specs/design-{feature-name}.md

markdown
---
title: "Feature Name - Technical Design"
status: draft | review | approved | implementing | done
prd: skills/prd-feature-name/SKILL.md
last-updated: YYYY-MM-DD
---
markdown
---
title: "功能名称 - 技术设计"
status: draft | review | approved | implementing | done
prd: skills/prd-feature-name/SKILL.md
last-updated: YYYY-MM-DD
---

Feature Name - Technical Design

功能名称 - 技术设计

TL;DR

概述

[2-3 sentences: Architecture approach and key trade-off. Agent reads this to understand implementation direction.]
[2-3句话:架构方案和核心权衡点。 Agent会阅读此部分以理解实现方向。]

Decision Summary

决策摘要

DecisionChoiceRationale
[Area][Technology/Pattern][Why, in one phrase]
[Area][Technology/Pattern][Why, in one phrase]
[Area][Technology/Pattern][Why, in one phrase]
决策领域选型依据
[领域][技术/模式][一句话说明原因]
[领域][技术/模式][一句话说明原因]
[领域][技术/模式][一句话说明原因]

Component Overview

组件概览

text
[ASCII diagram: components and data flow]

┌──────────┐     ┌──────────┐     ┌──────────┐
│  Client  │────>│ API GW   │────>│ Service  │
└──────────┘     └──────────┘     └────┬─────┘
                                  ┌────▼─────┐
                                  │    DB     │
                                  └──────────┘

Arrows: ──> sync  ══> async  ··> optional
text
[ASCII图:组件和数据流]

┌──────────┐     ┌──────────┐     ┌──────────┐
│  Client  │────>│ API GW   │────>│ Service  │
└──────────┘     └──────────┘     └────┬─────┘
                                  ┌────▼─────┐
                                  │    DB     │
                                  └──────────┘

箭头说明:──> 同步调用  ══> 异步调用(事件/队列)  ··> 可选/条件触发

[Component Name]

[组件名称]

  • Responsibility: [Single sentence]
  • Location:
    path/to/component/
  • Interface: [Key method signatures]
  • Depends on: [Other components]
  • 职责:[一句话描述]
  • 位置
    path/to/component/
  • 接口:[核心方法签名]
  • 依赖:[其他组件]

[Component Name]

[组件名称]

[Same structure]
[相同结构]

Interface Contracts

接口契约

[ComponentA] -> [ComponentB]

[组件A] -> [组件B]

go
type OrderService interface {
    CreateOrder(ctx context.Context, req CreateOrderRequest) (*Order, error)
    GetOrder(ctx context.Context, id string) (*Order, error)
}

type CreateOrderRequest struct {
    UserID string
    Items  []OrderItem
}
go
type OrderService interface {
    CreateOrder(ctx context.Context, req CreateOrderRequest) (*Order, error)
    GetOrder(ctx context.Context, id string) (*Order, error)
}

type CreateOrderRequest struct {
    UserID string
    Items  []OrderItem
}

Event Contracts

事件契约

json
{
  "event": "order.status_changed",
  "payload": {
    "order_id": "string (UUID)",
    "old_status": "string (enum: pending|processing|shipped|delivered)",
    "new_status": "string (enum)",
    "changed_at": "string (ISO8601)"
  }
}
json
{
  "event": "order.status_changed",
  "payload": {
    "order_id": "string (UUID)",
    "old_status": "string (enum: pending|processing|shipped|delivered)",
    "new_status": "string (enum)",
    "changed_at": "string (ISO8601)"
  }
}

Data Model

数据模型

sql
CREATE TABLE orders (
    id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id    UUID NOT NULL REFERENCES users(id),
    status     TEXT NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending','processing','shipped','delivered')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_orders_user_status ON orders(user_id, status);
sql
CREATE TABLE orders (
    id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id    UUID NOT NULL REFERENCES users(id),
    status     TEXT NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending','processing','shipped','delivered')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_orders_user_status ON orders(user_id, status);

Entity Relationships

实体关系

text
User 1──* Order 1──* OrderItem *──1 Product
text
User 1──* Order 1──* OrderItem *──1 Product

Open Questions

待解决问题

  • [Unresolved technical question] (@owner)
  • [Resolved question] -> Decision: [answer]

<!-- Below this line = L4 (deep reference) -->
  • [未解决的技术问题] (@负责人)
  • [已解决的问题] -> 决策:[答案]

<!-- 此线以下为L4(深度参考内容) -->

Alternatives Considered

备选方案考量

[Alternative Name]

[备选方案名称]

  • Approach: [Description]
  • Pros: [Benefits]
  • Cons: [Drawbacks]
  • Rejected because: [Specific reason tied to requirements]
  • 方案:[描述]
  • 优势:[好处]
  • 劣势:[弊端]
  • 未采纳原因:[与需求相关的具体理由]

Migration Plan

迁移计划

  1. [Step] (rollback: [how to undo])
  2. [Step] (rollback: [how to undo])
  1. [步骤](回滚方案:[如何撤销])
  2. [步骤](回滚方案:[如何撤销])

ADR Log

ADR日志

DateDecisionContextConsequences
YYYY-MM-DD[What was decided][Why][Impact]
undefined
日期决策内容背景影响
YYYY-MM-DD[决策内容][原因][影响]
undefined

Writing Guidelines

编写指南

Decision Summary: The Agent's First Reference

决策摘要:Agent的首要参考

When an agent starts implementing, it checks the decision summary table FIRST. This table prevents:
  • Re-investigating technology choices already made
  • Using the wrong pattern for this project
  • Introducing inconsistent approaches
Write decisions as concrete choices, not vague directions:
markdown
<!-- BAD -->
| Storage | Modern database | Best for our use case |

<!-- GOOD -->
| Storage | PostgreSQL 16 via sqlc | ACID for order state, sqlc for type-safe queries |
当Agent开始实现时,会首先查看决策摘要表。此表格可避免:
  • 重复调研已确定的技术选型
  • 为项目使用错误的模式
  • 引入不一致的实现方案
决策需写成具体选型,而非模糊方向:
markdown
<!-- 错误示例 -->
| 存储方案 | 现代数据库 | 符合我们的使用场景 |

<!-- 正确示例 -->
| 存储方案 | PostgreSQL 16 via sqlc | 订单状态需ACID特性,sqlc提供类型安全查询 |

Component Overview: Code Navigation Map

组件概览:代码导航地图

Agents need to know where to put new code. The
Location
field is critical -- it's what the agent uses to
Glob
or
Read
existing code:
markdown
undefined
Agent需要知道新代码应放置的位置
位置
字段至关重要——Agent会用它来
Glob
Read
现有代码:
markdown
undefined

Notification Sender

通知发送器

  • Responsibility: Delivers push notifications via FCM/APNs
  • Location:
    internal/notification/sender/
  • Interface:
    Send(ctx, userID, Notification) error
  • Depends on:
    internal/notification/template/
    , FCM SDK
undefined
  • 职责:通过FCM/APNs推送通知
  • 位置
    internal/notification/sender/
  • 接口
    Send(ctx, userID, Notification) error
  • 依赖
    internal/notification/template/
    , FCM SDK
undefined

Interface Contracts: Write as Code

接口契约:以代码形式编写

Agents implement against interface contracts. Write them as actual type definitions and function signatures, not prose descriptions:
go
// The agent will implement this interface.
// Prose description would require interpretation; code is unambiguous.
type NotificationSender interface {
    Send(ctx context.Context, userID string, n Notification) error
    SendBatch(ctx context.Context, batch []NotificationRequest) []Result
}
Agent会依据接口契约进行实现。需将其写成实际的类型定义和函数签名,而非文字描述:
go
// Agent将实现此接口。
// 文字描述需要解读,代码则清晰明确。
type NotificationSender interface {
    Send(ctx context.Context, userID string, n Notification) error
    SendBatch(ctx context.Context, batch []NotificationRequest) []Result
}

Data Model: DDL as Source of Truth

数据模型:DDL作为唯一可信来源

Write data models as executable DDL. Agents can use these directly to create migration files:
sql
-- Include CHECK constraints: they serve as documentation AND validation
CREATE TABLE notifications (
    id      UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id),
    channel TEXT NOT NULL CHECK (channel IN ('push', 'email', 'sms')),
    status  TEXT NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending', 'sent', 'failed', 'read'))
);
数据模型需写成可执行的DDL。Agent可直接用这些内容创建迁移文件:
sql
-- 包含CHECK约束:既是文档也是验证规则
CREATE TABLE notifications (
    id      UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id),
    channel TEXT NOT NULL CHECK (channel IN ('push', 'email', 'sms')),
    status  TEXT NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending', 'sent', 'failed', 'read'))
);

ASCII Diagrams: Keep Simple

ASCII图:保持简洁

Agents parse ASCII diagrams to understand data flow. Use consistent notation:
text
──>  synchronous call
══>  asynchronous (event/queue)
··>  optional/conditional
─X─  blocked/denied
Agent会解析ASCII图以理解数据流。使用统一的符号:
text
──>  同步调用
══>  异步调用(事件/队列)
··>  可选/条件触发
─X─  阻塞/拒绝

L2 Integration: Extracting Component Rules

L2层集成:提取组件规则

After finalizing the design, extract component-specific patterns into L2 conditional rules:
markdown
<!-- .claude/rules/notification-service.md -->
---
paths:
  - "internal/notification/**/*.go"
---

Notification service patterns (from specs/design-notifications.md):
- Use NotificationSender interface for all delivery
- Never call FCM/APNs directly; go through sender abstraction
- Queue notifications via Redis Streams, never send in HTTP handler
- Use structured logging with slog for all operations
markdown
<!-- .claude/rules/order-repository.md -->
---
paths:
  - "internal/order/repository/**/*.go"
---

Order repository patterns (from specs/design-notifications.md):
- Use sqlc-generated code; do not write raw SQL
- All queries must use context for cancellation
- Use partial indexes for status-based queries
This ensures agents working on specific code areas automatically get relevant architecture constraints without loading the full design document.
设计定稿后,将组件特定模式提取到L2条件规则中:
markdown
<!-- .claude/rules/notification-service.md -->
---
paths:
  - "internal/notification/**/*.go"
---

通知服务模式(来自specs/design-notifications.md):
- 所有通知发送均使用NotificationSender接口
- 禁止直接调用FCM/APNs;需通过发送器抽象层
- 通过Redis Streams队列发送通知,禁止在HTTP处理器中直接发送
- 所有操作使用slog进行结构化日志记录
markdown
<!-- .claude/rules/order-repository.md -->
---
paths:
  - "internal/order/repository/**/*.go"
---

订单仓库模式(来自specs/design-notifications.md):
- 使用sqlc生成的代码;禁止编写原生SQL
- 所有查询必须使用context进行取消操作
- 针对基于状态的查询使用部分索引
这样可确保处理特定代码区域的Agent自动获取相关架构约束,无需加载完整设计文档。

Lifecycle

生命周期

1. Start from approved feature spec (PRD Agent Skill: skills/prd-{feature}/SKILL.md)
2. Write TL;DR with architecture approach
3. Fill decision summary table
4. Draw component diagram (ASCII)
5. Define interface contracts as code
6. Specify data model as DDL
7. Set status: "draft"
8. Add L1 reference to constitution
9. Review -> set status: "approved"
10. Extract component rules to L2 files
11. Create implementation task commands (writing-implementation-tasks skill)
12. During implementation -> set status: "implementing"
13. After completion -> set status: "done"
1. 从已批准的功能规范开始(PRD Agent Skill: skills/prd-{feature}/SKILL.md)
2. 撰写概述,说明架构方案
3. 填写决策摘要表
4. 绘制ASCII组件图
5. 以代码形式定义接口契约
6. 以DDL形式指定数据模型
7. 设置状态:"draft"
8. 在constitution中添加L1层参考
9. 评审通过后设置状态:"approved"
10. 将组件规则提取到L2文件
11. 创建实现任务指令(writing-implementation-tasks skill)
12. 实现过程中设置状态:"implementing"
13. 完成后设置状态:"done"

Quality Checklist

质量检查清单

Technical Design Quality Check:
- [ ] Links to feature spec PRD skill in frontmatter (prd field)
- [ ] TL;DR states architecture approach and key trade-off
- [ ] Decision summary has concrete choices with rationale
- [ ] Every component has location, responsibility, interface
- [ ] Interface contracts are code, not prose
- [ ] Data model is DDL with constraints
- [ ] ASCII diagram shows component relationships
- [ ] No requirements in this doc (those belong in feature spec)
- [ ] L4 separator between core design and deep reference
- [ ] Component patterns extracted to L2 rules
- [ ] File named: specs/design-{feature-name}.md
技术设计质量检查:
- [ ] 前置matter中链接到功能规范PRD技能(prd字段)
- [ ] 概述明确说明架构方案和核心权衡点
- [ ] 决策摘要包含具体选型及依据
- [ ] 每个组件都有位置、职责、接口定义
- [ ] 接口契约以代码形式呈现,而非文字描述
- [ ] 数据模型为带约束的DDL
- [ ] ASCII图展示组件关系
- [ ] 本文档不包含需求内容(需求应放在功能规范中)
- [ ] 核心设计与深度参考内容之间有L4分隔线
- [ ] 组件模式已提取到L2规则
- [ ] 文件命名为:specs/design-{feature-name}.md

Detailed Guides

详细指南

Context layer mapping details: See CONTEXT-LAYERS.md Complete design doc examples: See EXAMPLES.md
上下文层映射详情:参见 CONTEXT-LAYERS.md 完整设计文档示例:参见 EXAMPLES.md