326 lines
13 KiB
Markdown
326 lines
13 KiB
Markdown
# Agent 项目规范文档(uni-app / uvue / uts)
|
||
|
||
## 0. 文档目标与适用范围
|
||
|
||
- **目标**:统一项目目录、命名、依赖边界、数据库(SQL/RLS/RPC)安全策略与准入流程,使 Agent 在改动代码/SQL 时遵循一致的工程约束与安全基线。
|
||
- **适用范围**:
|
||
- 前端:`pages/`、`components/`、`layouts/`、`services/`、`utils/`、`types/`、`uni_modules/`、`static/`
|
||
- 文档与数据库:`docs/`、`docs/sql/`、模块内 `test/` SQL
|
||
|
||
---
|
||
|
||
## 1. 项目核心结构与职责边界
|
||
|
||
### 1.1 页面与路由
|
||
|
||
- **权威路由配置**:根目录 `pages.json`
|
||
- **分包规则**:
|
||
- `tabBar`:主入口页面(消费者端)
|
||
- `subPackages`:按模块分包(consumer 非 tab 页、delivery、analytics、admin、merchant、service 等模块)
|
||
- **页面目录**:`pages/`
|
||
- `pages/user/`:登录/注册/用户中心等公共页面
|
||
- `pages/mall/<module>/`:各业务模块(consumer/delivery/analytics/admin/merchant/service...)
|
||
- **规则**:
|
||
- `pages/` 内只放页面(路由入口)与页面级组合逻辑
|
||
- 可复用 UI/逻辑必须下沉到 `components/` / `services/` / `utils/` / `types/`
|
||
|
||
### 1.2 布局
|
||
|
||
- **目录**:`layouts/`
|
||
- **规则**:
|
||
- layout 只负责结构与 slot/容器
|
||
- layout 不直接写重业务数据请求(可触发初始化但不承担领域逻辑)
|
||
|
||
### 1.3 组件
|
||
|
||
- **目录**:`components/`
|
||
- **推荐分层(可渐进迁移)**:
|
||
- `components/base/`:无业务语义基础组件(按钮、弹窗、表单控件、空状态等)
|
||
- `components/biz/<domain>/`:带业务语义组件(订单卡片、SKU 选择器等)
|
||
- `components/integration/<vendor>/`:第三方/平台集成组件(如 supabase、analytics SDK 外观层)
|
||
- **规则**:
|
||
- 组件不得直接读写数据库或拼接 SQL
|
||
- 网络/数据访问必须通过 `services/`(数据访问唯一入口)
|
||
|
||
### 1.4 服务层(数据访问唯一入口)
|
||
|
||
- **目录**:`services/`
|
||
- **职责**:
|
||
- RPC/API 调用封装
|
||
- 鉴权、token 注入、错误标准化处理
|
||
- 数据转换(DTO -> ViewModel 允许在这里或页面层,但必须统一口径)
|
||
- **规则**:
|
||
- 页面/组件不得直接访问底层 client(如 supabase client),必须经 `services/` 统一出口
|
||
|
||
### 1.5 工具与类型
|
||
|
||
- **目录**:
|
||
- `utils/`:纯工具函数(尽量无 IO、无全局状态)
|
||
- `types/`:全局类型、领域模型、DTO、服务返回类型
|
||
- **规则**:
|
||
- `utils/` 不反向依赖业务模块目录
|
||
- `types/` 不依赖运行时代码(保持纯类型)
|
||
|
||
### 1.6 插件/可替换模块
|
||
|
||
- **目录**:`uni_modules/`
|
||
- **定位**:可独立发布/可替换的插件能力(组件、uts sdk、集成适配等)
|
||
- **规则**:
|
||
- 不把所有业务通用代码塞到 `uni_modules/`;业务通用优先 `services/utils/components`
|
||
|
||
---
|
||
|
||
## 2. 路径别名与引用规范
|
||
|
||
### 2.1 当前事实
|
||
|
||
- `tsconfig.json` 已配置:`@/* -> ./*`
|
||
|
||
### 2.2 统一引用建议(Agent 必须遵循)
|
||
|
||
- 默认使用 `@/` 前缀引用项目内代码(例如 `@/services/...`、`@/components/...`)
|
||
- 不强制引入 `@components`、`@uni_modules` 这类新 alias,除非后续明确要落地到配置文件;当前以目录语义规范为准
|
||
|
||
---
|
||
|
||
## 3. 依赖方向(强约束)
|
||
|
||
为避免循环依赖与业务污染,依赖方向必须满足:
|
||
|
||
- `pages` -> 可依赖 `components/services/utils/types/layouts`
|
||
- `components` -> 可依赖 `services/utils/types`
|
||
- `layouts` -> 可依赖 `components/utils/types`(避免重业务)
|
||
- `services` -> 只依赖 `utils/types`(不得依赖 pages/components)
|
||
- `utils` -> 不依赖业务目录
|
||
- `types` -> 不依赖运行时代码
|
||
|
||
---
|
||
|
||
## 4. 命名与文件组织规范
|
||
|
||
- **目录名**:全小写,必要时用连字符(全仓统一一种风格)
|
||
- **组件文件**:`PascalCase.uvue`
|
||
- **服务文件**:统一 `xxxService.uts`
|
||
- **SQL 文件**:
|
||
- 测试阶段:模块 `test/` 下自由命名,但必须含用途前缀
|
||
- 权威阶段:进入 `docs/sql/` 后必须按分层目录 + 版本号命名(见第 6 节)
|
||
|
||
---
|
||
|
||
## 5. 数据库/权限权威口径(与前端联动)
|
||
|
||
本项目数据库权限与前端路由/页面访问形成闭环。以下为强制口径:
|
||
|
||
- **角色字段唯一权威**:`public.ak_users.role`
|
||
- **analytics/admin 的全局数据访问**:必须通过 RPC 完成,避免直接开放业务表全局权限
|
||
- **前端必须做客户端守卫**:
|
||
- 访问 analytics/admin 页面入口时,必须校验登录与角色(例如 `ensureRole(['admin','analytics'])`)
|
||
- 客户端守卫只用于“快速失败”,最终权限以数据库侧为准
|
||
|
||
---
|
||
|
||
## 6. SQL 两阶段工作流(模块测试 -> 权威入库)
|
||
|
||
### 6.1 阶段 A:模块内测试 SQL(非权威)
|
||
|
||
- **位置**:各模块目录 `test/`
|
||
- 例:`pages/mall/analytics/test/*.sql`
|
||
- **允许**:快速迭代、验证思路、临时脚本
|
||
- **禁止**:高危破坏性操作(见 7.3)
|
||
|
||
### 6.2 阶段 B:入库到 `docs/sql/`(权威)
|
||
|
||
- **位置**:`docs/sql/`
|
||
- **入库准入条件**:
|
||
- 必须通过 Agent 安全评估(输出评审报告)
|
||
- 必须符合本项目角色/RLS/RPC 安全口径(见 7.2;并强制对照 `docs/sql/11_roles_and_permissions_strategy.md`)
|
||
- 建议至少 1 人人工确认后再合并
|
||
|
||
### 6.3 `docs/sql/` 分层(权威目录结构)
|
||
|
||
为保证可审计、可复用与最小风险暴露,进入权威目录的 SQL 必须按“对象类型”拆分归档,禁止将多种对象(表 + RLS + RPC + GRANT 等)长期混放在同一个文件中。
|
||
|
||
- `docs/sql/00_meta/`:规范/策略/说明类(如角色与权限策略)
|
||
- `docs/sql/10_schema/`:表/类型/索引等 DDL
|
||
- 建议进一步按域分组:`docs/sql/10_schema/<domain>/...`
|
||
- `docs/sql/20_rls/`:RLS enable + policies(按表/域拆分)
|
||
- 建议进一步按域分组:`docs/sql/20_rls/<domain>/...`
|
||
- `docs/sql/30_rpc/`:RPC/函数(尤其 analytics)
|
||
- 建议进一步按域分组:`docs/sql/30_rpc/<domain>/...`
|
||
- `docs/sql/40_grants/`:显式授权(GRANT/REVOKE)
|
||
- 仅允许最小权限;对 `anon/authenticated` 的任何授权必须附带评审结论
|
||
- `docs/sql/90_archive/`:历史/废弃(只读,不再作为引用口径)
|
||
|
||
**对象拆分规则(入库必选一类)**:
|
||
|
||
- **表/类型/索引**:只放 DDL(`CREATE/ALTER TABLE/TYPE/INDEX`),归入 `10_schema`
|
||
- **RLS 策略**:只放 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` 及 `CREATE POLICY/ALTER POLICY/DROP POLICY`,归入 `20_rls`
|
||
- **函数/RPC**:只放 `CREATE OR REPLACE FUNCTION ...`(含 `SECURITY DEFINER` 等),归入 `30_rpc`
|
||
- **授权**:只放 `GRANT/REVOKE`,归入 `40_grants`
|
||
|
||
**例外(允许同文件)**:
|
||
|
||
- 同一对象的“紧耦合小变更”可以同文件(例如同一个函数的创建 + 注释/owner 设置),但不得混入其他对象类型。
|
||
|
||
### 6.4 权威 SQL 入库步骤(从模块 test/ 迁移)
|
||
|
||
当模块内 `test/` SQL 验证通过、准备进入 `docs/sql/` 时,必须按以下步骤执行:
|
||
|
||
- **步骤 0:目录存在性检查(必须)**
|
||
- 若以下目录不存在,Agent 必须创建;若已存在则复用,禁止新建“近似重复目录”。
|
||
- 目录清单:
|
||
- `docs/sql/00_meta/`
|
||
- `docs/sql/10_schema/`
|
||
- `docs/sql/20_rls/`
|
||
- `docs/sql/30_rpc/`
|
||
- `docs/sql/40_grants/`
|
||
- `docs/sql/90_archive/`
|
||
- 如采用域分组(`<domain>`),对应的 `docs/sql/<layer>/<domain>/` 目录同样遵循“无则创建,有则复用”。
|
||
|
||
- **步骤 1:对象识别与拆分**
|
||
- 将 SQL 按对象类型拆分为:schema / rls / rpc / grants(必要时再细分 domain)
|
||
|
||
- **步骤 2:命名与归档路径确定**
|
||
- 表/DDL:`docs/sql/10_schema/<domain>/<object>_v<version>.sql`
|
||
- RLS:`docs/sql/20_rls/<domain>/<table>_rls_v<version>.sql`
|
||
- RPC:`docs/sql/30_rpc/<domain>/<rpc_name>_v<version>.sql`
|
||
- Grants:`docs/sql/40_grants/<domain>/<scope>_grants_v<version>.sql`
|
||
|
||
- **步骤 3:安全评审(Agent 必须输出评审报告)**
|
||
- 评审必须强制对照 `docs/sql/11_roles_and_permissions_strategy.md`
|
||
- 结论为 `OK` 方可入库
|
||
|
||
- **步骤 4:入库与引用口径**
|
||
- 入库后,模块 `test/` 中对应脚本仅保留为测试/回归用途(不得再作为权威引用)
|
||
|
||
---
|
||
|
||
## 7. Agent SQL 安全评估制度(准入制)
|
||
|
||
### 7.1 评估结论(必须输出其一)
|
||
|
||
- `Reject`:拒绝入库
|
||
- `High`:高风险,必须整改后复评
|
||
- `OK`:可入库
|
||
|
||
### 7.2 项目强制安全要求(RPC/analytics)
|
||
|
||
所有 `rpc_analytics_*`(及类似特权 RPC)必须满足:
|
||
|
||
- `SECURITY DEFINER`
|
||
- `SET search_path = public`(固定 search_path)
|
||
- 函数入口显式鉴权:
|
||
- `get_current_user_role() IN ('admin','analytics')` 才允许执行
|
||
- 返回字段最小化(只返回统计必要字段/聚合结果)
|
||
|
||
**强制参照文档**:所有 SQL 评审必须对照并满足 `docs/sql/11_roles_and_permissions_strategy.md` 中的角色定义、RLS 分层、RPC 安全闭环要求。
|
||
|
||
### 7.3 硬阻断(出现任意一条:Reject)
|
||
|
||
- **裸放权**:对 `anon/authenticated` 大范围 `GRANT` 且无等价约束
|
||
- **破坏性操作**:
|
||
- `DROP TABLE/SCHEMA/ROLE/EXTENSION`
|
||
- `TRUNCATE`
|
||
- 大范围 `DELETE/UPDATE` 无可靠 `WHERE`
|
||
- **不安全的 SECURITY DEFINER**:
|
||
- 无入口鉴权
|
||
- 未固定 `search_path`
|
||
- **绕过 RLS 的不透明入口**:绕过后无角色校验/无最小返回字段
|
||
|
||
### 7.4 高风险需整改(High)
|
||
|
||
- RLS 覆盖不全(业务需要写但未覆盖 `INSERT/UPDATE/DELETE`)
|
||
- policy 条件过宽(如 `USING (true)`)
|
||
- RPC 返回敏感字段
|
||
- 无分页/无 LIMIT 约束造成全量泄露或性能风险
|
||
|
||
---
|
||
|
||
## 8. Agent SQL 评审报告模板(固定输出)
|
||
|
||
### SQL 安全评审报告
|
||
|
||
- **对象**:`<文件路径>`
|
||
- **目标**:`<此 SQL 的目的>`
|
||
- **结论**:`Reject | High | OK`
|
||
- **涉及对象**:
|
||
- 表/视图/函数:`...`
|
||
- 角色/权限:`...`
|
||
- RLS:是否启用/修改;覆盖哪些操作
|
||
- `SECURITY DEFINER`:是/否;入口鉴权:是/否;`search_path` 固定:是/否
|
||
- **与项目口径一致性(强制对照 docs/sql/11)**:
|
||
- admin/analytics 是否仅通过 RPC 获取全局数据:是/否
|
||
- **风险点列表**:
|
||
- `等级` + `定位(片段/行号)` + `原因`
|
||
- **整改建议**:
|
||
- 可执行修改建议清单
|
||
- **准入建议**:
|
||
- 是否允许进入 `docs/sql/`:是/否;若否:进入条件
|
||
|
||
---
|
||
|
||
## 9. 与现有 SQL/文档目录的边界(避免双真相)
|
||
|
||
仓库存在多处 SQL/迁移相关目录(如 `mall_sql/`、`doc_mall/`)。必须明确:
|
||
|
||
- **权威策略/权威脚本口径**:以 `docs/sql/` 为准
|
||
- 其他目录若属于迁移脚本仓/历史产物:
|
||
- 必须标注用途(迁移工具、一次性脚本、报告存档)
|
||
- 不允许出现与 `docs/sql/` 并行的“第二份权威定义”
|
||
|
||
---
|
||
|
||
## 10. 操作文档(强制)
|
||
|
||
任何会对项目产生可观察影响的操作,Agent 必须同步编写“操作文档”,将操作过程与结果可描述化、可审计化。
|
||
|
||
### 10.1 何时必须写操作文档
|
||
|
||
- 修改/新增/删除任何代码文件(`.uvue/.uts/.ts/.js/.json/.scss` 等)
|
||
- 修改 `pages.json`、`manifest.json`、`package.json`、`tsconfig.json` 等配置
|
||
- 新增/调整 SQL(包括模块 `test/` 与 `docs/sql` 权威入库)
|
||
- 任何涉及权限/鉴权/RLS/RPC/GRANT 的变更
|
||
|
||
### 10.2 操作文档存放位置(从当前操作目录向上查找)
|
||
|
||
存放规则:从“当前正在操作的目录”开始,逐层向上寻找 `docs/` 目录,直到“当前模块根目录”为止。
|
||
|
||
- 若在某一层找到 `docs/`:将操作文档写入该 `docs/` 下的 `ops/` 子目录。
|
||
- 若一路向上直到模块根目录仍未找到 `docs/`:Agent 必须在模块根目录创建 `docs/ops/` 并写入。
|
||
- 若目标 `docs/ops/` 不存在:Agent 必须创建;若存在则复用。
|
||
|
||
**模块根目录判定**(满足任一即可认为到达模块根):
|
||
|
||
- 存在 `pages.json`(项目根)
|
||
- 或进入了业务模块目录(例如 `pages/mall/analytics/`、`pages/mall/admin/`、`pages/user/`)的顶层
|
||
- 或进入了公共模块目录(例如 `services/`、`components/`、`utils/`、`types/`、`uni_modules/<name>/`)的顶层
|
||
|
||
### 10.3 公共模块 vs 业务模块 的归档规则
|
||
|
||
- **业务模块操作**:文档归档到该业务模块自己的 `docs/ops/`
|
||
- 例:操作发生在 `pages/mall/analytics/...`,则优先归档到 `pages/mall/analytics/docs/ops/`
|
||
- **公共模块操作**:文档归档到对应公共模块自己的 `docs/ops/`
|
||
- 例:操作发生在 `services/...`,则归档到 `services/docs/ops/`
|
||
- 例:操作发生在 `uni_modules/<name>/...`,则归档到 `uni_modules/<name>/docs/ops/`
|
||
|
||
### 10.4 操作文档命名规范
|
||
|
||
- 文件名:`YYYY-MM-DD__<scope>__<short-title>.md`
|
||
- `scope` 建议值:
|
||
- `analytics` / `admin` / `consumer` / `merchant` / `delivery` / `user`
|
||
- `services` / `components` / `utils` / `types` / `uni_modules-<name>`
|
||
|
||
### 10.5 操作文档最小内容模板
|
||
|
||
- **摘要**:做了什么
|
||
- **动机**:为什么要做
|
||
- **影响范围**:涉及哪些模块/页面/接口/权限
|
||
- **变更清单**:
|
||
- 新增文件:...
|
||
- 修改文件:...
|
||
- 删除文件:...
|
||
- **兼容性与风险**:可能的副作用、回滚风险
|
||
- **回滚方案**:如何撤销、恢复到原状态
|
||
- **验证方式**:如何验证改动正确(手工步骤/测试点)
|
||
- **关联文档**:例如 `docs/sql/11_roles_and_permissions_strategy.md` 或对应评审报告
|