3.3 KiB
3.3 KiB
AGENTS.md — 给编码代理的指引
本仓库是 VMall B2B2C 商城 MVP(pnpm + Cargo 双 workspace)。改动前先读本文件与 README.md;功能变更须同步 OpenSpec。
布局与所有权
apps/api— Rust 后端(cratevmall-api)。迁移在apps/api/migrations/(sqlx,启动时自动执行,只增不改)。apps/mall/apps/shop-admin/apps/admin— 三个 Nuxt 3 应用。端口固定 3000/3001/3002。packages/shared—@vmall/shared:唯一 API 契约(src/types.ts+src/api.ts)、en/zh 语言包、共享样式ui.css。前端禁止自建 API 封装;契约变更只在这里改,且三个前端都要过构建。openspec/— 规范。specs/是已归档能力规范(auth, rbac, catalog, currency, cart, order, shipment, invoice, frontend-*)。scripts/seed-demo.mjs— 幂等演示数据。
硬性约定
- 金额:
i64/number最小单位 + 币种码;换算走后端/api/currencies/convert或共享formatMoney(minor, code, exponent, locale)。禁止浮点金额运算,禁止在前端硬编码 exponent=2(JPY 是 0)——用币种表里的 exponent。 - i18n 内容:凡是面向用户的内容字段都是
{"en","zh"}JSONB;UI 文案一律$t(),缺键加到本应用的locales-extra.ts,不要从应用代理改packages/shared语言包以外的文件(共享包改动属契约变更,需谨慎并跑齐三个构建)。 - TS 纪律:禁止
any/as any/@ts-ignore;外部数据用类型守卫或 schema 校验;客户端方法类型在@vmall/shared命名导出。 - Rust 纪律:错误统一
ApiError({"error":{"code","message"}});SQL 用sqlx::query*+ 显式 bind;状态迁移必须校验前置状态(参考 orders/shipments 的UPDATE ... WHERE status = ...模式)。 - RBAC:受保护路由声明角色(
auth.require(&[...]));店铺资源必须过auth.own_shop()作用域,跨店返回 404。
开发流程(OpenSpec)
- 新能力/行为变更:在
openspec/changes/<name>/建proposal.md+tasks.md+specs/<capability>/spec.md(## ADDED Requirements/### Requirement:/#### Scenario:格式),openspec change validate <name> --strict必须通过。 - 按 tasks 实现;完成后勾选并
openspec archive <name> --yes;归档后openspec validate --all --strict保持全绿。 - 只改文档/样式/重构可不建 change。
验证(交付前必跑)
cargo test -p vmall-api # 集成测试连 docker 的 vmall_test + Redis,须全绿且可重复运行(测试夹具 slug 已唯一化,勿改回固定 slug)
pnpm --filter @vmall/<改动过的前端> build
- 修 bug:先复现,修完确认复现不再触发;有价值的场景补成集成测试(放
apps/api/tests/,复用tests/common/mod.rs夹具)。 - UI 变更:起 dev server 用浏览器实际点一遍改动路径,视觉确认才算完成。
- 不要跑与改动无关的全仓命令(
pnpm -r build、lint 全仓等)。
环境
- Postgres:
docker exec pg18 psql -U postgres(postgres/postgres;库vmall/vmall_test)。Redis:容器rdb8。 - 后端环境变量见 README;测试库连接串写死在
apps/api/tests/common/mod.rs。