273 lines
8.5 KiB
Markdown
273 lines
8.5 KiB
Markdown
> **For AI assistants**: Read this entire file before writing any code. All decisions here are final. Do not suggest alternatives unless asked.
|
||
|
||
# Fonrey 系统管理(系统设置)技术方案
|
||
|
||
**版本**: 1.2
|
||
**项目**: Fonrey 房产经纪管理系统
|
||
**技术栈**: Django 4.x + HTMX + Alpine.js + PostgreSQL 16 + Redis
|
||
**关联 PRD**: `PRD/系统配置/系统配置模块PRD.md`
|
||
**关联数据模型**: `DATA_MODEL/DATA_MODEL_SETTING.md`(本方案不重复 DDL)
|
||
**关联契约规范**: `TECH_STACK/API_CONTRACT.md`(全局 API 契约权威)
|
||
**关联枚举字典**: `DATA_MODEL/ENUMS.md`
|
||
**最后更新**: 2026-04-27
|
||
|
||
---
|
||
|
||
## 变更历史
|
||
|
||
| 日期 | 变更人 | 变更内容 |
|
||
|---|---|---|
|
||
| 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) |
|
||
|
||
## 一、文档定位与边界
|
||
|
||
本文件仅定义系统设置模块的:
|
||
|
||
1. 页面与 API 端点设计
|
||
2. 配置读取服务与调用边界
|
||
3. 缓存一致性与审计策略
|
||
4. 错误码与测试映射
|
||
|
||
> 不在本文件展开 `lookup_groups/lookup_items/tenant_settings/field_requirement_rules` 的 DDL。数据结构以 `DATA_MODEL_SETTING.md` 为唯一权威。
|
||
|
||
---
|
||
|
||
## 二、范围定义(US-SETTING-001)
|
||
|
||
### 2.1 MVP 必须覆盖
|
||
|
||
- A:管理员配置可选枚举值(lookup items)
|
||
- B:管理员配置房源字段必填规则
|
||
- C:管理员配置客源规则(查重范围 + 必填字段)
|
||
|
||
### 2.2 预留(非本期强制)
|
||
|
||
- 财务/交易/合同参数配置
|
||
- 通知渠道与发布平台配置
|
||
- 高级规则引擎(跨模块联动)
|
||
|
||
---
|
||
|
||
## 三、模块架构边界
|
||
|
||
## 3.1 模块职责(`apps/setting`)
|
||
|
||
- 为租户管理员提供配置台
|
||
- 为业务模块提供统一读取入口
|
||
- 负责写后缓存失效与审计记录
|
||
|
||
## 3.2 外部依赖
|
||
|
||
| 依赖模块 | 依赖内容 |
|
||
|---|---|
|
||
| `apps/property` | 读取房源来源与字段规则 |
|
||
| `apps/client` | 读取客源来源、跟进目的、查重规则 |
|
||
| `apps/permission` | 控制设置台与配置变更权限 |
|
||
| `core/cache.py` | 缓存键封装与失效工具 |
|
||
|
||
## 3.3 分层约束
|
||
|
||
- 业务模块禁止直查 setting 表
|
||
- 统一通过 `TenantSettingsService` 读取
|
||
- 设置写入后必须同步清理对应缓存键
|
||
|
||
---
|
||
|
||
## 四、API 设计原则
|
||
|
||
1. 固定枚举与可配置枚举分层管理。
|
||
2. 设置写入后下一次请求立即可见(主动失效)。
|
||
3. 所有配置接口默认管理员权限保护。
|
||
4. 批量规则写入以原子事务提交。
|
||
5. API 与 HTMX 响应都遵循统一错误码语义。
|
||
|
||
---
|
||
|
||
## 五、端点清单(核心)
|
||
|
||
## 5.1 页面路由(SSR)
|
||
|
||
| 路径 | 方法 | 权限 code | 说明 |
|
||
|---|---|---|---|
|
||
| `/setting/` | GET | `setting.console.view.allow` | 设置首页 |
|
||
| `/setting/lookup/` | GET | `setting.lookup.view.allow` | 枚举配置页 |
|
||
| `/setting/property-field-rules/` | GET | `setting.property_rules.view.allow` | 房源规则页 |
|
||
| `/setting/client-rules/` | GET | `setting.client_rules.view.allow` | 客源规则页 |
|
||
|
||
## 5.2 HTMX 片段端点
|
||
|
||
| 路径 | 方法 | 用途 | 返回 |
|
||
|---|---|---|---|
|
||
| `/setting/fragments/lookup-groups/` | GET | 分组列表局刷 | HTML 片段 |
|
||
| `/setting/fragments/lookup-items/{group_id}/` | GET | 选项列表局刷 | HTML 片段 |
|
||
| `/setting/fragments/property-field-rule-matrix/` | GET | 规则矩阵局刷 | HTML 片段 |
|
||
| `/setting/fragments/client-rule-form/` | GET | 客源规则表单局刷 | HTML 片段 |
|
||
|
||
## 5.3 JSON API(MVP)
|
||
|
||
| 端点 | 方法 | 权限 code | 说明 |
|
||
|---|---|---|---|
|
||
| `/api/setting/lookup/groups/` | GET | `setting.lookup.view.allow` | 获取分组 |
|
||
| `/api/setting/lookup/items/query/` | POST | `setting.lookup.view.allow` | 查询选项 |
|
||
| `/api/setting/lookup/items/` | POST | `setting.lookup.edit.allow` | 新增选项 |
|
||
| `/api/setting/lookup/items/{id}/` | PATCH | `setting.lookup.edit.allow` | 编辑选项 |
|
||
| `/api/setting/lookup/items/{id}/deactivate/` | POST | `setting.lookup.edit.allow` | 停用选项 |
|
||
| `/api/setting/lookup/items/reorder/` | POST | `setting.lookup.edit.allow` | 批量排序 |
|
||
| `/api/setting/property-field-rules/query/` | POST | `setting.property_rules.view.allow` | 查询规则矩阵 |
|
||
| `/api/setting/property-field-rules/batch-upsert/` | POST | `setting.property_rules.edit.allow` | 保存房源规则 |
|
||
| `/api/setting/client-rules/get/` | GET | `setting.client_rules.view.allow` | 获取客源规则 |
|
||
| `/api/setting/client-rules/update/` | POST | `setting.client_rules.edit.allow` | 更新客源规则 |
|
||
| `/api/setting/snapshot/` | GET | 已登录 | 业务录入统一快照入口 |
|
||
|
||
---
|
||
|
||
## 六、关键 API 规范(请求/响应)
|
||
|
||
## 6.1 新增可配置枚举选项
|
||
|
||
`POST /api/setting/lookup/items/`
|
||
|
||
```json
|
||
{
|
||
"module": "client",
|
||
"key": "source",
|
||
"value": "douyin",
|
||
"label_zh": "抖音",
|
||
"sort_order": 99
|
||
}
|
||
```
|
||
|
||
校验:
|
||
- 同组 `value` 不可重复
|
||
- `value` 限定 lowercase + `_`
|
||
|
||
## 6.2 批量保存房源字段规则
|
||
|
||
`POST /api/setting/property-field-rules/batch-upsert/`
|
||
|
||
```json
|
||
{
|
||
"module": "property",
|
||
"entity_type": "residential",
|
||
"trade_status": "sale",
|
||
"rules": [
|
||
{"field_key": "orientation", "requirement": "required"},
|
||
{"field_key": "parking_count", "requirement": "hidden"}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 七、HTMX 交互约定
|
||
|
||
## 7.1 Header 约定
|
||
|
||
- 请求头:`HX-Request: true`
|
||
- 成功触发:`HX-Trigger` toast(success)
|
||
- 失败触发:`HX-Trigger` toast(error)
|
||
|
||
## 7.2 模板分片命名
|
||
|
||
- `templates/setting/fragments/lookup_groups.html`
|
||
- `templates/setting/fragments/lookup_items_table.html`
|
||
- `templates/setting/fragments/property_rule_matrix.html`
|
||
- `templates/setting/fragments/client_rule_form.html`
|
||
|
||
---
|
||
|
||
## 八、权限与数据范围
|
||
|
||
## 8.1 最小权限矩阵
|
||
|
||
| 能力 | 权限 code |
|
||
|---|---|
|
||
| 设置台查看 | `setting.console.view.allow` |
|
||
| 可配置枚举查看/编辑 | `setting.lookup.view.allow` / `setting.lookup.edit.allow` |
|
||
| 房源规则查看/编辑 | `setting.property_rules.view.allow` / `setting.property_rules.edit.allow` |
|
||
| 客源规则查看/编辑 | `setting.client_rules.view.allow` / `setting.client_rules.edit.allow` |
|
||
|
||
## 8.2 范围规则
|
||
|
||
- 设置项作用域默认为当前租户
|
||
- 不允许跨租户读取或写入配置
|
||
|
||
---
|
||
|
||
## 九、异步任务与缓存策略
|
||
|
||
## 9.1 异步任务(可选)
|
||
|
||
| 任务 | 触发时机 | 说明 |
|
||
|---|---|---|
|
||
| `setting_rebuild_lookup_cache_task` | 大批量导入后 | 后台预热常用 lookup 缓存 |
|
||
|
||
## 9.2 Redis Key 规范
|
||
|
||
| Key | TTL | 触发失效 |
|
||
|---|---|---|
|
||
| `{schema}:setting:lookup:{module}.{key}` | 300s | lookup 新增/编辑/停用/排序 |
|
||
| `{schema}:setting:field_req:{module}.{entity_type}.{trade_status}` | 300s | 字段规则保存 |
|
||
| `{schema}:setting:kv:{category}.{key}` | 300s | tenant_settings 更新 |
|
||
| `{schema}:setting:client_rules` | 300s | client rules 更新 |
|
||
|
||
---
|
||
|
||
## 十、性能与可靠性约束
|
||
|
||
- 设置读取接口目标:`p95 < 150ms`(命中缓存)
|
||
- 批量规则写入目标:`p95 < 500ms`(中等规模)
|
||
- 缓存失效失败需上报 Sentry,不回滚已提交事务
|
||
- 读路径在缓存不可用时可退化到 DB 查询
|
||
|
||
---
|
||
|
||
## 十一、安全与合规
|
||
|
||
1. 配置写接口仅管理员可用。
|
||
2. 每次写操作记录审计:操作者、配置域、前后值、IP、时间。
|
||
3. 系统预置项(`is_system=true`)不可删除,可停用。
|
||
4. 历史业务数据不得因枚举停用被破坏。
|
||
|
||
---
|
||
|
||
## 十二、错误码建议
|
||
|
||
| code | HTTP | 场景 |
|
||
|---|---|---|
|
||
| `SETTING_LOOKUP_GROUP_NOT_FOUND` | 404 | 分组不存在 |
|
||
| `SETTING_LOOKUP_VALUE_DUPLICATED` | 409 | 选项 value 冲突 |
|
||
| `SETTING_LOOKUP_SYSTEM_ITEM_DELETE_FORBIDDEN` | 403 | 尝试删除系统预置项 |
|
||
| `SETTING_RULE_INVALID_REQUIREMENT` | 400 | 规则值非法 |
|
||
| `SETTING_PERMISSION_DENIED` | 403 | 权限不足 |
|
||
|
||
---
|
||
|
||
## 十三、测试映射(P0)
|
||
|
||
| 子场景 | 最低覆盖 |
|
||
|---|---|
|
||
| 001-A 参数配置 | 分组加载、增改停用、排序、生效验证 |
|
||
| 001-B 房源字段规则 | 查询矩阵、批量保存、录入页规则生效 |
|
||
| 001-C 客源规则 | 查重范围更新、必填更新、录入页生效 |
|
||
| 缓存一致性 | 写入后缓存失效,下一次读取为最新值 |
|
||
|
||
测试文件:`tests/integration/setting/test_us_setting.py`
|
||
|
||
---
|
||
|
||
## 十四、落地顺序建议
|
||
|
||
1. 先实现 `TenantSettingsService` 与失效框架
|
||
2. 再做 lookup items(001-A)
|
||
3. 再做 property field rules(001-B)
|
||
4. 最后做 client rules(001-C)与业务接线
|
||
|
||
---
|
||
|
||
## 十五、文档同步规则
|
||
|
||
- 新增/调整可配置枚举域:同步 `DATA_MODEL/ENUMS.md`
|
||
- 新增 setting key:同步 `DATA_MODEL_SETTING.md`
|
||
- API 变更:同步本文件与系统配置 PRD
|