文档更新

This commit is contained in:
Shen Wei
2026-05-02 11:35:20 +08:00
parent 464c5fce51
commit ca33cc141f
21 changed files with 5906 additions and 2908 deletions

View File

@@ -2,10 +2,10 @@
# Fonrey — Public Schema 数据模型
> **作者**: Backend Architect
> **版本**: v1.5
> **日期**: 2026-04-30
> **版本**: v1.6
> **日期**: 2026-05-02
> **权威源**: 本文件是 `public` schema 所有表的唯一权威定义
> **设计依据**: 系统管理模块 PRD`PRD/系统管理/系统管理模块PRD.md`);客户端发布管理模块 PRD`PRD/发布管理/客户端发布管理模块PRD.md`
> **设计依据**: 平台管理后台 PRD`PRD/平台管理后台/平台管理后台PRD.md`
> **索引文档**: [`DATA_MODEL.md §三`](./DATA_MODEL.md)(仅保留摘要索引,开发以本文件为准)
---
@@ -14,6 +14,7 @@
| 日期 | 变更人 | 变更内容 |
|---|---|---|
| 2026-05-02 | Atlas | 对齐平台管理后台 PRD v1.0`tenants` 增加 License 授权用户数上限字段 `license_user_limit`(含约束、索引、查询示例);`suspended_reason` 增加 `license_expired`;审计动作补充 `UPDATE_LICENSE_USER_LIMIT``AUTO_SUSPEND_LICENSE_EXPIRED``domains` 标注为统一 `tenant=` 路由下的兼容保留;同步更新元信息与版本历史。 |
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
## 一、概览
@@ -53,7 +54,7 @@ PostgreSQL Instance
| 表名 | 说明 | 节 |
|------|------|----|
| `public.tenants` | 租户主表(每家房产公司一条记录) | §2.1 |
| `public.domains` | 域名↔租户映射(多域名支持 | §2.1 |
| `public.domains` | 域名↔租户映射(兼容保留;主路径已切换统一 `tenant=` 参数路由 | §2.1 |
| `public.tenant_status_logs` | 租户状态变更不可变审计日志 | §2.1 |
| `public.platform_admins` | 平台管理员账号3 种角色) | §2.2 |
| `public.admin_mfa_devices` | 管理员 TOTP MFA 设备(强制启用) | §2.2 |
@@ -81,7 +82,7 @@ PostgreSQL Instance
-- ============================================================
-- 文件: shared_schema.sql
-- 用途: django-tenants 公共 Schema存放平台运营层数据
-- 设计依据: 系统管理模块 PRD v1.0
-- 设计依据: 平台管理后台 PRD v1.0
-- ============================================================
-- ────────────────────────────────────────────────────────────
@@ -111,11 +112,13 @@ CREATE TABLE public.tenants (
CHECK (status IN ('creating','active','suspended','pending_delete','deleted','failed')),
suspended_until TIMESTAMPTZ, -- NULL = 永久挂起,非 NULL = Celery Beat 定时恢复
suspended_reason VARCHAR(50)
CHECK (suspended_reason IN ('overdue','violation','requested','other')),
CHECK (suspended_reason IN ('overdue','violation','requested','other','license_expired')),
deleted_at TIMESTAMPTZ, -- 软删除时间戳;硬删除直接物理删除行
-- 订阅
paid_until DATE, -- 订阅到期日
paid_until DATE, -- 订阅到期日License 到期日期)
license_user_limit INTEGER NOT NULL DEFAULT 50
CHECK (license_user_limit > 0), -- License 授权用户数上限(含 Tenant Admin + Agent
on_trial BOOLEAN NOT NULL DEFAULT TRUE,
-- 灰度升级
@@ -139,11 +142,14 @@ CREATE INDEX idx_tenants_suspended_until ON public.tenants(suspended_until)
CREATE INDEX idx_tenants_canary ON public.tenants(is_canary) WHERE is_canary = TRUE;
CREATE INDEX idx_tenants_pending_delete ON public.tenants(deleted_at)
WHERE status = 'pending_delete';
CREATE INDEX idx_tenants_license_user_limit ON public.tenants(license_user_limit);
CREATE INDEX idx_tenants_paid_until_active ON public.tenants(paid_until)
WHERE status = 'active';
-- Feature Flag 租户级覆盖的 GIN 索引(详见 §2.7
-- 同时在 §2.7 中以 ALTER TABLE ADD COLUMN IF NOT EXISTS 兜底,便于按模块独立部署
CREATE INDEX idx_tenants_feature_flags_gin ON public.tenants USING gin (feature_flags);
-- 域名映射表(支持多域名绑定一个租户,子域名创建后不可修改)
-- 域名映射表(兼容保留:主路径已切换统一 `tenant=` 参数路由;子域名创建后不可修改)
CREATE TABLE public.domains (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
domain VARCHAR(253) UNIQUE NOT NULL, -- 含子域名的完整域名(如 abc.platform.com
@@ -257,6 +263,7 @@ CREATE TABLE public.platform_audit_logs (
operator_name VARCHAR(100), -- 快照(防止账号删除后失去溯源)
action_type VARCHAR(50) NOT NULL,
-- CREATE_TENANT | SUSPEND_TENANT | RESUME_TENANT | DELETE_TENANT | HARD_DELETE_TENANT
-- UPDATE_LICENSE | UPDATE_LICENSE_USER_LIMIT | AUTO_SUSPEND_LICENSE_EXPIRED
-- RESTORE_DATA | TRIGGER_BACKUP | SYSTEM_UPGRADE | ROLLBACK
-- RESET_PASSWORD | CREATE_ADMIN | DEACTIVATE_ADMIN | FORCE_LOGOUT
-- UPDATE_IP_WHITELIST | UPDATE_BACKUP_SCHEDULE | EXPORT_DATA | ...
@@ -709,7 +716,7 @@ CREATE INDEX idx_ff_log_operator ON public.feature_flag_change_log(operator_id,
| `tenant_status_logs` append-only | 禁止 UPDATE / DELETE状态机变更只追加新行 |
| `platform_audit_logs` append-only | 禁止 UPDATE / DELETE建议按月 RANGE 分区 |
| `public.tenants.schema_name` 不可修改 | 创建后禁止 UPDATEPG schema 绑定 |
| `public.domains.domain` 不可修改 | 子域名创建后禁止 UPDATE |
| `public.domains.domain` 不可修改(兼容保留) | `tenant=` 统一路由方案下,`domains` 仅用于历史兼容与迁移窗口;子域名创建后禁止 UPDATE |
| `system_versions` 唯一 current | `idx_system_versions_current` 部分唯一索引保证全局只有一个 `status='current'` |
| `backup_schedules.tenant_id` UNIQUE | 每个租户最多一条独立计划;`NULL` 全局计划由应用层保证唯一 |
| `platform_admins``staff` 完全独立 | 不共享表、不共享 auth 系统 |
@@ -801,16 +808,25 @@ draft ──提交──► pre_check ──健康检查通过──► pre_back
```sql
-- 查询所有活跃租户
SELECT id, name, plan, paid_until
SELECT id, name, plan, paid_until, license_user_limit
FROM public.tenants
WHERE status = 'active'
ORDER BY created_at DESC;
-- 查询即将到期的租户(7 天内)
SELECT id, name, contact_email, paid_until
-- 查询即将到期的租户(15 天内,对齐平台管理后台 PRD
SELECT id, name, contact_email, paid_until, license_user_limit
FROM public.tenants
WHERE status = 'active'
AND paid_until BETWEEN CURRENT_DATE AND CURRENT_DATE + 7;
AND paid_until BETWEEN CURRENT_DATE AND CURRENT_DATE + 15;
-- 查询“用户数已满/超限”的租户(供运营筛选)
-- current_user_count 由租户侧聚合任务回填至统计视图或物化视图,此处示例为联表查询形态
SELECT t.id, t.name, t.tenant_code, t.license_user_limit, u.current_user_count
FROM public.tenants t
JOIN public.v_tenant_user_counts u ON u.tenant_id = t.id
WHERE t.status = 'active'
AND u.current_user_count >= t.license_user_limit
ORDER BY u.current_user_count DESC, t.created_at DESC;
-- 查询灰度租户canary 升级目标)
SELECT id, schema_name, name
@@ -1009,7 +1025,7 @@ ORDER BY created_at DESC;
| `DELETE FROM public.platform_audit_logs` | append-only 审计表 |
| `UPDATE public.tenants SET schema_name = ...` | schema 名绑定 PG 物理 schema |
| `UPDATE public.tenants SET tenant_code = ...` | 12 位识别码一旦发放给用户不可更改,避免经纪人无法登录 |
| `UPDATE public.domains SET domain = ...` | 域名路由不可变 |
| `UPDATE public.domains SET domain = ...` | 域名路由不可变`domains` 为兼容保留表,主路径使用 `tenant=` 参数) |
| `UPDATE public.client_releases SET version = ...` | 版本号创建后不可修改,变更须新建记录 |
| 在租户 schema 中创建 `client_releases` 副本 | 本表属于 public schema多租户共享禁止下沉到租户层 |
| `UPDATE public.feature_flag_change_log` / `DELETE FROM ...` | append-only 审计表 |
@@ -1030,3 +1046,4 @@ ORDER BY created_at DESC;
| v1.3 | 2026-04-30 | 配合登录管理 PRD v2.0 / 系统管理 PRD§2.1 `tenants` 新增 `tenant_code` (CHAR(12), 全局唯一对外识别码) 与 `contact_phone` (CHAR(11)Tenant Admin 账号创建数据来源)`contact_email` 改为可 NULL同步更新约束、查询模式 |
| v1.4 | 2026-04-30 | 配合客户端发布管理 PRD v1.1 §5.5 Story 5§2.6 新增 `client_heartbeats` 表(启动时 Upsert by `tenant_id + device_id`,活跃定义为最近 24h 内心跳);同步更新表清单、§三 约束Upsert 锚点 / 启动上报 / 不可下沉到租户 schema、§5.1 查询模式Upsert 模板 + 版本活跃分布 JOIN + 平台总活跃数 + 租户维度排查MVP 不做升级趋势图v2 规划) |
| v1.5 | 2026-04-30 | 配合客户端发布管理 PRD v1.2 §5.5 Story 5 验收标准追加(按租户统计安装数):① §2.6 `client_heartbeats.tenant_id` 注释强化,明确为"按租户统计安装数 / 活跃数 / 版本分布"的核心维度字段;② §5.1 新增"租户维度安装/活跃统计"查询专区4 个查询:某租户活跃安装数 / 历史装机总数 / 租户内版本分布 / 全平台租户活跃榜) |
| v1.6 | 2026-05-02 | 对齐平台管理后台 PRD v1.0:① `tenants` 增加 `license_user_limit``INTEGER NOT NULL DEFAULT 50 CHECK (>0)`)并新增 `idx_tenants_license_user_limit`;② `suspended_reason` 增加 `license_expired` 枚举;③ 新增 `idx_tenants_paid_until_active` 并将“即将到期”查询窗口由 7 天调整为 15 天;④ 新增“用户数已满/超限”查询示例(`v_tenant_user_counts` 联表);⑤ 审计动作补充 `UPDATE_LICENSE_USER_LIMIT``AUTO_SUSPEND_LICENSE_EXPIRED`;⑥ `domains` 标记为统一 `tenant=` 路由下的兼容保留。 |