Files
lingxi/docs/开发计划/灵犀_A0工程骨架与契约基线_实施报告_V0.1.md
T
Stev_Wang 68b5ca20f4
ci / 质量门禁 (push) Canceled after 0s
ci(ci): 支持本地 CI 并调整开发库凭据
背景:Gitea 暂未部署 Actions runner,远程 CI 会停留在 queued;本地开发库按约定改用 lingxi / postgres / postgres。

改动:
- 新增 pnpm ci:local,按 CI 工作流顺序执行 compose、格式、Lint、类型、单测、构建、迁移种子、集成、OpenAPI 与 e2e;
- 新增 scripts/e2e.mjs 管理 vite preview 生命周期,e2e 改为单 worker 避免退出挂起;
- openapi:export 生成后自动 Prettier,保持工作区干净;
- compose、.env.example、CI services 数据库凭据统一为 postgres/postgres,库名 lingxi;
- README、AGENTS、A0 报告同步本地 CI 与数据库说明。

影响面:仅本地开发与 CI 执行方式,无业务代码/接口/数据模型变更;本地库已重建为 lingxi/postgres。
回滚方式:git revert 本提交;数据库需按回滚后的 compose 凭据重新初始化。
验证:pnpm ci:local 全绿(158s),format:check、lint、typecheck、openapi:diff 通过。
2026-11-02 18:14:08 +08:00

8.6 KiB
Raw Blame History

灵犀 · A0 工程骨架与契约基线 实施报告 V0.1

对应开发计划:docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md §6.1「A0 工程骨架与契约基线」
交付方式:仅 main 直推,仓库不再保留任何短分支
日期:2026-11-02

1. 完成范围

WBS 状态 落地内容
A0-INF-01 Monorepo / 工具链 完成 pnpm workspace + Turborepo;TS strict、ESLint 9 flat + Prettier + commitlint + lint-staged + husky;.nvmrc / engines / packageManager / preinstall 仅允许 pnpm;目录与 AGENTS.md §5 一致
A0-INF-02 本地依赖与迁移种子 完成(种子范围受限,见 §4.4) infra/docker-compose.dev.yaml(PG 18 / Redis 7.4 / S3 兼容服务)+ 健康检查;.env.example;Prisma 初始化与首版迁移;system_configs 幂等种子
A0-INF-03 CI 与质量门禁 完成 .gitea/workflows/ci.yml:install → format → lint → typecheck → test → build → migrate → test:int → openapi:export/diff → e2e;新增 pnpm ci:local 在无 runner 时本地执行同一门禁;失败阻断
A0-BE-01 API 骨架 完成 NestJS 11 + Fastify;Pino + trace_id;统一错误体 {code,message,details,trace_id};GET /health;/api/docs 与 OpenAPI JSON;Zod 管道;CORS / Helmet
A0-BE-02 Prisma 基线 完成 PrismaService 封装;outbox_events / idempotency_keys / system_configs;ULID char(26)、软删/时间字段约定;首版迁移可重复执行
A0-SH-01 shared 包 完成 20 个错误码(40001–50003)、权限点常量与 模块:动作 规范、ULID、游标分页、时间/命名工具、通用 Zod schema;前后端共同引用
A0-FE-01 Web 骨架 完成 Vite 6 + React 19 + Router 7 + TanStack Query 5 + Zustand 5;Semi @douyinfe/semi-ui-19 与 React19 适配入口;路径别名;fetch 请求层(token 注入、单飞 401 刷新、统一错误提示)
A0-FE-02 UI 包基线 完成 Semi 二次封装(表格/查询表单/弹窗/空态/错误态/加载骨架);icons.ts 统一图标出口;locale;主题 token;ESLint 拦截越过出口的图标/UI 库与内联色值
A0-FE-03 布局与登录壳 完成 顶部模块菜单 + 左侧功能菜单 + 面包屑;用户菜单、任务角标占位;401/403/404/500 页;登录页;导航集中配置并按权限过滤
A0-QA-01 冒烟与报告 完成 健康检查冒烟、OpenAPI 冒烟、Playwright 登录/403/404/模块切换 4 条;覆盖率报告;CI 归档

2. 关键实现位置

  • 契约与工具:packages/shared/src/(errors/codes.ts、errors/api-error.ts、permissions.ts、ulid.ts、naming.ts、schemas/)
  • UI 基线:packages/ui/src/(icons.ts、components/、theme/tokens.css、locale.ts)
  • API:apps/api/src/(bootstrap.ts、common/filters、common/pipes、modules/platform/health/、openapi/document.ts、scripts/export-openapi.ts)
  • 数据:prisma/schema.prisma、prisma/migrations/20261102083445_init_platform_baseline/、prisma/seed.ts、prisma/SEED.md
  • Web:apps/web/src/(layout/、navigation/nav-config.ts、api/client.ts、pages/、stores/auth-store.ts、styles/)
  • 基础设施:infra/docker-compose.dev.yaml、infra/compose.dev.yaml、.env.example
  • 契约快照:openapi/lingxi.openapi.json、apps/web/src/api/generated/openapi.d.ts

3. 本地门禁实测

命令 结果
pnpm format:check 通过
pnpm lint 通过(0 error / 0 warning)
pnpm typecheck 通过(10/10 turbo tasks)
pnpm test 通过(shared 42、api 20、web 12)
pnpm build 通过(8/8 turbo tasks)
pnpm test:int 通过(真实 PostgreSQL + Redis,/health 200)
pnpm test:e2e 通过(4/4,Playwright/Chrome)
pnpm openapi:export + pnpm openapi:diff 通过;快照含 20 个错误码,OpenAPI 3.1.0
pnpm compose:up 通过;lingxi-pg / lingxi-redis / lingxi-s3 均 healthy
API 启动 /health 200、/api/docs 200、/api/openapi.json 200
Worker 启动 连接 Redis 成功,收到 SIGTERM 后正常退出
种子幂等 连续执行两次,system_configs 保持 7 条

4. 与文档的差异与待确认

4.1 宿主端口(环境适配)

本机已有容器占用 5432 / 6379,A0 compose 宿主端口改为 15432(PG)/ 16379(Redis)/ 19000–19001(S3),容器内端口不变。.env.example 已按宿主端口提供连接串;本地数据库为 lingxi,用户 postgres,密码 postgres(仅开发环境)。CI services 使用标准端口,凭据同为 postgres/postgres。

4.2 对象存储镜像不可得(环境适配)

当前 Docker 环境无法拉取 minio/minio 与 minio/mc(registry denied),dl.min.io 二进制返回 410。A0 使用 adobe/s3mock 并在启动时创建 assets / renders / temp / archive 四个桶,仅用于本地开发;CI / 生产接入真实 MinIO 时替换 compose 中 s3 服务即可,应用侧仍只依赖 S3 协议与环境变量。

4.3 演示登录(A0 临时)

A1 才实现真实鉴权。A0 登录页在 VITE_PUBLIC_DEMO_SESSION 非 false 时使用本地演示会话进入布局,便于验收布局与权限过滤;A1 接入真实登录后删除该分支。

4.4 种子范围【待确认 Q-A0-01】

开发计划 A0-INF-02 要求种子包含「超管、示例角色、核心字典、电商行业包占位」,但 users / roles / dict_* / industry_packages 等表分别在 A1 / A3 / A4 / B0 批次建立。A0 不提前建业务表,仅 seed system_configs 7 项,并在 prisma/SEED.md 登记待补种子清单。请确认是否接受该拆分;若要求 A0 内建表,则需调整开发计划批次顺序。

4.5 错误码 HTTP 映射

工程规范 04 未规定 50002 / 50003 的 HTTP 状态。A0 将 50002 依赖不可用 映射为 503(与 /health 依赖异常返回值一致),50003 超时 映射为 504;如需改为 502 / 504,请确认后调整 packages/shared/src/errors/codes.ts 与 codes.spec.ts。

4.6 Prisma CLI 与环境文件

Prisma CLI 只自动读取 .env,不读取 .env.local。本地需执行 cp .env.local .env(两者均在 .gitignore);应用与种子脚本同时兼容 .env.local 与 .env。

4.7 OpenAPI 破坏性检查实现

npm 上 oasdiff 为占位包(0.0.1-security),A0 暂用自研 scripts/openapi-diff.mjs 做路径/操作/字段级破坏性检查;CI 可后续替换为 oasdiff 官方二进制,命令仍为 pnpm openapi:diff。

4.9 本地 CI 与数据库凭据

当前离线 Gitea 未部署 Actions runner,推送后远程 CI 会停留在 queued。A0 增加 pnpm ci:local:按 .gitea/workflows/ci.yml 的顺序在本地执行 compose、格式、Lint、类型、单测、构建、迁移与种子、集成、OpenAPI 契约与 e2e,全部通过才退出 0;runner 就绪后远程工作流可直接接管。

本地开发数据库已按约定改为:库名 lingxi、用户 postgres、密码 postgres;compose、.env.example、CI services 三处保持一致。

4.8 前端视觉方向

已按 oil-ui-pro 流程产出两轮方案:

  • v1(概念化:剪辑台 / 稿纸 / 调度台)被否决;
  • v2(传统且现代化:云白蓝 / 石墨 / 暖白青)经产品负责人选择 A · 云白蓝,已落地到 packages/ui/src/theme/tokens.css、apps/web/src/styles/、apps/web/index.html:
    • 顶部模块菜单 + 左侧功能菜单 + 面包屑;
    • 白色顶栏、#F5F7FA 工作区、白卡片、#1677FF 主色、6px 圆角;
    • 工作台:4 指标卡 + 生产任务表 + 快速入口 + 最近素材;
    • 登录页:左上品牌、居中白卡、浅灰背景。

设计探索产物位于 design/a0-ui-v2/(含 6 屏、对比页与截图),按 .gitignore 约定不入库,仅本地留存评审。

5. 已知风险与后续动作

  1. A1 必须移除演示登录并接入真实 JWT / 刷新令牌 / 权限守卫。
  2. 种子业务数据待 A1 / A3 / A4 / B0 表就绪后补齐(Q-A0-01)。
  3. MinIO 本地替代方案需在具备镜像的环境回归;生产 compose 与 CI 镜像另行处理。
  4. Web 主包约 599 kB(Semi 全量 CSS 689 kB),A0 接受;M1 前做路由级拆分与 Semi 按需样式。
  5. 远程 CI 待 Gitea Actions runner 就绪后验证 services 与 Playwright 浏览器安装;当前以 pnpm ci:local 为准(已实测通过)。

6. 下一步(A1)

按开发计划进入 A1:identity / client 模块、真实登录与 RBAC、ScopeContext、客户与组织基础表、登录与权限三态测试。