feat(api): 开发auth、login等接口,规范格式化

This commit is contained in:
R524809
2026-09-03 13:11:06 +08:00
parent 195b6d25e9
commit 037928c778
82 changed files with 9199 additions and 5236 deletions
+4
View File
@@ -2,6 +2,10 @@
> 状态:第一批可评审契约。本文档描述预期的 NestJS HTTP API,不代表接口已经实现。接口统一以前缀 `/api` 提供,JSON 字段使用 `snake_case`,时间使用 ISO 8601 UTC 字符串,ID 使用 UUID。
API 启动后会在 `/api-docs` 提供 Swagger UI,并在其 OpenAPI 文档中标记已实现的接口。Swagger 是运行时参考,不替代本目录的冻结契约。
运行状态端点不使用 `/api` 前缀:`GET /health` 只表明进程存活,`GET /ready` 会校验应用数据库连接,失败时返回 `503`。生产环境由环境变量控制 API 端口、CORS 来源、日志级别、请求体上限、认证限流及可信反向代理列表;缺少或格式错误的必需安全配置会阻止 API 启动。
## 1. 文档路线
| 文档 | 状态 | 范围 |
+19
View File
@@ -29,6 +29,25 @@ X-Atlas-Platform-Id: 57ad…-uuid
## 3. 响应、分页和字段格式
### 3.1 强制响应信封
本项目不采用完整 JSON:API 规范,但所有业务 HTTP 接口必须使用以下响应信封;这是
前端、服务端、Worker 和扩展共同遵守的强制契约:
| 场景 | HTTP 响应体 |
|---|---|
| 成功的单资源或同步动作 | `{ "data": T }` |
| 成功的列表 | `{ "data": T[], "meta": PaginationMeta }` |
| 失败 | `{ "error": ApiError }` |
| `204 No Content` | 无响应体 |
`data` 只能位于顶层且只能出现一次;不得返回 `{ "data": { "data": ... } }`,也不得以
`{ "data": null }` 表示失败。HTTP 状态码仍表达请求结果,错误必须使用本文件第 4 节的
`error` 信封,不能混入成功响应。`meta` 只承载分页、游标或与整个响应相关的元信息,不能
替代资源字段。
### 3.2 成功与列表响应
成功响应统一为:
```json
+18 -1
View File
@@ -12,6 +12,22 @@
`atlas_app_login` 和 `atlas_app` 都必须是 `NOBYPASSRLS`,也不能是 PostgreSQL 超级用户。生产环境不得把 `atlas_migrator` 的连接串写入 API 或 Worker 的环境变量。
### 角色链与请求上下文
三层角色链是固定的,不能简化为“应用直接使用迁移账号”:
```text
atlas_migrator ──拥有──> atlas schema 与业务表
atlas_app_login ──登录身份,NOINHERIT──> SET LOCAL ROLE atlas_app
atlas_app ──无登录权限组──────────> 最小 DML 与序列权限
```
API 和 Worker 只以 `atlas_app_login` 建立连接。每笔业务事务必须先执行
`SET LOCAL ROLE atlas_app`,再设置 `SET LOCAL app.workspace_id`。前者收窄为
应用所需的最小数据库权限,后者为 RLS 策略提供当前工作空间上下文;任何一步缺失,
都不应使跨工作空间数据变得可见。
## 2. 一次性数据库初始化
以下由云数据库管理员或基础设施脚本执行;它不属于 NestJS 的业务 migration,因为托管 PostgreSQL 常不允许应用账户创建角色。密码应从密钥管理服务注入,示例中不填写真实密码。
@@ -22,6 +38,7 @@ CREATE ROLE atlas_app NOLOGIN NOINHERIT NOBYPASSRLS;
CREATE ROLE atlas_app_login LOGIN NOINHERIT NOBYPASSRLS PASSWORD '<managed-secret>';
GRANT atlas_app TO atlas_app_login;
GRANT CREATE ON DATABASE atlas TO atlas_migrator;
CREATE SCHEMA IF NOT EXISTS atlas AUTHORIZATION atlas_migrator;
GRANT USAGE ON SCHEMA atlas TO atlas_app;
@@ -34,7 +51,7 @@ ALTER DEFAULT PRIVILEGES FOR ROLE atlas_migrator IN SCHEMA atlas
GRANT USAGE, SELECT ON SEQUENCES TO atlas_app;
```
首次 DDL 与后续 migration 都以 `atlas_migrator` 执行,确保新表的所有者一致。若云服务统一由管理员创建 schema,可将 `atlas_migrator` 设为 schema/表所有者或由管理员代为执行 migration;无论哪种方式,应用登录角色都不得成为表所有者。
首次 DDL 与后续 migration 都以 `atlas_migrator` 执行,确保新表的所有者一致。迁移角色拥有数据库级 `CREATE` 的唯一目的,是创建其拥有的 `atlas` schema;它不授予 API 或 Worker 任何额外权限。若云服务统一由管理员创建 schema,可将 `atlas_migrator` 设为 schema/表所有者或由管理员代为执行 migration;无论哪种方式,应用登录角色都不得成为表所有者。
## 3. RLS 的运行方式
+1
View File
@@ -86,6 +86,7 @@ User → Workspace → Membership / Role
- 覆盖账户认证、平台/门店、水印与素材、定价、浏览器采集/采集箱、商品编辑/首次发布、在线商品读取与同步。
- 所有接口遵循统一鉴权、工作空间隔离、页头平台上下文、金额字符串、错误格式、`Idempotency-Key`、`If-Match` 和异步 `operation` 约定。
- **响应信封是强制契约:** 成功单资源或同步动作返回 `{ "data": T }`,列表返回 `{ "data": T[], "meta": PaginationMeta }`,失败返回 `{ "error": ApiError }`,`204 No Content` 不返回响应体。项目不采用完整 JSON:API;任何调用方不得自行增加嵌套 `data` 或以 `data: null` 表示错误。完整规则见 [`api/conventions.md`](../api/conventions.md)。
- 关键异步动作必须在同一事务写入业务记录、`operations`(如需用户可见进度)和 `outbox_events`;Dispatcher 至少一次投递 BullMQ,Worker 必须幂等。
- DDL 已通过临时隔离 PostgreSQL 实例执行验证;API 契约已完成文档评审。这不表示 NestJS 模块、迁移执行器或 Worker 已实现。