with one click
nexusx-4phase
基于 nexusx 的四阶段开发模式,从 Schema 建模到 API 响应组装再到 TS SDK 的完整项目构建流程。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
基于 nexusx 的四阶段开发模式,从 Schema 建模到 API 响应组装再到 TS SDK 的完整项目构建流程。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | nexusx-4phase |
| description | 基于 nexusx 的四阶段开发模式,从 Schema 建模到 API 响应组装再到 TS SDK 的完整项目构建流程。 |
| argument-hint | [项目路径] 创建四阶段项目的目标目录 |
基于 nexusx 的渐进式开发方法论。项目在一个 src/ 目录下逐步演进,每个阶段在上一阶段基础上新增代码。
| Phase | 职责 | 产出 |
|---|---|---|
| Phase 0 | 需求确认 | 实体 + 关系 + 聚合根 + 用例方法(与用户反复确认) |
| Phase 1 | Schema + ER Diagram + 聚合根入口 + mock seed | models + db(engine + session) + database(seed) + voyager |
| Phase 2 | Loader 实现 | models 方法体实现,GraphQL 可查询 |
| Phase 3 | UseCase 响应组装 + MCP | dtos + services + REST(或 JSON-RPC)+ MCP + CLI + Voyager 补充 services |
| Phase 4 | OpenAPI spec → TS SDK | 端到端 SDK |
每个 Phase 的结构统一为三段:
┌──────────────────────────────────────────────┐
│ V 降:定义验收标准 │
│ "在当前 Phase 开始之前,先定义什么算做完。" │
│ 写入 spec/<phase>.md 的"验收标准"部分 │
└──────────────────────────────────────────────┘
↓
┌───────────────┐
│ 实现 Phase │
└───────────────┘
↓
┌──────────────────────────────────────────────┐
│ V 升:逐条回查验收 │
│ "一条一条对照验收标准,通过才可继续。" │
│ 用户逐条确认 → 写入 spec/<phase>.md │
└──────────────────────────────────────────────┘
验收标准必须是可观察、可操作的——不写"代码健壮",写"GraphiQL 中执行 X query 返回 Y"。
Phase 0(需求确认)完整包含在本文件中。
Phase 0 完成并确认后,读取当前阶段的详细指令:
phases/phase1.mdphases/phase2.mdphases/phase3.mdphases/phase4.md每个阶段完成后,继续进行下一阶段之前暂停并等待用户确认。
对于 Spec 管理工作流(目录命名、文件格式、迭代规则、交付验证),读取 spec-management.md。
在写任何代码之前,必须与用户逐项确认以下内容。每一项都需要用户明确认可后才算完成。
逐一列出所有业务实体,每个实体说明:
用表格形式呈现,方便用户逐行确认。
用文本 ER 图展示实体间关系,每条关系标明:
User ──1:N──→ Participant
Conversation ──1:N──→ Message
...
必须与用户确认关系方向和基数是否正确。
明确哪个(或哪些)实体是聚合根。聚合根决定:
每个聚合根必须明确是 SQLModel 实体还是 虚拟实体(普通 pydantic.BaseModel):
| 类型 | 何时选 | 数据持久化 | 例子 |
|---|---|---|---|
| SQLModel 实体 | 数据需要落库、参与 alembic 迁移、是 GraphQL 实体入口 | ✅ 表 | User / Sprint / Conversation |
| 虚拟实体(BaseModel) | 响应根不对应ORM表:组装自外部 claims、聚合视图、第三方 SDK DTO | ❌ 不建表 | CurrentUser(OIDC claims)、Page[T](分页 wrapper)、第三方 SDK 镜像 |
虚拟实体通过 ErManager.add_virtual_entities([...]) 在 Phase 1 注册,与 SQLModel 实体在 Resolver / ER / Voyager 中同等对待(详见 docs/guide/virtual_entities.md)。
判断依据:如果根字段全部来自数据库表 → SQLModel;如果字段来自请求上下文(JWT、headers)或聚合多个源 → 虚拟实体。混合场景(如 Page[TaskDTO] 包含真实 task 数据)由 Phase 3 DTO 组合,根本身仍是虚拟实体。
⚠️ 禁止自行决定 Service 切分方案。必须提出候选方案与用户讨论,由用户最终确认。
业务域(Service)按功能边界划分,不按实体划分。Service 切分直接影响:
service/<domain>/)必须向用户提出至少一种候选方案,说明每种方案的切分依据和优劣,由用户选择或修正。
常见的切分策略参考:
| 策略 | 示例 | 适用场景 |
|---|---|---|
| 按业务功能域 | auth / chat / order | 业务边界清晰,领域间耦合低 |
| 按聚合根 | user / conversation / message | 实体独立性强,CRUD 为主 |
| 混合(功能域 + 独立聚合) | auth / chat(含 conversation+message) | 部分域跨实体协作 |
向用户展示的格式:
方案 A:按功能域
auth/ → register, login
chat/ → create_conversation, list_messages, send_message
优势:业务内聚,方法自然归组
劣势:chat 域可能过大
方案 B:按聚合根
user/ → register, login
conversation/ → create_conversation, list_messages
message/ → send_message
优势:每个 service 粒度均匀
劣势:conversation 和 message 强耦合却拆开了
必须等用户明确选择后才能继续。 如果用户提出自己的分法,按用户的来。
用户确认 Service 切分后,按每个业务域列出用例方法。每个方法说明:
create_conversation、list_messages)示例格式:
| 业务域 | 方法名 | 业务意图 | 挂载实体 | 关键参数 |
|---|---|---|---|---|
| auth | register | 注册新用户 | User | username, nickname, password |
| auth | login | 登录返回 JWT | User | username, password |
| chat | create_conversation | 创建会话 | Conversation | type, creator_id, name |
| chat | list_messages | 查询会话消息(分页) | Conversation | conversation_id, before_id, limit |
用例方法不需要实现细节,但必须逻辑自洽:
GraphQL 是辅助开发测试和 AI 测试的接口,不是正式 API。
业务方法的定义和挂载关系:
service/<domain>/methods.py ← 独立定义业务逻辑(核心)
↓ 挂载 ↓ 挂载
Entity @query/@mutation UseCaseService @query/@mutation
(GraphQL 辅助测试) (REST + MCP 正式接口)
service/<domain>/methods.py 中实现,models.py 的 mount_method() 函数挂载到 Entity,main.py 显式调用列出项目中涉及的非业务功能领域(认证、实时推送、文件存储、数据迁移等),对每个领域:
用表格形式呈现:
| 功能领域 | 推荐方案 | 理由 | 备注 |
|---|---|---|---|
| 认证 | ... | ... | ... |
| ... | ... | ... | ... |
注意事项:
必须与用户确认每个领域的选型后才能继续。
⚠️ 必须由用户明确选定 DB 类型与迁移策略,决定 Phase 1 的 db.py / database.py 实现方式以及是否引入 alembic。
| 选项 | async DB URL | 持久化 | Alembic | 额外依赖 | 适用场景 |
|---|---|---|---|---|---|
| In-memory SQLite | sqlite+aiosqlite:// | ❌ 进程退出即丢 | ❌ 不需要 | aiosqlite | 纯原型/Demo/团队讨论数据样本,不关心数据保留 |
| File-backed SQLite | sqlite+aiosqlite:///./var/<name>.db | ✅ 文件 | ✅ 必须 | aiosqlite | 本地开发、单人项目、轻量持久化 |
| Docker PostgreSQL | postgresql+asyncpg://user:pwd@localhost:5432/db | ✅ 容器卷 | ✅ 必须 | asyncpg + docker-compose | 团队开发、生产前演练 |
| Docker MySQL | mysql+aiomysql://user:pwd@localhost:3306/db | ✅ 容器卷 | ✅ 必须 | aiomysql + docker-compose | 同上,团队偏好 MySQL |
| External DB | 各种 | ✅ | ✅ 必须 | 视驱动 | 已有 DB 基础设施 |
db.py:engine URL 取决于此决策database.py:
init_db() 做 create_all + mock seed(每次重启自动恢复,讨论用样本数据)init_db() 改为 no-op,schema 由 alembic 管,seed 改为一次性 scripts/load_seed.py(保留 ID)alembic init alembicenv.py:import src.models 注册表 + target_metadata = SQLModel.metadata + 同步 URL(app 用 async,alembic 用 sync)render_as_batch=True;PostgreSQL / MySQL 不需要script.py.mako 模板加 import sqlmodel(SQLModel 的 AutoString 类型需要)pyproject.toml 加 alembic>=1.13alembic revision --autogenerate -m "init schema" → 检查 → alembic upgrade head.gitignore 加 var/(file sqlite 场景)spec/phase0.md)DB 选型:[in-memory sqlite / file sqlite / docker pg / docker mysql / external ___]
async DATABASE_URL:________________
sync DATABASE_URL_SYNC(alembic + load_seed 用):________________
是否引入 alembic:[是 / 否]
是否需要 docker-compose:[是 / 否]
init_db() 策略:[create_all+seed / no-op+alembic / 其他]
用户未明确选定前,禁止进入 Phase 1。
全部确认后,向用户展示汇总,确保以下问题已回答:
全部确认后才能进入 Phase 1。
读取本 skill 目录下 template/ 中的代码作为生成参考。严格遵守 template 中的文件结构、import 风格和命名约定。
单项目渐进演进,每个 Phase 在上一阶段基础上新增文件:
src/
├── models.py # Phase 1 纯实体 → Phase 2 从 methods 挂载 @query/@mutation
├── db.py # Phase 1(engine + session factory,不依赖 models;URL 由 Step 0-7 DB 选型决定)
├── database.py # Phase 1(in-memory: create_all+seed;持久化: no-op,schema 由 alembic 管)
├── service/ # Phase 2 新增 methods.py,Phase 3 补充 service.py/dtos.py
│ ├── auth/ # 按业务域划分(非按实体)
│ │ ├── methods.py # Phase 2: 独立业务方法
│ │ ├── dtos.py # Phase 3: DTO
│ │ ├── service.py # Phase 3: UseCaseService
│ │ ├── test.py # Phase 3: unittest, file or folder, depends on complexity
│ │ └── spec.md # Phase 3: 服务说明
│ └── chat/
│ ├── methods.py
│ ├── dtos.py
│ ├── service.py
│ ├── test.py
│ └── spec.md
├── main.py # 逐步扩展(voyager → graphql → create_use_case_router → mcp)
alembic/ # Phase 1 持久化场景才引入(file sqlite / docker / external)
├── env.py # 接 SQLModel.metadata + sync URL + render_as_batch(sqlite)
├── script.py.mako # 模板加 import sqlmodel
└── versions/ # 自动生成的迁移文件
scripts/ # Phase 1 持久化场景
└── load_seed.py # 一次性把 var/seed_data.json 灌入文件 DB(保留 ID)
var/ # gitignored(file sqlite 场景)
├── note-tool.db # 实际 DB 文件
└── seed_data.json # mock seed 数据
fe/ # Phase 4 前端 SDK
├── openapi-ts.config.ts
├── package.json
└── src/sdk/ # 自动生成的 SDK
├── sdk.gen.ts # SDK class(按 tag 分组)
├── types.gen.ts # TS 类型定义
└── client/ # HTTP client
REST 路由通过 create_use_case_router(use_case_config) 自动生成,不需要手写 router/ 目录。也可使用 create_jsonrpc_router() 替代 REST(JSON-RPC 2.0 协议)。
| 方面 | Phase 1 | Phase 2 | Phase 3 | Phase 4 |
|---|---|---|---|---|
| 实体 | 纯字段 + Relationship + docstring + mock seed | methods.py 实现 + mount_method() 挂载到 Entity | 继承 Phase 2 | - |
| 关系 | Relationship 声明 | DataLoader 实现 | DefineSubset 隐藏 FK | - |
| 查询 | 无方法 | methods.py + mount_method() 挂载 | UseCaseService 封装(复用 methods.py) | - |
| API | Voyager(ER diagram) | GraphiQL | GraphQL + REST(或 JSON-RPC)+ Voyager(+services) + MCP + CLI | TS SDK |
| 响应 | N/A | 完整实体 | DefineSubset DTO | OpenAPI spec |