一键导入
nexusx-4phase
基于 nexusx 的四阶段开发模式,从 Schema 建模到 API 响应组装再到 TS SDK 的完整项目构建流程。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
基于 nexusx 的四阶段开发模式,从 Schema 建模到 API 响应组装再到 TS SDK 的完整项目构建流程。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| 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 |