添加变更历史 添加ARD文档
This commit is contained in:
@@ -2,13 +2,20 @@
|
||||
# Fonrey 房产经纪管理系统 — DATA MODEL 设计文档
|
||||
|
||||
> **作者**: Backend Architect
|
||||
> **版本**: v1.4
|
||||
> **日期**: 2026-04-24(v1.1 修复 S1/S2/S4;v1.2 扩展 public schema;v1.3 §三 DDL 迁至 DATA_MODEL_PUBLIC.md,本文改为索引;v1.4 补充 LOGIN/PERMISSION 子文档引用、领域对象、租户 Schema 章节、Redis 缓存策略)
|
||||
> **版本**: v1.5
|
||||
> **日期**: 2026-04-30(v1.1 修复 S1/S2/S4;v1.2 扩展 public schema;v1.3 §三 DDL 迁至 DATA_MODEL_PUBLIC.md,本文改为索引;v1.4 补充 LOGIN/PERMISSION 子文档引用、领域对象、租户 Schema 章节、Redis 缓存策略;v1.5 新增 ADR 导航与治理联动)
|
||||
> **技术栈**: Django 4.x + PostgreSQL + django-tenants + Redis
|
||||
> **设计目标**: 支撑 89,000+ 房源、多租户隔离、sub-100ms 查询、合规审计
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 新增 ADR 导航与治理联动规则(数据模型变更需 ADR 可追溯) |
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、架构决策总览 (Architecture Decision Records)
|
||||
|
||||
### 1.1 多租户策略:Schema-per-Tenant
|
||||
@@ -157,6 +164,7 @@ OrgUnit (组织架构)
|
||||
| [DATA_MODEL_LOGIN.md](./DATA_MODEL_LOGIN.md) | 登录与账号认证(user_accounts, login_attempts, password_reset_tokens, password_histories + Redis 登录缓存) | ✅ 完成 |
|
||||
| [DATA_MODEL_PERMISSION.md](./DATA_MODEL_PERMISSION.md) | 权限管理(permission_defs, roles, role_permissions, staff_roles, staff_permission_overrides, staff_data_scopes, permission_change_logs + Redis 权限缓存) | ✅ 完成 |
|
||||
| [ENUMS.md](./ENUMS.md) | 枚举字典(`public.enum_labels` 表设计 + 所有模块枚举定义 + 种子数据 SQL) | ✅ 完成 |
|
||||
| [ADR.md](../ADR.md) | 架构与需求决策记录(按日期/按模块/历史流水,append-only) | ✅ 完成 |
|
||||
|
||||
---
|
||||
|
||||
@@ -833,7 +841,14 @@ app.conf.beat_schedule["partition_maintenance_task"] = {
|
||||
| 跟进目的枚举 | 存 lookup_items 表,运营可维护 | 初始化数据需提前收集 |
|
||||
| 手机号加密算法 | AES-256-GCM,密钥存 Django settings(生产用 Vault) | 密钥管理需单独规划 |
|
||||
|
||||
## 十、文档治理与 ADR 联动规则
|
||||
|
||||
- 任何会影响数据模型边界的变更(新增/删除表、关键约束变更、索引策略调整、枚举口径变更)必须先在 `ADR.md` 记录为 `accepted`,再修改本文件与子文档。
|
||||
- 若既有数据决策被替代,必须在 `ADR.md` 增加 `superseded` 记录并指向新 ADR,禁止直接覆盖旧结论。
|
||||
- 提交 PR 时,凡涉及 `DATA_MODEL/*` 结构性变更,PR 描述必须包含 ADR ID(格式:`ADR-YYYYMMDD-XXX`)。
|
||||
- `DATA_MODEL.md` 只维护全局索引与规则;表级 DDL 以各子文档为权威源,避免双写漂移。
|
||||
|
||||
---
|
||||
|
||||
*本文档为 Fonrey 系统 DATA MODEL v1.0,随 PRD 迭代同步更新。*
|
||||
*本文档为 Fonrey 系统 DATA MODEL v1.5,随 PRD 与 ADR 迭代同步更新。*
|
||||
*下一步建议:API 接口规范(URL 设计 + Request/Response Schema)*
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 核心概念
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 核心概念
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 核心概念
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 核心概念
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 1.1 核心概念
|
||||
|
||||
@@ -1,45 +1,20 @@
|
||||
> **For AI assistants**: Read this entire file before writing any code. All decisions here are final. Do not suggest alternatives unless asked.
|
||||
# Fonrey — 房源模块数据模型(DATA_MODEL_PROPERTY)
|
||||
|
||||
> **权威定义**:本文件是房源模块所有表结构的唯一权威来源。
|
||||
> **所属系统**: Fonrey 房产经纪管理系统
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-04-24
|
||||
> **关联模块**: `apps/property/`
|
||||
> **主文档引用**:`DATA_MODEL.md` §3.3–§3.16 为本文件的概览摘要,开发以本文件为准。
|
||||
> **版本**:v1.0 | **日期**:2026-04-24
|
||||
|
||||
---
|
||||
## 变更历史
|
||||
|
||||
## 目录
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
| ---------- | ----- | ---------------- |
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
1. [模块说明](#1-模块说明)
|
||||
2. [表清单](#2-表清单)
|
||||
3. [枚举值总览](#3-枚举值总览)
|
||||
4. [DDL 定义](#4-ddl-定义)
|
||||
- 4.1 [properties(房源主表)](#41-properties房源主表)
|
||||
- 4.2 [property_contacts(联系人)](#42-property_contacts联系人)
|
||||
- 4.3 [listing_histories(挂牌历史)](#43-listing_histories挂牌历史)
|
||||
- 4.4 [price_changes(调价记录)](#44-price_changes调价记录)
|
||||
- 4.5 [follow_logs(跟进日志)](#45-follow_logs跟进日志)
|
||||
- 4.6 [follow_log_attachments(跟进附件)](#46-follow_log_attachments跟进附件)
|
||||
- 4.7 [follow_log_recordings(跟进录音)](#47-follow_log_recordings跟进录音)
|
||||
- 4.8 [property_keys(钥匙管理)](#48-property_keys钥匙管理)
|
||||
- 4.9 [key_attachments(钥匙附件)](#49-key_attachments钥匙附件)
|
||||
- 4.10 [commissions(委托管理)](#410-commissions委托管理)
|
||||
- 4.11 [commission_attachments(委托附件)](#411-commission_attachments委托附件)
|
||||
- 4.12 [field_surveys(实勘管理)](#412-field_surveys实勘管理)
|
||||
- 4.13 [survey_photos(实勘照片)](#413-survey_photos实勘照片)
|
||||
- 4.14 [property_photos(房源图片)](#414-property_photos房源图片)
|
||||
- 4.15 [property_attachments(房源附件)](#415-property_attachments房源附件)
|
||||
- 4.16 [property_marketing(营销信息)](#416-property_marketing营销信息)
|
||||
- 4.17 [property_certificates(产证信息)](#417-property_certificates产证信息)
|
||||
- 4.18 [property_completeness(维护完成度)](#418-property_completeness维护完成度)
|
||||
- 4.19 [property_tags / property_tag_relations(标签)](#419-property_tags--property_tag_relations标签)
|
||||
- 4.20 [property_favorites(收藏)](#420-property_favorites收藏)
|
||||
- 4.21 [property_protections(保护房)](#421-property_protections保护房)
|
||||
- 4.22 [number_holder_approvals(号码方审批)](#422-number_holder_approvals号码方审批)
|
||||
5. [触发器](#5-触发器)
|
||||
6. [查询模式参考](#6-查询模式参考)
|
||||
7. [禁止操作](#7-禁止操作)
|
||||
|
||||
---
|
||||
|
||||
## 1 模块说明
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Fonrey — Public Schema 数据模型
|
||||
|
||||
> **作者**: Backend Architect
|
||||
> **版本**: v1.3
|
||||
> **版本**: v1.5
|
||||
> **日期**: 2026-04-30
|
||||
> **权威源**: 本文件是 `public` schema 所有表的唯一权威定义
|
||||
> **设计依据**: 系统管理模块 PRD(`PRD/系统管理/系统管理模块PRD.md`);客户端发布管理模块 PRD(`PRD/发布管理/客户端发布管理模块PRD.md`)
|
||||
@@ -10,6 +10,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、概览
|
||||
|
||||
`public` schema 存储**平台运营层**数据,与各租户的业务 schema 完全隔离。
|
||||
@@ -34,6 +40,7 @@ PostgreSQL Instance
|
||||
│ ├── system_versions 版本历史
|
||||
│ ├── upgrade_events 升级事件(A/B/C 分级 + B 类分批编排)
|
||||
│ ├── client_releases 客户端版本发布
|
||||
│ ├── client_heartbeats 客户端启动心跳(活跃统计 + 版本分布)
|
||||
│ ├── feature_flag_definitions Feature Flag 定义(C 类灰度控制平面)
|
||||
│ └── feature_flag_change_log Feature Flag 变更历史(append-only)
|
||||
│
|
||||
@@ -59,6 +66,7 @@ PostgreSQL Instance
|
||||
| `public.system_versions` | 平台版本历史,唯一 current 约束 | §2.5 |
|
||||
| `public.upgrade_events` | 升级/回滚事件,A/B/C 升级类型分级,B 类按租户分批编排 + 健康门控 | §2.5 |
|
||||
| `public.client_releases` | Windows 客户端发布版本,含安装包 URL、SHA256、强制更新标记 | §2.6 |
|
||||
| `public.client_heartbeats` | 客户端启动心跳(活跃统计 + 版本分布支撑) | §2.6 |
|
||||
| `public.feature_flag_definitions` | Feature Flag 全局定义(C 类运行时灰度控制平面) | §2.7 |
|
||||
| `public.tenants.feature_flags` | 租户级 Flag 显式覆盖(`tenants` 表新增 JSONB 列) | §2.7 |
|
||||
| `public.feature_flag_change_log` | Feature Flag 变更历史(append-only) | §2.7 |
|
||||
@@ -538,6 +546,72 @@ CREATE INDEX idx_client_releases_status ON public.client_releases(status, create
|
||||
|
||||
-- 按版本号快速定位(客户端更新检测时传入 current_version 查询)
|
||||
CREATE INDEX idx_client_releases_version ON public.client_releases(version);
|
||||
|
||||
-- ────────────────────────────────────────────────────────────
|
||||
-- 客户端启动心跳表(活跃统计 + 版本分布数据支撑)
|
||||
-- ────────────────────────────────────────────────────────────
|
||||
-- 设计依据: 客户端发布管理模块 PRD §5.5 Story 5(客户端版本分布查询)
|
||||
-- 上报模型: 客户端 App 每次启动时 Upsert 一条记录(by tenant_id + device_id)
|
||||
-- 归属说明: 本表属于 shared_apps(public schema)。虽然 tenant_id 字段做了租户归属,
|
||||
-- 但 device_id 由客户端首次安装时生成(本机 UUID),跨租户全局唯一管理;
|
||||
-- 将本表放在 public schema 便于平台运营做全量版本分布、活跃数统计,
|
||||
-- 避免跨所有 tenant schema 做 UNION ALL。
|
||||
-- 隐私说明: 不收集任何业务数据,仅用于平台运营版本管理与升级决策。
|
||||
|
||||
CREATE TABLE public.client_heartbeats (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
|
||||
-- 归属
|
||||
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
||||
-- 心跳上报时所属租户(由客户端登录态决定,从 Tenant Code 解析得到);
|
||||
-- 是"按租户统计安装数 / 活跃数 / 版本分布"的核心维度字段,
|
||||
-- 配合 idx_client_heartbeats_tenant_lastseen 索引支撑租户维度聚合查询;
|
||||
-- 租户被硬删除时心跳一并清理(CASCADE);
|
||||
-- 同一物理设备登录不同租户视作多条独立记录(Upsert 锚点为 (tenant_id, device_id))
|
||||
device_id UUID NOT NULL,
|
||||
-- 客户端首次安装时本机生成并持久化的设备 UUID;
|
||||
-- 卸载重装会变化(视作新设备);同一设备换租户登录视作不同记录
|
||||
user_id UUID,
|
||||
-- 上次启动时登录的用户 ID(指向 tenant schema 的 staff.id);
|
||||
-- 不加外键约束(跨 schema 无法外键),仅作排查辅助;
|
||||
-- 未登录或退出后启动允许为 NULL
|
||||
|
||||
-- 版本与环境
|
||||
client_version VARCHAR(20) NOT NULL,
|
||||
-- 上报时客户端 SemVer 版本号,如 '1.2.3'
|
||||
platform VARCHAR(20) NOT NULL DEFAULT 'win32'
|
||||
CHECK (platform IN ('win32')),
|
||||
arch VARCHAR(10) NOT NULL DEFAULT 'x64'
|
||||
CHECK (arch IN ('x64', 'arm64')),
|
||||
os_version VARCHAR(80),
|
||||
-- 操作系统版本字符串,如 'Windows 10 22H2';可选
|
||||
|
||||
-- 时间戳
|
||||
first_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
-- 该 (tenant_id, device_id) 组合首次心跳时间,Upsert 时不更新
|
||||
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
-- 最近一次启动心跳时间,Upsert 时刷新为 NOW()
|
||||
launch_count INTEGER NOT NULL DEFAULT 1,
|
||||
-- 累计启动次数,Upsert 时 +1,用于排查异常高频启动
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- 同一租户下同一设备唯一一条记录(Upsert 锚点)
|
||||
CONSTRAINT uq_client_heartbeats_tenant_device UNIQUE (tenant_id, device_id)
|
||||
);
|
||||
|
||||
-- 活跃数统计("最近 24h 内有心跳")核心索引
|
||||
CREATE INDEX idx_client_heartbeats_last_seen
|
||||
ON public.client_heartbeats(last_seen_at DESC);
|
||||
|
||||
-- 版本分布统计:按版本聚合活跃设备数
|
||||
CREATE INDEX idx_client_heartbeats_version_lastseen
|
||||
ON public.client_heartbeats(client_version, last_seen_at DESC);
|
||||
|
||||
-- 租户维度排查:某租户下所有活跃设备
|
||||
CREATE INDEX idx_client_heartbeats_tenant_lastseen
|
||||
ON public.client_heartbeats(tenant_id, last_seen_at DESC);
|
||||
```
|
||||
|
||||
### 2.7 Feature Flag 灰度体系
|
||||
@@ -644,6 +718,9 @@ CREATE INDEX idx_ff_log_operator ON public.feature_flag_change_log(operator_id,
|
||||
| `client_releases` 唯一 published | `idx_client_releases_published` 部分唯一索引保证同平台+架构下只有一条 `status='published'` |
|
||||
| `client_releases` 不可跨租户隔离 | 本表属于 public schema,所有租户共享;禁止在租户 schema 中创建副本 |
|
||||
| `client_releases.download_count` 原子递增 | 必须使用 `UPDATE ... SET download_count = download_count + 1`,禁止先读后写 |
|
||||
| `client_heartbeats` Upsert 锚点 | 必须使用 `INSERT ... ON CONFLICT (tenant_id, device_id) DO UPDATE SET last_seen_at=NOW(), launch_count=client_heartbeats.launch_count+1, client_version=EXCLUDED.client_version`;禁止先 SELECT 再 INSERT |
|
||||
| `client_heartbeats` 仅启动时上报 | 客户端 App 仅在每次启动时上报一次心跳;不做 4h 周期心跳,避免 public schema 写入压力 |
|
||||
| `client_heartbeats` 不可跨租户隔离 | 本表属于 public schema,所有租户共享;禁止在租户 schema 中创建副本 |
|
||||
| `upgrade_events.gray_tenant_ids` 与 `upgrade_type` 一致性 | A_app 类型必须为空数组(CHECK 约束 `chk_app_upgrade_no_gray` 强制);只有 B_schema 类型才使用灰度名单与批次字段 |
|
||||
| `upgrade_events` 状态流转单向 | 状态机详见 §4.2;`succeeded` / `rolled_back` / `failed` 为终态,禁止再写回中间态 |
|
||||
| `feature_flag_change_log` append-only | 禁止 UPDATE / DELETE;任何 Flag 变更都必须经此表追溯,含 `reason` 强制非空 |
|
||||
@@ -782,11 +859,83 @@ SELECT version, platform, arch, release_type, status,
|
||||
FROM public.client_releases
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- 统计各版本活跃客户端数(需结合客户端上报心跳表,当前仅记录下载量)
|
||||
SELECT version, download_count
|
||||
FROM public.client_releases
|
||||
WHERE status IN ('published', 'archived')
|
||||
ORDER BY published_at DESC;
|
||||
-- 客户端启动心跳 Upsert(每次启动调用,原子更新最后活跃时间与启动次数)
|
||||
INSERT INTO public.client_heartbeats (
|
||||
tenant_id, device_id, user_id,
|
||||
client_version, platform, arch, os_version,
|
||||
first_seen_at, last_seen_at, launch_count
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW(), 1)
|
||||
ON CONFLICT (tenant_id, device_id) DO UPDATE
|
||||
SET last_seen_at = NOW(),
|
||||
launch_count = public.client_heartbeats.launch_count + 1,
|
||||
client_version = EXCLUDED.client_version,
|
||||
user_id = EXCLUDED.user_id,
|
||||
os_version = EXCLUDED.os_version,
|
||||
updated_at = NOW();
|
||||
|
||||
-- 统计各版本活跃客户端数(活跃 = 最近 24h 内有心跳)
|
||||
SELECT cr.version,
|
||||
cr.status,
|
||||
cr.download_count,
|
||||
COUNT(ch.id) FILTER (
|
||||
WHERE ch.last_seen_at >= NOW() - INTERVAL '24 hours'
|
||||
) AS active_devices_24h,
|
||||
COUNT(ch.id) AS total_devices_ever
|
||||
FROM public.client_releases cr
|
||||
LEFT JOIN public.client_heartbeats ch ON ch.client_version = cr.version
|
||||
WHERE cr.status IN ('published', 'archived')
|
||||
GROUP BY cr.version, cr.status, cr.download_count, cr.published_at
|
||||
ORDER BY cr.published_at DESC;
|
||||
|
||||
-- 平台总活跃数(最近 24h)
|
||||
SELECT COUNT(*) AS active_devices_24h
|
||||
FROM public.client_heartbeats
|
||||
WHERE last_seen_at >= NOW() - INTERVAL '24 hours';
|
||||
|
||||
-- 某租户下活跃设备列表(运营排查)
|
||||
SELECT device_id, client_version, user_id, last_seen_at, launch_count
|
||||
FROM public.client_heartbeats
|
||||
WHERE tenant_id = $1
|
||||
AND last_seen_at >= NOW() - INTERVAL '24 hours'
|
||||
ORDER BY last_seen_at DESC;
|
||||
|
||||
-- ============================================================
|
||||
-- 租户维度安装/活跃统计(Platform Admin 运营看板)
|
||||
-- ============================================================
|
||||
|
||||
-- 某租户当前活跃安装数(最近 24h 内启动过的设备)
|
||||
SELECT COUNT(*) AS active_installs_24h
|
||||
FROM public.client_heartbeats
|
||||
WHERE tenant_id = $1
|
||||
AND last_seen_at >= NOW() - INTERVAL '24 hours';
|
||||
|
||||
-- 某租户历史装机总数(不区分是否活跃,含已离线设备)
|
||||
SELECT COUNT(*) AS total_installs_ever
|
||||
FROM public.client_heartbeats
|
||||
WHERE tenant_id = $1;
|
||||
|
||||
-- 某租户内部各版本分布(识别该租户内升级覆盖率)
|
||||
SELECT client_version,
|
||||
COUNT(*) FILTER (WHERE last_seen_at >= NOW() - INTERVAL '24 hours') AS active_devices_24h,
|
||||
COUNT(*) AS total_devices_ever
|
||||
FROM public.client_heartbeats
|
||||
WHERE tenant_id = $1
|
||||
GROUP BY client_version
|
||||
ORDER BY active_devices_24h DESC;
|
||||
|
||||
-- 全平台租户活跃榜(PRD §5.5 Story 5:按租户维度查看版本分布,识别落后租户)
|
||||
SELECT t.tenant_code,
|
||||
t.name,
|
||||
COUNT(h.id) FILTER (
|
||||
WHERE h.last_seen_at >= NOW() - INTERVAL '24 hours'
|
||||
) AS active_installs_24h,
|
||||
COUNT(h.id) AS total_installs_ever
|
||||
FROM public.tenants t
|
||||
LEFT JOIN public.client_heartbeats h ON h.tenant_id = t.id
|
||||
WHERE t.status = 'active'
|
||||
GROUP BY t.id, t.tenant_code, t.name
|
||||
ORDER BY active_installs_24h DESC;
|
||||
|
||||
-- ============================================================
|
||||
-- 升级编排相关查询(B 类 Schema 迁移分批升级)
|
||||
@@ -878,3 +1027,6 @@ ORDER BY created_at DESC;
|
||||
| v1.0 | 2026-04-24 | 从 `DATA_MODEL.md §三` 独立拆分;内容等价于 v1.2 DATA_MODEL.md §三 |
|
||||
| v1.1 | 2026-04-24 | 新增 §2.6 `client_releases` 表(客户端发布管理);同步更新表清单、约束规则、查询模式 |
|
||||
| v1.2 | 2026-04-26 | 配合系统管理技术文档 v1.2 升级分批专节:§2.5 `upgrade_events` 增加 `upgrade_type`、`gray_tenant_ids`、`batch_size`、`batch_concurrency`、`batch_interval_seconds`、`failure_policy`、`current_batch_no`、`total_batch_count`、`health_gate_config`、`pre_backup_record_id`、`halted_reason` 字段,状态机扩展为 10 态;新增 §2.7 Feature Flag 体系(`feature_flag_definitions` / `tenants.feature_flags` JSONB / `feature_flag_change_log`);同步更新表清单、§4.2 升级状态机、§4.3 Flag 流程、§5.1 查询模式、§5.2 禁止操作 |
|
||||
| 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 个查询:某租户活跃安装数 / 历史装机总数 / 租户内版本分布 / 全平台租户活跃榜) |
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、模块定位与架构边界
|
||||
|
||||
### 1.1 系统配置模块职责
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
`DATA_MODEL.md` 的核心目标是:**让 AI 在触碰任何数据相关代码时,都能理解业务语义,而不只是看到一堆字段名。**
|
||||
|
||||
---
|
||||
@@ -11,6 +12,7 @@
|
||||
md
|
||||
|
||||
```md
|
||||
|
||||
## Domain Overview
|
||||
|
||||
This is a **multi-tenant** project management tool.
|
||||
@@ -259,4 +261,4 @@ md
|
||||
|
||||
---
|
||||
|
||||
**核心原则**:`DATA_MODEL.md` 写的不是给数据库看的 DDL,而是给 AI 看的**业务契约**。每一个"显而易见"的业务规则,在 AI 眼里都是需要被明确告知的约束。没写的,它都会自己猜。
|
||||
**核心原则**:`DATA_MODEL.md` 写的不是给数据库看的 DDL,而是给 AI 看的**业务契约**。每一个"显而易见"的业务规则,在 AI 眼里都是需要被明确告知的约束。没写的,它都会自己猜。
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 变更历史
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||||
|
||||
## 一、枚举分层标准(必须遵守)
|
||||
|
||||
Fonrey 采用两层枚举体系:
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
# Schema 变更记录
|
||||
|
||||
> **用途**:记录在初始 Model 创建之后新增/修改的字段,供架构师逐一更新 Migration 脚本。
|
||||
> **格式**:每条变更含目标表、变更类型、字段定义、变更原因、来源 PRD 依据。
|
||||
> **状态流转**:`待迁移` → `已迁移`(架构师完成 migration 后更新状态)
|
||||
|
||||
---
|
||||
|
||||
## 变更清单
|
||||
|
||||
| # | 状态 | 目标表 | 变更类型 | 字段名 | 提出日期 |
|
||||
|---|------|--------|----------|--------|----------|
|
||||
| 1 | 待迁移 | `public.tenants` | 新增字段 | `tenant_code` | 2026-04-30 |
|
||||
| 2 | 待迁移 | `public.tenants` | 新增字段 | `contact_phone` | 2026-04-30 |
|
||||
| 3 | 待迁移 | `public.tenants` | 字段修改 | `contact_email`(NOT NULL → 可 NULL) | 2026-04-30 |
|
||||
|
||||
---
|
||||
|
||||
## 变更详情
|
||||
|
||||
### #1 — `public.tenants` 新增 `tenant_code`
|
||||
|
||||
**状态**:待迁移
|
||||
**提出日期**:2026-04-30
|
||||
**目标表**:`public.tenants`(Public Schema,django-tenants 主租户表)
|
||||
|
||||
**字段定义**:
|
||||
```sql
|
||||
tenant_code CHAR(12) UNIQUE NOT NULL
|
||||
```
|
||||
|
||||
**注释**:对外暴露的 12 位纯数字识别码,如 `202500010001`;用户首次登录客户端时输入;由平台运营在注册租户时生成;创建后不可修改。
|
||||
|
||||
**推荐加在**:`schema_name` 字段之后,`name` 字段之前。
|
||||
|
||||
**约束要求**:
|
||||
- `CHAR(12)`:固定 12 位
|
||||
- `UNIQUE`:全局唯一
|
||||
- `NOT NULL`:注册时必填
|
||||
- 禁止 `UPDATE`(应用层 + DB 层双重约束,与 `schema_name` 同等级别)
|
||||
|
||||
**建议索引**:
|
||||
```sql
|
||||
CREATE UNIQUE INDEX idx_tenants_tenant_code ON public.tenants(tenant_code);
|
||||
```
|
||||
|
||||
**变更原因**:
|
||||
登录 PRD §5.1.3 明确用户输入 12 位 Tenant Code 完成租户识别,服务端需通过该码查找对应 `schema_name`,原始 `public.tenants` 表中缺少此字段。
|
||||
|
||||
**PRD 依据**:
|
||||
`PRD/登录管理/用户登录管理模块PRD.md` §5.1.3 — Tenant Code 格式规范:
|
||||
> 格式:固定 12 位纯数字,如 `202500010001`
|
||||
|
||||
**登录查询示例**:
|
||||
```sql
|
||||
SELECT schema_name, name
|
||||
FROM public.tenants
|
||||
WHERE tenant_code = '202500010001'
|
||||
AND status = 'active';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### #2 — `public.tenants` 新增 `contact_phone`
|
||||
|
||||
**状态**:待迁移
|
||||
**提出日期**:2026-04-30
|
||||
**目标表**:`public.tenants`(Public Schema)
|
||||
|
||||
**字段定义**:
|
||||
```sql
|
||||
contact_phone CHAR(11) NOT NULL
|
||||
```
|
||||
|
||||
**注释**:联系人手机号(11位纯数字);系统开通租户时自动以此手机号创建 Tenant Admin 登录账号;必填字段,平台运营在创建租户时录入。
|
||||
|
||||
**推荐加在**:`contact_name` 字段之后,`contact_email` 字段之前。
|
||||
|
||||
**约束要求**:
|
||||
- `CHAR(11)`:固定 11 位手机号
|
||||
- `NOT NULL`:开通租户时必填
|
||||
|
||||
**变更原因**:
|
||||
登录 PRD v1.5 决策:Tenant Admin 账号统一以联系人手机号作为用户名,与普通员工账号规则对齐。需在 tenants 表增加手机号字段作为 Tenant Admin 账号创建的数据来源。
|
||||
|
||||
**PRD 依据**:
|
||||
`PRD/登录管理/用户登录管理模块PRD.md` §5.3.2 Tenant Admin 账号规格表
|
||||
|
||||
---
|
||||
|
||||
### #3 — `public.tenants.contact_email` 改为可 NULL
|
||||
|
||||
**状态**:待迁移
|
||||
**提出日期**:2026-04-30
|
||||
**目标表**:`public.tenants`(Public Schema)
|
||||
|
||||
**变更 SQL**:
|
||||
```sql
|
||||
ALTER TABLE public.tenants
|
||||
ALTER COLUMN contact_email DROP NOT NULL;
|
||||
```
|
||||
|
||||
**变更原因**:
|
||||
`contact_email` 原为 `NOT NULL`。由于 Tenant Admin 账号创建数据来源改为 `contact_phone`(手机号,必填),邮箱降级为选填,仅用于找回密码功能。为空时 Tenant Admin 无法自助找回密码,需联系平台运营处理。
|
||||
|
||||
**PRD 依据**:
|
||||
`PRD/登录管理/用户登录管理模块PRD.md` §5.3.2
|
||||
|
||||
---
|
||||
|
||||
*后续如有新增字段,按同样格式追加到本文件。*
|
||||
Reference in New Issue
Block a user