# members 表字段设计 > 数据模型新增表之一:成员实体——「成员」维度的锚点。key 归属(经 `api_keys.member_id` 指向本表)、成员视图的身份、按成员统计的分组键。裁决背景见 `docs/design/需求清单.md` §9「访问主体模型」。 | 项目 | 内容 | |------|------| | 状态 | 定稿(2026-10-01) | | 关联 | `docs/design/api_keys表字段设计.md` 3.9(归属列指向本表)· `docs/design/需求清单.md` §9 | | 范围 | 列结构 + 语义 + 写入时机;令牌生成细节归技术稿;方言映射归数据访问层设计 | | 字段数 | 7 = 1 主键 + 6 业务字段 | --- ## 1. 表定位 - **一行 = 一个分摊成员** - 三个角色:`api_keys.member_id` 的归属目标;成员视图的访问主体(令牌校验命中本表行 + `status = active`);按成员统计的分组键 - 数据规模:个位数行 ## 2. 字段清单 | 列 | 类型 | 值来源 | 说明 | |----|------|--------|------| | `id` | bigserial PK | 自增 | | | `name` | text UNIQUE | 管理面录入 | 显示名——账目与视图中的署名 | | `remark` | text | 管理面录入 | 备注(联系方式、是谁等;可空) | | `status` | text | 管理面 | `active` / `disabled`——停用即成员视图访问立即失效(令牌校验含状态判断) | | `token_hash` | text | 管理面生成令牌时 | 成员视图的访问凭证(哈希存储,明文只在生成时展示一次) | | `token_issued_at` | timestamptz | 同上 | 当前令牌的签发时间(审计线索) | | `created_at` | timestamptz | 开户时 | | ## 3. 决策记录(含理由) ### 3.1 令牌哈希存储 拖库不泄令牌(与 `api_keys.key_hash` 同思路);副作用是明文不可找回——丢了只能重发(`token_hash` + `token_issued_at` 一起更新),这正是「凭证事务经作者」的裁决语义。 ### 3.2 令牌不过期(无 `token_expires_at`),且与 `sessions` 无关 - 令牌是**长期访问凭证**(access token,近 GitHub PAT 形态),不是「登录令牌」:没有会话语义——不过期、无登出、无「验证持久身份 → 换发短时会话」的过程,吊销与重发是唯一的生命周期操作,均经作者(管理面) - **与 `sessions` 表零关系**:sessions 服务于管理面(作者)的登录体系(密码验证 → 短时会话);本表令牌是成员链路唯一的凭证,成员请求直接携带、服务端直查本表(`token_hash` + `status`)——两条链路各自独立、物理隔离 - 成员低频只读,过期只会制造无意义的重发摩擦 ### 3.3 `name` UNIQUE 账目署名不可歧义。 ### 3.4 软删除(`status`)而非物理删除 成员名下的 key 与历史用量是账本的一部分——「退拼」是停用(保留行、停访问),不是抹掉事实。 ## 4. 写入时机 | 时机 | 动作 | |------|------| | 开户(管理面) | INSERT(`name` / `remark`;生成令牌 → `token_hash` + `token_issued_at`) | | 停用 / 启用 | UPDATE `status` | | 重发令牌 | UPDATE `token_hash` + `token_issued_at`(旧令牌即失效) | 以上全部为管理面写操作,均落**审计日志**(审计为独立需求,表结构归技术稿)。 ## 5. 待定事项 | 事项 | 归属 | |------|------| | 令牌生成的随机源与长度(256bit 起步) | 技术稿 | | 审计日志表结构 | 技术稿 |