ci / 质量门禁 (push) Canceled after 0s
背景:项目方提供公网 RustFS(https://oss.xinsenidea.com,桶 lingxi-dev)。 改动:.env.example 填入 endpoint / 桶名占位;README 与 A0 报告记录 对象存储接入方式与验证结果;真实密钥仅保存在本地 .env / .env.local。 影响面:环境变量样例与文档,无运行时代码变更。 回滚方式:还原 .env.example 与文档即可。 验证:list buckets、HEAD bucket、PUT/GET/DELETE 探针对象均成功; format:check、lint、typecheck、test 全绿。
108 lines
8.9 KiB
Markdown
108 lines
8.9 KiB
Markdown
# 灵犀 · 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) | 复用本机 `docker-postgres-1`(PostgreSQL 18,5432)与 `docker-redis-1`(6379);`pnpm check:dev` 预检;`.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/`)
|
||
- 本地依赖:`scripts/check-dev-deps.mjs`、`.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 check:dev` | 通过;PostgreSQL `5432/lingxi` 与 Redis `6379` 均可连接,`/health` 与 `test:int` 验证连通 |
|
||
| API 启动 | `/health` 200、`/api/docs` 200、`/api/openapi.json` 200 |
|
||
| Worker 启动 | 连接 Redis 成功,收到 SIGTERM 后正常退出 |
|
||
| 种子幂等 | 连续执行两次,`system_configs` 保持 7 条 |
|
||
|
||
## 4. 与文档的差异与待确认
|
||
|
||
### 4.1 本地依赖来源(环境适配)
|
||
|
||
本地 PostgreSQL 与 Redis **复用本机已有 Docker 服务**,不另起容器:`docker-postgres-1`(PostgreSQL 18,`127.0.0.1:5432`,库 `lingxi`、用户 `postgres`、密码 `postgres`)与 `docker-redis-1`(`127.0.0.1:6379`)。仓库不包含任何数据库/缓存容器编排。CI services 使用标准 5432/6379,凭据同为 `postgres/postgres`。
|
||
|
||
### 4.2 对象存储接入公网 RustFS
|
||
|
||
本地 Docker 不提供 S3 服务,`minio/minio` 镜像在当前网络也不可拉取。项目方已提供公网 RustFS:`https://oss.xinsenidea.com`,桶 `lingxi-dev`。A0 代码不依赖对象存储(`/health` 只检查 DB 与 Redis),已在本地 `.env.local` / `.env` 配置 `S3_*` 并实测通过(list buckets、HEAD bucket、PUT / GET / DELETE 探针对象均成功)。三类产物(assets / renders / temp)暂共用 `lingxi-dev` 桶,A1 落地渲染链路时再按前缀或独立桶拆分。真实 access key / secret 不入库。
|
||
|
||
### 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`,直接连接本机已有 PostgreSQL 容器;`.env.example` 与 CI services 保持一致;对象存储已接入公网 RustFS(见 §4.2)。
|
||
|
||
### 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. 对象存储为公网 RustFS 单桶,A1 需按产物类型落前缀或拆分桶,并在 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`、客户与组织基础表、登录与权限三态测试。
|