- 新增 PRD/系统配置/系统配置模块PRD.md(v0.1 Draft) - MVP 范围:US-SETTING-001-A(Lookup Items)、B(房源字段必填规则)、C(客源录入规则) - 新增 PRD/系统配置/系统配置数据模型设计说明_for_Atlas.md - 新增 PRD/系统配置/系统配置参数数据.md(竞品参数数据) - 删除旧版 PRD/系统配置/系统配置.md(已被新PRD替代) - 新增 DATA_MODEL/DATA_MODEL_SETTING.md(系统配置数据模型) - 新增 DATA_MODEL/ENUMS.md(枚举定义与约定) - 新增 AGENTS.md(AI Agent 开发规范) - 更新 PRD/TASK.md:US-SETTING-001 拆分为 A/B/C 三个子任务,修正参考文档路径与验收标准 - 新增 VIBE_CODING_开工前缺失清单.md - 新增 TECH_STACK/房源管理技术方案.md - 更新 DATA_MODEL/DATA_MODEL.md、DATA_MODEL_CLIENT.md、DATA_MODEL_LOGIN.md - 更新 PRD/PRD_MVP.md、PRD/权限管理/权限管理模块PRD.md - 更新 TECH_STACK/TECH_STACK.md、权限管理系统技术方案.md - 更新 UI_DESIGN/preview.html、UI_SYSTEM/UI_SYSTEM.md - 新增 prompt/PRD - 为系统设置生成PRD设计文档.md、更新 prompt 模板
12 KiB
系统配置模块 — 数据模型设计说明
致:Atlas(架构师)
来自:Nova(PM)
日期:2026-04-27
关联 PRD:PRD/系统配置/系统配置模块PRD.md
关联文档:DATA_MODEL/ENUMS.md、DATA_MODEL/DATA_MODEL.md
一、背景与问题
在设计系统配置模块的数据模型时,我发现当前 DATA_MODEL/ENUMS.md 已经明确了「固定枚举」与「可配置枚举」的分层设计,但两者的边界在文档中未完全显式化。本说明文档的目的是:
- 厘清三类配置数据各自应存在哪张表
- 指出需要新增的两张表及其建议 DDL
- 说明与 ENUMS.md 现有设计的关系,以及需要 Atlas 补充/修改的内容
请 Atlas 在完成 DATA_MODEL/DATA_MODEL.md 和 DATA_MODEL/ENUMS.md 的修订后,同步通知 Nova 确认。
二、三类配置数据的划分
系统配置涉及三类性质不同的数据,分属不同的表和 Schema,请严格区分:
类型 A:固定系统枚举(存 Public Schema / enum_labels)
特征:
- 值域固定,所有租户共享同一套
- 与数据库
CHECK CONSTRAINT绑定(如decoration IN ('rough','plain','simple','medium','fine','luxury')) - 只能由平台研发通过 migration 修改
- 租户管理员无权增删
代表字段:property.decoration(装修)、property.orientation(朝向)、property.status(交易状态)、client.status(客源状态)、client.grade(客源等级)、common.gender、common.id_type
现状:ENUMS.md 已完整定义,enum_labels 表 DDL 已存在。无需改动。
类型 B:租户可配置枚举(存 Tenant Schema / lookup_items,需新增)
特征:
- 各租户选项不同(如来源渠道:A 公司有「抖音」,B 公司没有)
- 租户管理员可通过界面增删排序
- 系统预制初始值(
is_system = True),预制值不可删除但可停用 - 无
CHECK CONSTRAINT(值域动态) - 与
enum_labels完全独立,不存在于 Public Schema
代表字段:客源来源(client.source)、跟进目的(client_follow_logs.follow_purpose)、房源来源(property.source)
ENUMS.md 现状:
§2.14 跟进目的已明确标注「此枚举为可配置项,存储方式:lookup_items表」,但lookup_items的 DDL 尚未在任何 DATA_MODEL 文档中定义client.source(来源)在 ENUMS.md 中未定义(因为它是可配置的),但竞品系统有 50+ 预制来源选项
需要 Atlas 做的事:
- 在
DATA_MODEL/DATA_MODEL.md中新增lookup_groups和lookup_items表的 DDL - 在 ENUMS.md 中补充一节「可配置枚举说明」,列出哪些 domain 属于
lookup_items而非enum_labels - 确认
apps/setting/下新增lookup.pymodels 文件
建议 DDL(供参考,Atlas 可调整):
-- ============================================================
-- 可配置枚举分组(租户 Schema)
-- ============================================================
CREATE TABLE lookup_groups (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
module VARCHAR(50) NOT NULL, -- 'client' | 'property'
key VARCHAR(100) NOT NULL, -- 'source' | 'follow_purpose'
label_zh VARCHAR(50) NOT NULL, -- 界面显示名称,如「客源来源」
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (module, key)
);
-- ============================================================
-- 可配置枚举选项(租户 Schema)
-- ============================================================
CREATE TABLE lookup_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
group_id UUID NOT NULL REFERENCES lookup_groups(id) ON DELETE CASCADE,
value VARCHAR(100) NOT NULL, -- 存储值(英文 key,建议 snake_case)
label_zh VARCHAR(50) NOT NULL, -- 显示文本
is_system BOOLEAN NOT NULL DEFAULT FALSE, -- True=系统预制,不可删除
is_active BOOLEAN NOT NULL DEFAULT TRUE,
sort_order SMALLINT NOT NULL DEFAULT 0,
created_by UUID REFERENCES staff(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (group_id, value)
);
CREATE INDEX idx_lookup_items_group_active ON lookup_items(group_id, is_active, sort_order);
预制种子数据参考(需写入 migration fixtures,is_system = TRUE):
| module | key | 预制选项(部分) |
|---|---|---|
client |
source |
门店接待、老客户转介绍、驻守派单、上门、网络-58同城、网络-安居客、微信、朋友介绍 |
client |
follow_purpose |
回拨、推房、带看、维护、其他 |
property |
source |
主动开发、业主上门、老客户转介绍、网络来电 |
类型 C:行为规则与开关(存 Tenant Schema,需新增两张表)
C-1:键值配置表 tenant_settings
特征:
- 存储开关(bool)、阈值(int)、枚举选择(string)等标量类型配置
- 每个 key 全局唯一,有默认值
- 租户管理员通过界面修改
建议 DDL:
-- ============================================================
-- 租户标量配置表(键值对)
-- ============================================================
CREATE TABLE tenant_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
category VARCHAR(50) NOT NULL, -- 配置分类:'client' | 'property' | 'showroom'
key VARCHAR(100) NOT NULL, -- 配置 key,如 'duplicate_check_scope'
value JSONB NOT NULL, -- 存储任意类型(bool/int/str/list)
value_type VARCHAR(20) NOT NULL, -- 'bool' | 'int' | 'string' | 'enum'(用于前端渲染)
updated_by UUID REFERENCES staff(id),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (category, key)
);
MVP 阶段需要预置的 key:
| category | key | value_type | 默认值 | 说明 |
|---|---|---|---|---|
client |
duplicate_check_scope |
enum |
"self" |
新增私客查重范围:self/dept/company |
C-2:字段必填规则表 field_requirement_rules
特征:
- 按「模块 × 实体用途 × 交易状态 × 字段」四元组确定一条规则
- 规则值为三态:
required/optional/hidden - MVP 仅需支持
property模块
建议 DDL:
-- ============================================================
-- 字段必填/隐藏规则表(租户 Schema)
-- ============================================================
CREATE TABLE field_requirement_rules (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
module VARCHAR(20) NOT NULL, -- 'property' | 'client'
entity_type VARCHAR(50) NOT NULL, -- property_type 值,如 'residential' | 'shop'
trade_status VARCHAR(50) NOT NULL, -- 'sale' | 'rent' | 'sale_rent'(or '*' 表示所有)
field_key VARCHAR(50) NOT NULL, -- 字段 key,如 'orientation' | 'decoration'
requirement VARCHAR(10) NOT NULL -- 'required' | 'optional' | 'hidden'
CHECK (requirement IN ('required', 'optional', 'hidden')),
updated_by UUID REFERENCES staff(id),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (module, entity_type, trade_status, field_key)
);
CREATE INDEX idx_field_req_lookup ON field_requirement_rules(module, entity_type, trade_status);
MVP 初始规则(建议由研发预置,管理员可覆盖):
| module | entity_type | trade_status | field_key | requirement |
|---|---|---|---|---|
property |
residential |
sale |
orientation |
optional |
property |
residential |
sale |
decoration |
optional |
property |
residential |
sale |
floor |
optional |
property |
residential |
rent |
decoration |
optional |
property |
residential |
rent |
floor |
optional |
三、与 ENUMS.md 的冲突与修改建议
冲突点 1:lookup_items DDL 缺失
现状:ENUMS.md §2.14 和 §六.4 已提到「可配置枚举通过 lookup_items 表管理」,但 lookup_items 的 DDL 既不在 ENUMS.md 中,也不在 DATA_MODEL.md 中。
建议修改:在 DATA_MODEL/ENUMS.md 末尾(或新增 §七)补充 lookup_groups + lookup_items 的 DDL 和说明,明确与 enum_labels 的区别:
## 七、可配置枚举(lookup_items)
与 `enum_labels`(Public Schema,固定)不同,`lookup_items` 存储在 **Tenant Schema**,
由租户管理员自主维护。适用于各租户选项不同的枚举字段。
[此处补充 DDL 和说明]
**属于 lookup_items 的 domain**:
- `client.source`(客源来源)
- `client.follow_purpose`(跟进目的)— 已在 §2.14 说明
- `property.source`(房源来源)
冲突点 2:client.source(来源)未在 ENUMS.md 定义
现状:来源是可配置枚举,不应在 ENUMS.md 中定义固定值。但目前 ENUMS.md 中没有任何地方说明「哪些 domain 是可配置的、对应哪张表」,导致读者不清楚来源应该去哪里查。
建议修改:在 ENUMS.md §六 维护约定中新增一条:
5. **可配置枚举对照表**:以下 domain 属于 `lookup_items`,不在本文件定义,
不建立 CHECK 约束,请查阅 `PRD/系统配置/系统配置模块PRD.md`:
- `client.source`
- `client.follow_purpose`(已标注)
- `property.source`
冲突点 3:tenant_settings 和 field_requirement_rules 完全缺失
现状:现有 DATA_MODEL 文档未涵盖这两张表。
建议修改:在 DATA_MODEL/DATA_MODEL.md 中新增「系统配置模块数据模型」章节,包含这两张表的 DDL。(本文件的建议 DDL 见第二章 C 节)
四、服务层约定(供研发参考)
所有业务模块通过统一服务层读取配置,禁止直接查询配置表:
# apps/setting/services/tenant_settings_service.py
class TenantSettingsService:
def get(self, key: str, default=None):
"""
读取标量配置(tenant_settings 表)
缓存 key:{tenant_schema}:setting:kv:{key},TTL 5min
"""
def get_lookup_items(self, module: str, key: str) -> list[dict]:
"""
获取可配置枚举选项(lookup_items 表)
仅返回 is_active=True 的项,按 sort_order 排序
缓存 key:{tenant_schema}:setting:lookup:{module}.{key},TTL 5min
写入时主动 invalidate
"""
def get_field_requirements(
self, module: str, entity_type: str, trade_status: str
) -> dict[str, str]:
"""
获取字段必填规则,返回 {field_key: 'required'|'optional'|'hidden'}
缓存 key:{tenant_schema}:setting:field_req:{module}.{entity_type}.{trade_status},TTL 5min
"""
五、需要 Atlas 完成的具体动作
| 编号 | 动作 | 修改文件 | 优先级 |
|---|---|---|---|
| A-1 | 新增 lookup_groups + lookup_items DDL |
DATA_MODEL/DATA_MODEL.md 或单独 DATA_MODEL_SETTING.md |
P0(开发依赖) |
| A-2 | 新增 tenant_settings DDL |
同上 | P0 |
| A-3 | 新增 field_requirement_rules DDL |
同上 | P0 |
| A-4 | ENUMS.md §七 补充可配置枚举说明和对照表 | DATA_MODEL/ENUMS.md |
P0 |
| A-5 | ENUMS.md §六 维护约定新增第 5 条(可配置枚举对照) | DATA_MODEL/ENUMS.md |
P0 |
| A-6 | 确认 entity_type 字段的值域与 property.property_type 的 CHECK 约束完全一致 |
DATA_MODEL_PROPERTY.md 对齐 |
P0 |
| A-7 | 确认 trade_status 字段的值域(sale/rent/sale_rent/*)是否与 property.status 兼容 |
DATA_MODEL_PROPERTY.md 对齐 |
P1 |
完成以上动作后,请更新 DATA_MODEL/DATA_MODEL.md 的版本号,并通知 Nova 做最终 PRD 对齐确认。
本文档由 Nova 起草,数据模型最终决策权归 Atlas。如有架构层面的调整,请反馈给 Nova 同步更新 PRD 中的技术考量章节。