# Orbitra 三端统一账号与数据模型

> 目标：PC 官网 / 用户控制台、微信小程序、管理后台 / 代理商后台 **账号统一、权限一致、数据同源**。

## 一、统一账号体系

### 1.1 账号主键

**手机号是唯一账号主键**，三端共用。小程序端通过微信授权拿到 `openid` 后，与手机号账号做**绑定**（而非新建账号），保证同一自然人在任意端登录，看到的是同一家企业、同一份订阅、同一批数据。

| 场景 | 处理方式 |
|------|---------|
| PC 注册 | 手机号 + 密码（无短信验证，密码强度校验 + 加盐哈希） |
| PC 登录 | 手机号 + 密码 |
| 小程序首次进入 | 微信授权 → 引导绑定手机号 → 与既有账号合并 / 新建 |
| 小程序再次进入 | 微信静默授权，自动登录 |
| 后台 / 代理端 | 手机号 + 密码，角色由平台分配 |

### 1.2 角色模型

```
用户（user）              —— 企业内成员，数据范围 = 本企业租户
管理员（admin）           —— 平台运营，数据范围 = 全平台
代理商（agent）           —— 城市合伙人，数据范围 = 名下客户 + 下级代理
```

企业内部的**二级权限**（不改变 account.role）：

| 企业角色 | 权限 |
|---------|------|
| `owner` 所有者 | 全部权限：订阅、计费、成员管理、数据导出 |
| `admin` 管理员 | 岗位、知识库、审核、发布；不可改订阅 |
| `editor` 编辑 | 下命令、编辑草稿、提交审核；不可发布高敏内容 |
| `viewer` 只读 | 只读交付物与效果看板 |

### 1.3 会话与鉴权

- 登录成功签发 `token`（演示环境为 `tk_*`），存于 `localStorage`（键 `orbitra.session.v3`）。
- 生产环境建议：`token` 走 HttpOnly Cookie 或 Authorization Header，配合刷新令牌与设备管理。
- 每个端在进入前做角色校验，角色不匹配自动跳转到对应端（`Orbitra.pageFor(role)`）。

## 二、核心数据模型（对齐 openapi.yaml）

| 实体 | 说明 | 关键字段 |
|------|------|---------|
| `users` | 账号 | `id`、`phone`（唯一）、`password`（摘要）、`salt`、`role`、`status`、`company`、`industry` |
| `agents` | 代理商 | `id`、`user_id`、`code`（推广码）、`region`、`level`、`rate`、`parent_id` |
| `plans` | 套餐 | `id`、`name`、`monthly`、`yearly`、`seats`、`commands/images/videos` 额度、`channels` |
| `subscriptions` | 订阅 | `user_id`、`plan_id`、`cycle`、`started`、`expires`、`status`、`usage`、`agent_id` |
| `orders` | 订单 | `order_no`、`user_id`、`plan_id`、`cycle`、`amount`、`status`、`pay_method`、`agent_id` |
| `positions` | AI 岗位主数据 | `position_code`（如 `G-C01`）、`name`、`domain_code`、`type`（core/extended/industry）、`requires_human_approval`、`status` |
| `enabledPositions` | 企业已装配岗位 | `user_id` → `position_code[]` |
| `members` | 企业子账号 | `user_id`、`name`、`phone`、`role`、`dept`、`status` |
| `deliverables` | 交付物 | `position_code`、`title`、`status`、`effect`（曝光/互动/线索） |

> 完整 DDL 见 `orbitra-contract/db/all_in_one.sql`（41 张表），接口契约见 `orbitra-contract/api/openapi.yaml`。

## 三、三端一致性对照

| 维度 | PC 官网 / 控制台 | 微信小程序 | 管理 / 代理后台 |
|------|------------------|-----------|----------------|
| 账号标识 | 手机号 | 手机号 ↔ openid 绑定 | 手机号 + 角色 |
| 登录 | 手机号 + 密码 | 微信授权 / 手机号 + 密码 | 手机号 + 密码 |
| 角色 | user | user（同企业主体） | admin / agent |
| 数据范围 | 本企业租户 | 本企业租户（同源） | 全平台 / 下级客户 |
| 订阅与额度 | 共享同一订阅记录 | 共享同一订阅记录 | 只读 / 代管 |
| 岗位装配 | 可开关 | 可查看、可开关 | 可配置行业模板 |
| 交付物 | 全量 | 全量（列表 + 详情） | 只读统计 |
| 发布确认 | 支持 | 支持（含服务通知） | — |

## 四、接口复用原则

1. **一套 API 服务三端**：`/api/auth/*`、`/api/subscription`、`/api/positions/*`、`/api/commands`、`/api/deliverables`、`/api/team/*` 三端共用；仅小程序端额外调用微信授权相关接口。
2. **一套组件语义**：岗位卡片、用量条、订单行、状态徽章在三端保持同一数据字段与同一视觉语义（如「试用中」永远是警告色）。
3. **一套错误码**：`PHONE_INVALID` / `PHONE_EXISTS` / `PW_WEAK` / `PW_WRONG` / `DISABLED` 等，三端文案一致。
4. **一套鉴权**：`token` + `role` 决定可见范围，前端只做展示层拦截，**权限判定必须在服务端二次校验**。

## 五、数据隔离（多租户）

| 层级 | 方案 |
|------|------|
| 库级 | 共享库 + `tenant_id`（当前演示方案） |
| 表级 | 关键表带 `tenant_id` 列 + 复合索引，所有查询强制带租户条件 |
| 行级 | 数据库 RLS（Row Level Security）兜底，防止漏写条件导致越权 |
| 存储级 | 对象存储按租户前缀隔离；知识库支持本地建库、仅检索片段上云 |

验收要求：**A 客户无法通过任何接口访问 B 客户数据**（含渗透测试）。
