文档更新
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
| 2026-04-30 | Atlas | 初始化 ADR 动态决策记录;补录当日关键技术与需求决策 |
|
||||
| 2026-05-02 | Sisyphus | 新增 ADR-20260502-001:合并系统管理与客户端发布两份 PRD 为统一的『平台管理后台 PRD』,原文件删除 |
|
||||
| 2026-05-02 | Sisyphus | 新增 ADR-20260502-003:定义『PRD 与 Tech 文档职责边界』规则(PRD 管 what/why、Tech 管 how);首次落地于登录管理 PRD v3.0 |
|
||||
| 2026-06-04 | Sisyphus | 新增 ADR-20260604-001:列表分页全局采用 Keyset(cursor),允许 page-based 作过渡兼容;同步修订 `UI_DESIGN/ROUTES.md` 与 `UI_DESIGN/房源管理/房源列表_UI.md` |
|
||||
| 2026-06-04 | Sisyphus | 新增 ADR-20260604-002:ROUTES.md 客源条目"重复客源(成交)"与"重复客源(公客)"合并为单条 `/clients/duplicates/?tab=transacted\|public`,客源条目数稳定为 19 |
|
||||
|
||||
## 一、记录规范(必须遵守)
|
||||
|
||||
@@ -247,6 +249,43 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-04
|
||||
|
||||
### ADR-20260604-001
|
||||
- **类型**:TECH
|
||||
- **模块**:列表分页(全局)
|
||||
- **状态**:accepted
|
||||
- **背景**:`AGENTS.md` §4.5 与 `UI_DESIGN/ROUTES.md` §1 全局约定明文要求"所有列表查询必须使用 Keyset 分页(参数禁止包含 `offset`,统一使用 `cursor`)"。但 `UI_DESIGN/房源管理/房源列表_UI.md` 现存示例(行 97 query params 列表、行 741 HTMX `hx-vals='{"page": N}'`)仍是 page-based 风格,与全局规范冲突。MVP 阶段一次性切到 Keyset 会拖慢前端模板与示例代码改造节奏,且页码 UI(`[1][2][3]...[N]`)已被多份截图与组件清单采用。
|
||||
- **决策**:
|
||||
1. **目标口径**:列表分页长期统一为 Keyset(cursor);新增列表页与新增分页 API 不得使用 page/offset。
|
||||
2. **过渡兼容**:MVP Phase 1 期间,已有 page-based 示例的模块文档与代码可保留 page UI 表现(页码导航 + 跳页),但**数据获取层必须支持 cursor 参数**;后端 API 接受 `cursor` 为主参数,`page` 仅作过渡兼容输入且不得用于 1000 条以上数据集。
|
||||
3. **文档承接**:`UI_DESIGN/ROUTES.md` §1 通用约定新增"过渡兼容"说明;`UI_DESIGN/房源管理/房源列表_UI.md` 示例代码改为 `cursor`,分页 UI 表现保留。
|
||||
4. **退出条件**:MVP GA 后 1 个版本内,所有 page-based 示例必须清理;届时新增 ADR 关闭本过渡条款。
|
||||
- **影响范围**:
|
||||
- `UI_DESIGN/ROUTES.md` §1
|
||||
- `UI_DESIGN/房源管理/房源列表_UI.md` §2.1.1、§2.1.3 分页栏
|
||||
- 后续所有列表页 HTMX 模板与 API 视图
|
||||
- **关联文档**:
|
||||
- `AGENTS.md` §4.5
|
||||
- `UI_DESIGN/ROUTES.md`
|
||||
- `UI_DESIGN/房源管理/房源列表_UI.md`
|
||||
- **备注**:B-04(Keyset 分页规范缺位)由本 ADR 部分关闭;剩余的列表索引矩阵补全留待后续 Major 修订。
|
||||
|
||||
### ADR-20260604-002
|
||||
- **类型**:REQ
|
||||
- **模块**:客源管理(路由汇总)
|
||||
- **状态**:accepted
|
||||
- **背景**:`UI_DESIGN/ROUTES.md` §5 客源条目数与历史 handoff 口径"客源 19 项"不一致——实际列出 20 行,多出的 1 行来自将"重复客源(成交)"与"重复客源(公客)"拆分为两条独立路由。两者复用同一列表页结构、同一权限范围、同一组件清单,仅业务子集不同,符合 ROUTES.md 全局约定中"Tab 维度统一用 `?tab=` 表达"的模式。
|
||||
- **决策**:将两条重复客源路由合并为单条 `/clients/duplicates/`,子集通过 `?tab=transacted|public` 区分;客源条目总数稳定为 19。
|
||||
- **影响范围**:
|
||||
- `UI_DESIGN/ROUTES.md` §5(合并 2 行为 1 行)
|
||||
- **关联文档**:
|
||||
- `UI_DESIGN/ROUTES.md`
|
||||
- `UI_DESIGN/客源管理/客源列表_UI.md`
|
||||
- **备注**:本 ADR 不变更任何业务规则,仅统一 URL 表达形式与条目计数。
|
||||
|
||||
---
|
||||
|
||||
## 三、按模块分类记录(视图索引)
|
||||
|
||||
## 3.1 测试治理(全局)
|
||||
@@ -274,6 +313,12 @@
|
||||
- `ADR-20260502-001`:合并系统管理 PRD 与客户端发布 PRD 为统一的『平台管理后台 PRD』(REQ)
|
||||
- `ADR-20260502-002`:合并系统管理技术文档与客户端发布技术方案为统一的『平台管理后台技术方案』(TECH)
|
||||
|
||||
## 3.7 列表分页(全局)
|
||||
- `ADR-20260604-001`:Keyset(cursor) 为目标口径;MVP 期允许 page-based 作过渡兼容(TECH)
|
||||
|
||||
## 3.8 客源管理(路由)
|
||||
- `ADR-20260604-002`:重复客源合并为单条 `/clients/duplicates/?tab=transacted|public`,客源条目数=19(REQ)
|
||||
|
||||
---
|
||||
|
||||
## 四、历史记录(Append-Only Log)
|
||||
@@ -295,6 +340,8 @@
|
||||
| ADR-20260502-001 | 2026-05-02 | 平台管理后台 | REQ | accepted | 合并系统管理 PRD + 客户端发布 PRD 为『平台管理后台 PRD』,原文件删除 | `PRD/平台管理后台/平台管理后台PRD.md` |
|
||||
| ADR-20260502-002 | 2026-05-02 | 平台管理后台 | TECH | accepted | 合并系统管理技术文档 + 客户端发布技术方案为『平台管理后台技术方案』(覆盖技术选型/页面路由表/API 设计三维度),原文件删除 | `TECH_STACK/平台管理后台技术方案.md` |
|
||||
| ADR-20260502-003 | 2026-05-02 | 文档治理 | REQ | accepted | PRD 管 what/why、Tech 管 how;PRD 必须移出 API 路径/Redis Key/字段类型/框架 API 等实现细节,由 Tech 与 DATA_MODEL 承接 | `PRD/登录管理/用户登录管理模块PRD.md` v3.0 |
|
||||
| ADR-20260604-001 | 2026-06-04 | 列表分页(全局) | TECH | accepted | Keyset(cursor) 为目标口径;MVP 期允许 page-based 作过渡兼容 | `UI_DESIGN/ROUTES.md`、`UI_DESIGN/房源管理/房源列表_UI.md` |
|
||||
| ADR-20260604-002 | 2026-06-04 | 客源管理(路由) | REQ | accepted | 重复客源合并为单条 `/clients/duplicates/?tab=transacted\|public`,客源条目数=19 | `UI_DESIGN/ROUTES.md` |
|
||||
|
||||
---
|
||||
|
||||
|
||||
322
Project/fonrey/DATA_MODEL/STATE_MACHINE.md
Normal file
322
Project/fonrey/DATA_MODEL/STATE_MACHINE.md
Normal file
@@ -0,0 +1,322 @@
|
||||
> For AI assistants: Read this entire file before writing any code. All decisions here are final.
|
||||
|
||||
# Fonrey — 统一状态机规范 (STATE_MACHINE)
|
||||
|
||||
**定位**:本文档是 Fonrey 项目所有实体生命周期与状态流转的唯一权威定义。
|
||||
**变更历史**:
|
||||
|
||||
| 日期 | 变更人 | 变更内容 |
|
||||
|---|---|---|
|
||||
| 2026-06-04 | Sisyphus | 初始版本:整合各模块状态机逻辑,对齐 ENUMS v2.2 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 通用约定
|
||||
|
||||
- **状态值命名**:统一采用 `lower_snake_case`,必须与 `DATA_MODEL/ENUMS.md` 完全一致。
|
||||
- **触发动作**:状态迁移必须由显式的动作(Action)或事件(Event)触发。
|
||||
- **操作日志**:所有关键状态迁移(除系统内部中间态外)必须记录对应的 `status_log` 或 `audit_log` 表。
|
||||
- **不可逆规则**:标注为“终态”的状态禁止迁回初始态或中间态。
|
||||
- **权限要求**:状态迁移接口必须校验操作者的 DataScope 与 Function Permission。
|
||||
|
||||
---
|
||||
|
||||
## 2. 租户生命周期 (Public.Tenant)
|
||||
|
||||
**实体**: `public.tenants` | **字段**: `status`
|
||||
**参考**: `DATA_MODEL_PUBLIC.md` §2.1, §4.1
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> creating
|
||||
creating --> active: 初始化完成
|
||||
creating --> failed: 初始化失败
|
||||
active --> suspended: 逾期/违规/申请
|
||||
suspended --> active: 恢复条件满足
|
||||
active --> pending_delete: 申请注销
|
||||
suspended --> pending_delete: 申请注销
|
||||
pending_delete --> deleted: 30天后/人工确认
|
||||
deleted --> [*]
|
||||
```
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `public.tenant.status`)
|
||||
- `creating`: 创建中
|
||||
- `active`: 正常
|
||||
- `suspended`: 已挂起
|
||||
- `pending_delete`: 待删除
|
||||
- `deleted`: 已删除
|
||||
- `failed`: 创建/初始化失败
|
||||
|
||||
### 状态迁移表
|
||||
|
||||
| 当前状态 | 下一状态 | 触发动作/事件 | 触发角色 | 副作用 | 是否可逆 |
|
||||
|---|---|---|---|---|---|
|
||||
| `creating` | `active` | 租户 Schema 初始化成功 | System | 写 `tenant_status_logs` | 否 |
|
||||
| `creating` | `failed` | 初始化脚本执行失败 | System | 记录错误日志 | 否 |
|
||||
| `active` | `suspended` | 欠费/违规/License过期 | System/SuperAdmin | 设置 `suspended_until`, 写日志 | 是 |
|
||||
| `suspended` | `active` | 缴费成功/解封/到期恢复 | System/SuperAdmin | 清除挂起原因 | 是 |
|
||||
| `active`/`suspended` | `pending_delete` | 提交注销申请 | TenantAdmin | 设置 `deleted_at` | 是 |
|
||||
| `pending_delete` | `deleted` | 确认注销/静默期结束 | SuperAdmin/System | 物理删除或深度标记 | 否 |
|
||||
|
||||
**来源章节**: `DATA_MODEL_PUBLIC.md` §4.1
|
||||
|
||||
---
|
||||
|
||||
## 3. 客源状态机 (Client)
|
||||
|
||||
**实体**: `client.clients` | **字段**: `status`
|
||||
**参考**: `DATA_MODEL_CLIENT.md` §3.1, §4 | `ENUMS.md` §3.6
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> buying
|
||||
[*] --> renting
|
||||
[*] --> buy_or_rent
|
||||
|
||||
state "活跃态" as Active {
|
||||
buying
|
||||
renting
|
||||
buy_or_rent
|
||||
}
|
||||
|
||||
Active --> suspended: 暂时无需求
|
||||
suspended --> Active: 重新激活
|
||||
|
||||
Active --> public: 手动转公/超时自动
|
||||
suspended --> public: 手动转公
|
||||
|
||||
Active --> bought: 转成交(我购)
|
||||
Active --> rented_done: 转成交(我租)
|
||||
|
||||
Active --> invalid: 转无效
|
||||
suspended --> invalid: 转无效
|
||||
|
||||
invalid --> Active: 经理审批恢复
|
||||
|
||||
bought --> [*]
|
||||
rented_done --> [*]
|
||||
public --> [*]
|
||||
```
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `client.status`)
|
||||
- `buying`: 求购
|
||||
- `renting`: 求租
|
||||
- `buy_or_rent`: 租购
|
||||
- `suspended`: 暂缓
|
||||
- `bought`: 已购 (我购)
|
||||
- `rented_done`: 已租 (我租)
|
||||
- `public`: 公客
|
||||
- `invalid`: 无效
|
||||
|
||||
### 状态迁移表
|
||||
|
||||
| 当前状态 | 下一状态 | 触发动作/事件 | 触发角色 | 副作用 | 是否可逆 |
|
||||
|---|---|---|---|---|---|
|
||||
| `buying`/`renting`/`buy_or_rent` | `suspended` | 修改状态为暂缓 | 经纪人 | 写 `client_status_logs` | 是 |
|
||||
| `suspended` | `buying`/`renting`/`buy_or_rent` | 重新激活需求 | 经纪人 | 更新 `last_active_at` | 是 |
|
||||
| `Active`/`suspended` | `public` | 手动转公/超时自动转公 | 经纪人/System | 修改 `client_type='public'` | 否 |
|
||||
| `Active` | `bought`/`rented_done` | 录入成交合同 | 经纪人 | 修改 `client_type='transacted'` | 否 |
|
||||
| `Active`/`suspended` | `invalid` | 标记无效 | 经纪人 | 记录 `invalid_reason` | 需审批 |
|
||||
|
||||
### 禁迁规则
|
||||
- `transacted` (bought/rented_done) 状态为绝对终态,禁止迁往任何其他状态。
|
||||
- `public` 状态客源禁止直接修改为 `private` 状态下的需求状态,必须走领用流程。
|
||||
|
||||
**来源章节**: `DATA_MODEL_CLIENT.md` §4, `ENUMS.md` §3.6
|
||||
|
||||
---
|
||||
|
||||
## 4. 房源状态机 (Property)
|
||||
|
||||
**实体**: `property.properties` | **字段**: `status`
|
||||
**参考**: `DATA_MODEL_PROPERTY.md` §3, §4.1
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> unlisted
|
||||
unlisted --> for_sale: 挂牌出售
|
||||
unlisted --> for_rent: 挂牌出租
|
||||
|
||||
state "在盘态" as Listed {
|
||||
for_sale
|
||||
for_rent
|
||||
for_sale_rent
|
||||
}
|
||||
|
||||
Listed --> suspended: 业主暂缓
|
||||
suspended --> Listed: 重新上架
|
||||
|
||||
Listed --> sold: 本司成交
|
||||
Listed --> sold_elsewhere: 他售
|
||||
Listed --> rented_elsewhere: 他租
|
||||
|
||||
Listed --> unlisted: 下架
|
||||
|
||||
sold --> [*]
|
||||
sold_elsewhere --> [*]
|
||||
```
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `property.status`)
|
||||
- `for_sale`: 出售
|
||||
- `for_rent`: 出租
|
||||
- `for_sale_rent`: 租售
|
||||
- `suspended`: 暂缓
|
||||
- `sold_elsewhere`: 他售
|
||||
- `rented_elsewhere`: 他租
|
||||
- `sold`: 成交
|
||||
- `unlisted`: 未挂牌
|
||||
|
||||
### 状态迁移表
|
||||
|
||||
| 当前状态 | 下一状态 | 触发动作/事件 | 触发角色 | 副作用 | 是否可逆 |
|
||||
|---|---|---|---|---|---|
|
||||
| `unlisted` | `for_sale`/`for_rent` | 房源挂牌 | 经纪人 | 新增 `listing_histories` | 是 |
|
||||
| `Listed` | `suspended` | 业主通知暂缓 | 经纪人 | 写跟进日志 | 是 |
|
||||
| `Listed` | `sold` | 本司录入成交 | 经纪人 | 自动结束挂牌历史 | 否 |
|
||||
| `Listed` | `sold_elsewhere`/`rented_elsewhere` | 核实他司已成交 | 经纪人 | | 否 |
|
||||
| `Listed` | `unlisted` | 强制下架 | 管理员 | | 是 |
|
||||
|
||||
**来源章节**: `DATA_MODEL_PROPERTY.md` §3
|
||||
|
||||
---
|
||||
|
||||
## 5. 客户/房源等级 (Grade)
|
||||
|
||||
**实体**: `client.clients` / `property.properties` | **字段**: `grade`
|
||||
**参考**: `DATA_MODEL_CLIENT.md` §3.1 | `DATA_MODEL_PROPERTY.md` §4.1
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `client.grade` / `property.grade`)
|
||||
- `A`: A (急迫)
|
||||
- `B`: B (较强)
|
||||
- `C`: C (一般)
|
||||
- `D`: D (较弱)
|
||||
- `E`: E (暂不关注) - 仅客源
|
||||
|
||||
### 状态迁移表
|
||||
|
||||
| 当前状态 | 下一状态 | 触发动作/事件 | 触发角色 | 副作用 | 是否可逆 |
|
||||
| ---- | ------------------- | ------- | ---- | ----------------------------- | ---- |
|
||||
| 任意状态 | `A`/`B`/`C`/`D`/`E` | 手动调整等级 | 经纪人 | 写 `status_log` / `follow_log` | 是 |
|
||||
|
||||
**来源章节**: `DATA_MODEL_CLIENT.md` §4, `DATA_MODEL_PROPERTY.md` §3
|
||||
|
||||
---
|
||||
|
||||
## 6. 账号状态机 (Account)
|
||||
|
||||
**实体**: `login.user_accounts` | **字段**: `status`
|
||||
**参考**: `DATA_MODEL_LOGIN.md` §5.1
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> active: 创建(初始密码)
|
||||
active --> locked: 密码错误≥5次
|
||||
locked --> active: 30min到期/手动解锁
|
||||
active --> disabled: 离职/手动停用
|
||||
disabled --> active: 复职/手动恢复
|
||||
```
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `login.user_account.status`)
|
||||
- `active`: 启用
|
||||
- `disabled`: 停用
|
||||
- `locked`: 锁定
|
||||
|
||||
### 状态迁移表
|
||||
|
||||
| 当前状态 | 下一状态 | 触发动作/事件 | 触发角色 | 副作用 | 是否可逆 |
|
||||
|---|---|---|---|---|---|
|
||||
| `active` | `locked` | 密码连续错误5次 | System | 设置 `locked_until` | 是 |
|
||||
| `locked` | `active` | 时间到期/管理员解锁 | System/Admin | | 是 |
|
||||
| `active` | `disabled` | 员工离职/手动停用 | Admin/System | 踢出所有 Session | 是 |
|
||||
|
||||
**来源章节**: `DATA_MODEL_LOGIN.md` §5.1
|
||||
|
||||
---
|
||||
|
||||
## 7. 升级事件状态机 (Upgrade Event)
|
||||
|
||||
**实体**: `public.upgrade_events` | **字段**: `status`
|
||||
**参考**: `DATA_MODEL_PUBLIC.md` §4.2
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> draft
|
||||
draft --> pre_check: 提交
|
||||
pre_check --> pre_backup: 健康检查通过
|
||||
pre_backup --> batch_running: 备份完成
|
||||
batch_running --> batch_done: 批次租户成功
|
||||
batch_done --> batch_running: 下一批次
|
||||
batch_done --> succeeded: 全部完成
|
||||
|
||||
batch_running --> halted: 失败/门控拦截
|
||||
halted --> batch_running: 人工继续
|
||||
halted --> rollback_running: 人工回滚
|
||||
rollback_running --> rolled_back: 回滚完成
|
||||
|
||||
batch_running --> failed: 严重故障
|
||||
```
|
||||
|
||||
### 状态枚举值
|
||||
(domain: `public.upgrade_event.status`)
|
||||
- `draft`: 草稿
|
||||
- `pre_check`: 预检查
|
||||
- `pre_backup`: 预备份
|
||||
- `batch_running`: 批次执行中
|
||||
- `batch_done`: 批次完成
|
||||
- `halted`: 已暂停
|
||||
- `succeeded`: 已成功
|
||||
- `failed`: 失败
|
||||
- `rollback_running`: 回滚中
|
||||
- `rolled_back`: 已回滚
|
||||
|
||||
**来源章节**: `DATA_MODEL_PUBLIC.md` §4.2
|
||||
|
||||
---
|
||||
|
||||
## 8. 其他辅助状态
|
||||
|
||||
### 8.1 备份/导出任务 (Backup/Export)
|
||||
**字段**: `status` | **参考**: `ENUMS.md` §2.3
|
||||
- `pending` -> `in_progress` -> `success` / `failed`
|
||||
|
||||
### 8.2 客户端发布 (Client Release)
|
||||
**字段**: `status` | **参考**: `ENUMS.md` §2.4
|
||||
- `draft` -> `published` -> `archived`
|
||||
- **约束**: 同平台架构下仅允许一个 `published`。
|
||||
|
||||
### 8.3 员工状态 (Staff)
|
||||
**字段**: `status` | **参考**: `DATA_MODEL_ORG.md` §4
|
||||
- `probation` -> `active` -> `resigned`
|
||||
- `active` <-> `frozen`
|
||||
|
||||
### 8.4 审批流 (Approval)
|
||||
**实体**: `number_holder_approvals` | **字段**: `status`
|
||||
- `pending` -> `approved` / `rejected`
|
||||
|
||||
---
|
||||
|
||||
## X. 状态机一致性校验清单
|
||||
|
||||
1. **枚举同步**: 状态字段值是否在 `ENUMS.md` 中定义且拼写一致?
|
||||
2. **日志完备**: 每次 `status` 变更是否伴随对应的 `status_log` 插入动作?
|
||||
3. **并发控制**: 状态变更是否包含 `version` 乐观锁检查?
|
||||
4. **终态拦截**: 业务逻辑是否显式禁止从终态(如 `sold`, `deleted`, `rolled_back`)向外迁移?
|
||||
5. **副作用触发**: 状态变更相关的异步任务(如转公客通知、缓存清理)是否已在 Service 层注册?
|
||||
|
||||
---
|
||||
|
||||
## 待澄清问题
|
||||
|
||||
1. **Client Invalid 恢复路径**: `DATA_MODEL_CLIENT.md` §4 提到“需经理审批后可恢复”,但未定义恢复后的目标状态(是恢复到 `suspended` 还是之前的活跃态?)。
|
||||
- *涉及文件*: `DATA_MODEL_CLIENT.md`
|
||||
2. **Property Unlisted 属性**: 房源在 `unlisted` 状态下,其 `attribute` (公/私盘) 是否有意义?若从 `private` 挂牌变为 `unlisted`,再次挂牌时是否应默认保留 `private` 属性?
|
||||
- *涉及文件*: `DATA_MODEL_PROPERTY.md`
|
||||
3. **Tenant Deleted 物理性**: `DATA_MODEL_PUBLIC.md` §4.1 提到“硬删除直接到 deleted”,但在 §2.1 又说“硬删除直接物理删除行”。需要明确 `deleted` 状态是代表软删除的终点还是物理删除前的标记。
|
||||
- *涉及文件*: `DATA_MODEL_PUBLIC.md`
|
||||
4. **Staff Resigned 恢复**: 离职员工复职(`rejoin`)后,其 `status` 是回到 `probation` 还是 `active`?
|
||||
- *涉及文件*: `DATA_MODEL_ORG.md`
|
||||
@@ -36,6 +36,9 @@
|
||||
| 技术总纲 | [`TECH_STACK/TECH_STACK.md`](./TECH_STACK/TECH_STACK.md) | 跨模块技术决策、模块索引、测试策略 |
|
||||
| 数据模型总览 | [`DATA_MODEL/DATA_MODEL.md`](./DATA_MODEL/DATA_MODEL.md) | 全局数据架构与子文档索引 |
|
||||
| API 全局契约 | [`TECH_STACK/API_CONTRACT.md`](./TECH_STACK/API_CONTRACT.md) | 请求/响应、错误码、分页、上传下载规范 |
|
||||
| 本地开发与启动 | [`TECH_STACK/本地开发手册.md`](./TECH_STACK/本地开发手册.md) | 前置依赖、环境变量、`django-tenants` 初始化、种子数据、本地启动与验证 |
|
||||
| 路由与组件映射 | [`UI_DESIGN/ROUTES.md`](./UI_DESIGN/ROUTES.md) | 全局唯一权威:模块 → 页面 → URL → 复用组件 → 四态 |
|
||||
| 状态机权威 | [`DATA_MODEL/STATE_MACHINE.md`](./DATA_MODEL/STATE_MACHINE.md) | 全局唯一权威:所有实体生命周期与状态迁移规则 |
|
||||
| 测试规范 | [`TECH_STACK/测试规范.md`](./TECH_STACK/测试规范.md) | 测试流程、报告字段、CI 要求 |
|
||||
| 测试编号规则 | [`TEST_CASES/TEST_CASE_ID_SPEC.md`](./TEST_CASES/TEST_CASE_ID_SPEC.md) | `TC-FON-XXXXXX` 规则 |
|
||||
| 测试注册表 | [`TEST_CASES/TEST_CASE_REGISTRY.md`](./TEST_CASES/TEST_CASE_REGISTRY.md) | 测试编号水位与批次登记 |
|
||||
|
||||
260
Project/fonrey/TECH_STACK/本地开发手册.md
Normal file
260
Project/fonrey/TECH_STACK/本地开发手册.md
Normal file
@@ -0,0 +1,260 @@
|
||||
> For AI assistants: Read this entire file before writing any code. All decisions here are final.
|
||||
|
||||
# 本地开发手册 (Local Development Manual)
|
||||
|
||||
本手册为 Fonrey 项目本地环境搭建与开发验证的权威指南。旨在帮助新入场开发人员或 AI agent 快速启动项目并确保开发环境与生产环境的技术决策一致。
|
||||
|
||||
## §0 文档定位 + 变更历史表
|
||||
|
||||
| 日期 | 变更人 | 变更内容 | 版本 |
|
||||
|---|---|---|---|
|
||||
| 2026-06-04 | Sisyphus-Junior | 初始化本地开发手册,整合 ADR 与技术总纲决策 | v1.0 |
|
||||
|
||||
---
|
||||
|
||||
## §1 前置依赖
|
||||
|
||||
运行 Fonrey 前,请确保本地环境已安装以下基础组件:
|
||||
|
||||
- **操作系统**: 推荐 Linux (Ubuntu 22.04+) 或 macOS。Windows 用户建议使用 WSL2。
|
||||
- **Python**: 3.12+
|
||||
- **Node.js**: 20.x+ (用于 Tailwind CSS 编译)
|
||||
- **Docker & Docker Compose**: 必须,用于运行数据库、缓存与消息队列。
|
||||
- **PostgreSQL**: 16.x (通过 Docker 运行)
|
||||
- **Redis**: 7.x (通过 Docker 运行)
|
||||
- **浏览器**: 最新版 Google Chrome 或 Chromium (用于 Playwright E2E 测试)
|
||||
|
||||
---
|
||||
|
||||
## §2 仓库初始化
|
||||
|
||||
按照以下步骤克隆仓库并安装依赖:
|
||||
|
||||
```bash
|
||||
# 克隆仓库
|
||||
git clone <repository_url> fonrey
|
||||
cd fonrey
|
||||
|
||||
# 创建虚拟环境
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux/macOS
|
||||
# .\venv\Scripts\activate # Windows
|
||||
|
||||
# 安装 Python 依赖
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements/test.txt # 仅开发环境需要
|
||||
|
||||
# 安装前端依赖
|
||||
npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §3 环境变量 (`.env`)
|
||||
|
||||
在项目根目录创建 `.env` 文件。以下为必需项清单及示例值:
|
||||
|
||||
```bash
|
||||
# Django 基础配置
|
||||
DEBUG=True
|
||||
SECRET_KEY=django-insecure-development-key-change-me
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1,.fonrey.test
|
||||
|
||||
# 数据库配置 (需配合 Docker Compose)
|
||||
DATABASE_URL=postgres://fonrey_user:fonrey_password@localhost:5432/fonrey_db
|
||||
# 如果使用 PgBouncer
|
||||
# DATABASE_URL=postgres://fonrey_user:fonrey_password@localhost:6432/fonrey_db
|
||||
|
||||
# Redis 配置
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# Celery 配置
|
||||
CELERY_BROKER_URL=redis://localhost:6379/1
|
||||
CELERY_RESULT_BACKEND=redis://localhost:6379/1
|
||||
|
||||
# Cloudflare R2 / S3 存储 (本地开发推荐使用 MinIO)
|
||||
AWS_ACCESS_KEY_ID=minio_admin
|
||||
AWS_SECRET_ACCESS_KEY=minio_password
|
||||
AWS_STORAGE_BUCKET_NAME=fonrey-media
|
||||
AWS_S3_ENDPOINT_URL=http://localhost:9000
|
||||
AWS_S3_REGION_NAME=auto
|
||||
|
||||
# Sentry (本地开发可选)
|
||||
SENTRY_DSN=
|
||||
|
||||
# 加密密钥 (AES-256-GCM,必须为 32 字节 Base64)
|
||||
FIELD_ENCRYPTION_KEY=your-32-byte-base64-encoded-key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §4 数据库与缓存启动
|
||||
|
||||
推荐使用 Docker Compose 快速拉起基础服务。项目根目录应包含 `docker-compose.yml`:
|
||||
|
||||
```bash
|
||||
# 启动 PostgreSQL, Redis, MinIO
|
||||
docker-compose up -d
|
||||
|
||||
# 验证服务状态
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
**PgBouncer 提示**: 生产环境强制使用 PgBouncer 进行连接池管理。本地开发环境下,如果需要模拟高并发连接,可开启 docker-compose 中的 pgbouncer 服务并将 `DATABASE_URL` 指向 6432 端口。
|
||||
|
||||
---
|
||||
|
||||
## §5 django-tenants 初始化
|
||||
|
||||
由于项目采用 `django-tenants` 多租户架构,必须先初始化公共 Schema (public schema):
|
||||
|
||||
```bash
|
||||
# 1. 运行公共 Schema 的迁移
|
||||
python manage.py migrate_schemas --shared
|
||||
|
||||
# 2. 创建第一个租户 (手动交互或使用脚本)
|
||||
# 注意:在本地开发时,建议将租户域名映射到 .fonrey.test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §6 测试租户与种子数据
|
||||
|
||||
目前项目尚未完成自动化 seed 命令。建议通过以下方式手动创建测试环境:
|
||||
|
||||
### 6.1 创建初始租户 (建议命令)
|
||||
*预期放置位置: `apps/tenant/management/commands/setup_dev_tenant.py`*
|
||||
|
||||
```bash
|
||||
# 尚未实现,需后续补写。目前请进入 python shell 手动创建:
|
||||
python manage.py shell
|
||||
>>> from apps.tenant.models import Tenant, Domain
|
||||
>>> tenant = Tenant.objects.create(schema_name='test_tenant', name='测试经纪公司')
|
||||
>>> Domain.objects.create(domain='test.fonrey.test', tenant=tenant, is_primary=True)
|
||||
```
|
||||
|
||||
### 6.2 导入枚举种子数据
|
||||
```bash
|
||||
# 导入 ENUMS.md 定义的公共枚举值
|
||||
python manage.py loaddata shared/fixtures/enum_labels.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §7 后端启动
|
||||
|
||||
本地开发环境直接使用 Django 开发服务器即可。生产环境必须使用 Gunicorn + Uvicorn。
|
||||
|
||||
```bash
|
||||
# 本地开发模式
|
||||
python manage.py runserver 8000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §8 Celery 与 Celery Beat 启动
|
||||
|
||||
涉及异步任务(如图片处理、导出、配房)时,必须启动 Worker 和 Beat:
|
||||
|
||||
```bash
|
||||
# 启动 Worker
|
||||
celery -A core worker -l info
|
||||
|
||||
# 启动 Beat (定时任务)
|
||||
celery -A core beat -l info
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §9 前端资源
|
||||
|
||||
Fonrey 依赖 Tailwind CSS 进行样式构建。
|
||||
|
||||
```bash
|
||||
# 开发模式:监听文件变化并实时编译
|
||||
npm run dev
|
||||
|
||||
# 生产构建
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §10 静态资源与对象存储本地替代方案
|
||||
|
||||
本地开发建议使用 MinIO 替代 Cloudflare R2。
|
||||
|
||||
1. 修改 `.env` 中的 `AWS_S3_ENDPOINT_URL` 指向 MinIO 地址。
|
||||
2. 确保已手动或通过脚本创建了 `media` 和 `releases` 桶。
|
||||
3. 访问 `http://localhost:9001` 进入 MinIO 控制台。
|
||||
|
||||
---
|
||||
|
||||
## §11 测试运行手册
|
||||
|
||||
所有测试基于 `pytest` 运行。
|
||||
|
||||
### 11.1 运行单元与集成测试
|
||||
```bash
|
||||
# 运行全量测试
|
||||
pytest
|
||||
|
||||
# 按目录跑集成测试
|
||||
pytest tests/integration/property/
|
||||
|
||||
# 查看覆盖率
|
||||
pytest --cov=apps --cov=core
|
||||
```
|
||||
|
||||
### 11.2 运行 E2E 测试 (Playwright)
|
||||
```bash
|
||||
# 安装浏览器驱动 (仅需一次)
|
||||
playwright install chromium
|
||||
|
||||
# 运行 E2E
|
||||
pytest tests/e2e/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §12 dev / staging / production 配置差异表
|
||||
|
||||
| 配置项 | Local Dev | Staging | Production |
|
||||
|---|---|---|---|
|
||||
| DEBUG | True | False | False |
|
||||
| 多租户驱动 | django-tenants | django-tenants | django-tenants |
|
||||
| 数据库 | Postgres 16 | Postgres 16 (RDS/Self-host) | Postgres 16 + PgBouncer |
|
||||
| 存储服务 | MinIO (本地) | Cloudflare R2 | Cloudflare R2 |
|
||||
| 任务队列 | Redis | Redis | Redis (Cluster/Sentinel) |
|
||||
| 缓存 | Redis | Redis | Redis |
|
||||
| 静态资源 | 本地处理 | Cloudflare CDN | Cloudflare CDN |
|
||||
| 错误日志 | 控制台 | Sentry | Sentry + Grafana |
|
||||
| 服务运行器 | runserver | Gunicorn + Uvicorn | Gunicorn + Uvicorn + Nginx |
|
||||
|
||||
---
|
||||
|
||||
## §13 常见故障排查
|
||||
|
||||
- **schema 切换失败**: 检查 `django-tenants` 中间件是否已启用,且 `ALLOWED_HOSTS` 包含对应的子域名。
|
||||
- **R2 401**: 验证 `.env` 中的 AWS 凭证是否正确,桶是否存在。
|
||||
- **Celery 任务不执行**: 检查 Redis 是否连通,Worker 是否已启动,且任务是否使用了 `@tenant_task` 装饰器。
|
||||
- **HTMX 局刷 404**: 确认视图是否处理了 `HX-Request` 头,且 URL 路由配置正确。
|
||||
|
||||
---
|
||||
|
||||
## §14 关联文档索引
|
||||
|
||||
- [`AGENTS.md`](../AGENTS.md), 技术栈总览与禁止项
|
||||
- [`ADR.md`](../ADR.md), 关键技术决策追溯
|
||||
- [`TECH_STACK/测试规范.md`](./测试规范.md), 详细测试要求
|
||||
- [`DATA_MODEL/DATA_MODEL.md`](../DATA_MODEL/DATA_MODEL.md), 数据架构定义
|
||||
|
||||
---
|
||||
|
||||
## §15 待澄清/待补项
|
||||
|
||||
1. **种子数据脚本**: 尚未实现 `setup_dev_tenant` 命令,目前需手动在 Shell 创建租户。
|
||||
2. **MinIO 预设**: 需要一个初始化脚本自动创建所需的 S3 桶(media, releases)。
|
||||
3. **Playwright 浏览器环境**: 尚未在 CI 配置中固定特定 Chromium 版本,本地开发建议使用最新版。
|
||||
4. **系统配置 DDL**: `AGENTS.md` 提到系统配置 PRD 暂为空,对应的 DDL 迁移可能不完整。
|
||||
227
Project/fonrey/UI_DESIGN/ROUTES.md
Normal file
227
Project/fonrey/UI_DESIGN/ROUTES.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# Fonrey 路由与组件映射表 (ROUTES.md)
|
||||
|
||||
> **文档定位**:Fonrey MVP 全局路由与 UI 组件映射的权威来源。
|
||||
> **适用对象**:Web 开发、前端工程、后端视图开发。
|
||||
> **更新原则**:新增页面必须在此登记。URL 命名严格遵循 RESTful + Django 习惯。
|
||||
> **对齐基线**:本表与 `UI_DESIGN/*/*.md` 各模块设计文档对齐。模块设计文档的页面清单是权威,本文为汇总入口。
|
||||
|
||||
---
|
||||
|
||||
## 1. 通用约定
|
||||
|
||||
- **URL 规范**:资源复数形式 + 末尾斜杠(例如:`/properties/`)。
|
||||
- **多租户**:业务端 URL 不携带租户 ID(Schema 由 `django-tenants` 中间件按 subdomain 切换);平台管理后台为 `public` schema 下独立子域,前缀 `/admin/`。
|
||||
- **分页规范**:所有列表页强制使用 **Keyset 分页**。API 主参数统一为 `cursor`,禁止使用 `offset`。**过渡兼容**(MVP Phase 1 期,详见 `ADR-20260604-001`):已有 page-based 示例的模块可保留页码 UI 表现(页码导航 + 跳页),但后端 API 必须以 `cursor` 为主参数;`page` 仅作过渡输入且不得用于 1000 条以上数据集。MVP GA 后 1 个版本内须清理所有 page-based 示例。
|
||||
- **Tab 维度**:列表页的 Tab 切换统一以 query param `?tab=` 表达;切换走 HTMX 局刷,由后端根据 `tab` 返回对应数据。
|
||||
- **HTMX Partial 路径**:业务页面的局部刷新走 `/<resource>/_partials/<purpose>/`;与某条记录强绑定的子区块走 `/<resource>/<uuid>/<sub>/partial`。
|
||||
- **JSON-only API 端点**:对外暴露给前端 AJAX/HTMX 的纯数据端点统一前缀 `/api/`。
|
||||
- **组件引用**:本表"复用组件"列必须严格引用 [`UI_SYSTEM/组件清单.md`](../UI_SYSTEM/组件清单.md) 中的标准名称,统一双语形式 `English(中文)`。新增组件必须先入组件清单再在此引用,禁止造词。
|
||||
- **页面权威来源**:每个模块的路由细节、Tab/筛选、交互态以同模块下 `UI_DESIGN/<模块>/*_UI.md` 为准;本表仅做全局汇总。
|
||||
|
||||
---
|
||||
|
||||
## 2. 全局基础页面
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **仪表盘 (Dashboard)** | `/` | 统计页 | `Tab Navigation(标签页导航)`, `Collapsible Card Grid(折叠展开面板)` | **空**: 暂无统计数据(图表显示 0) / **加载**: Skeleton 占位 / **错误**: 全局 500 / **权限**: 重定向至登录 |
|
||||
| **404 错误页** | `/404/` | 错误页 | 无 | **空**: 不适用 / **加载**: 不适用 / **错误**: 展示 404 图文 / **权限**: 公开 |
|
||||
| **500 错误页** | `/500/` | 错误页 | 无 | **空**: 不适用 / **加载**: 不适用 / **错误**: 展示 500 图文 / **权限**: 公开 |
|
||||
| **403 无权限页** | `/403/` | 错误页 | 无 | **空**: 不适用 / **加载**: 不适用 / **错误**: 展示 403 图文 / **权限**: 已登录但无权 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 登录管理模块 (Account)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/登录管理/登录_UI.md`](./登录管理/登录_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **Tenant 识别页** | `/account/tenant/verify/` | 基础页 | 无 | **空**: 不适用 / **加载**: 提交按钮 Loading / **错误**: 租户未识别/网络错误内联提示 / **权限**: 公开 |
|
||||
| **登录页(密码 Tab)** | `/account/login/` | 基础页 | `Tab Navigation(标签页导航)` | **空**: 不适用 / **加载**: 提交按钮 Loading / **错误**: 凭证错误 / 锁定 / 禁用 / 会话过期 字段级提示 / **权限**: 公开 |
|
||||
| **登录页(验证码 Tab)** | `/account/login/?tab=otp` | 基础页 | `Tab Navigation(标签页导航)` | **空**: 不适用 / **加载**: OTP 发送 / 倒计时态 / **错误**: OTP 错误 / 过期 内联提示 / **权限**: 公开 |
|
||||
| **设置新密码页** | `/account/password/reset/` | 基础页 | 无 | **空**: 不适用 / **加载**: 强度校验态 + 提交 Loading / **错误**: 两次不一致/校验失败 内联提示 / **权限**: 仅通过 OTP 校验的合法 Token |
|
||||
| **退出登录** | `/account/logout/` | 处理页 | 无 | **空**: 不适用 / **加载**: 渐进式遮罩 / **错误**: Toast 提示 / **权限**: 仅登录用户 |
|
||||
| **(Partial) 租户识别** | `POST /api/auth/tenant/verify/` | API | — | **错误**: JSON 错误码 + 字段级提示 / **权限**: 公开 |
|
||||
| **(Partial) 密码登录** | `POST /api/auth/login/` | API | — | **错误**: JSON 错误码(凭证/锁定/禁用) / **权限**: 公开 |
|
||||
| **(Partial) OTP 发送** | `POST /api/auth/login/phone/` | API | — | **错误**: 频率限制/号码非法 / **权限**: 公开 |
|
||||
| **(Partial) 找回密码-请求** | `POST /api/auth/recover/password/request/` | API | — | **错误**: 账号不存在/限流 / **权限**: 公开 |
|
||||
| **(Partial) 找回密码-校验** | `POST /api/auth/recover/password/verify/` | API | — | **错误**: OTP 错误/过期 / **权限**: 公开 |
|
||||
| **(Partial) 找回密码-重置** | `POST /api/auth/recover/password/reset/` | API | — | **错误**: Token 过期/校验失败 / **权限**: 持有有效重置 Token |
|
||||
|
||||
---
|
||||
|
||||
## 4. 房源管理模块 (Property)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/房源管理/房源列表_UI.md`](./房源管理/房源列表_UI.md) / [`房源详情_UI.md`](./房源管理/房源详情_UI.md) / [`新增房源_UI.md`](./房源管理/新增房源_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **房源列表(全部)** | `/properties/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)`, `Toolbar(操作工具栏)`, `Export Button(导出按钮)`, `Smart Sort(智能排序)`, `Tab Navigation(标签页导航)` | **空**: 暂无房源(引导图 + 新增 CTA) / **加载**: 表格 Skeleton / **错误**: 列表刷新失败 Toast / **权限**: 403 遮罩 |
|
||||
| **房源列表(出售 Tab)** | `/properties/?tab=for_sale` | 列表页 | 同上 | 同上 |
|
||||
| **房源列表(出租 Tab)** | `/properties/?tab=for_rent` | 列表页 | 同上 | 同上 |
|
||||
| **房源列表(未挂牌 Tab)** | `/properties/?tab=unlisted` | 列表页 | 同上 | 同上 |
|
||||
| **房源列表(成交 Tab)** | `/properties/?tab=sold` | 列表页 | 同上 | 同上 |
|
||||
| **重复房源** | `/properties/duplicates/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无重复 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员/店长 |
|
||||
| **嫌疑号码** | `/properties/suspect-numbers/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无嫌疑号 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员/店长 |
|
||||
| **新增房源** | `/properties/create/` | 编辑页(独立) | `Tab Navigation(标签页导航)`, `Multi-select Tag Input(多选标签选择器)`, `Tree Select / Cascading Dropdown(树形下拉选择器)` | **空**: 字段默认值 / **加载**: 表单骨架屏 / **错误**: 422 字段级 / 500 Toast / **权限**: 仅有权经纪人 |
|
||||
| **房源详情** | `/properties/<uuid>/` | 详情页 | `Tab Navigation(标签页导航)`, `Accordion Progress Panel(可折叠进度检查面板)`, `Collapsible Card Grid(折叠展开面板)`, `Image Lightbox View(全屏图片灯箱预览器)` | **空**: 房源不存在(404) / **加载**: 模块化局部 Skeleton / **错误**: 详情加载失败 Toast / **权限**: 403 页面 |
|
||||
| **房源全量编辑** | `/properties/<uuid>/edit/` | 编辑页(独立) | `Tab Navigation(标签页导航)`, `Inline Edit Mode(页面级读写切换)`, `Multi-select Tag Input(多选标签选择器)` | **空**: 不适用 / **加载**: 表单骨架屏 / **错误**: 提交失败(422/500) / **权限**: 仅维护人/管理员 |
|
||||
| **挂牌历史** | `/properties/<uuid>/history/` | 子详情页 | `Collapsible Card Grid(折叠展开面板)` | **空**: 暂无挂牌记录 / **加载**: 列表 Skeleton / **错误**: Toast / **权限**: 403 遮罩 |
|
||||
| **(Partial) 写跟进** | `/properties/<uuid>/_partials/followup/` | Drawer | `Drawer / Slide-over Panel(右侧抽屉面板)`, `Tab Navigation(标签页导航)` | **加载**: Drawer 内 Loading / **错误**: 提交失败 Toast / **权限**: 仅参与经纪人 |
|
||||
| **(Partial) 相册管理** | `/properties/<uuid>/_partials/gallery/` | Modal | `Photo Gallery Manager(相册管理器)`, `Sortable Table with Drag Handle(带拖拽手柄的可排序表格)` | **空**: 暂无照片 / **加载**: 缩略图 Skeleton / **错误**: 上传失败 Toast / **权限**: 仅维护人/管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 客源管理模块 (Client)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/客源管理/客源列表_UI.md`](./客源管理/客源列表_UI.md) / [`客源详情_UI.md`](./客源管理/客源详情_UI.md) / [`新增客源_UI.md`](./客源管理/新增客源_UI.md) / [`编辑客源_UI.md`](./客源管理/编辑客源_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **私客列表(全部)** | `/clients/private/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)`, `Toolbar(操作工具栏)`, `Tab Navigation(标签页导航)` | **空**: 暂无客源(引导录入) / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 403 遮罩 |
|
||||
| **私客列表(求购 Tab)** | `/clients/private/?tab=buying` | 列表页 | 同上 | 同上 |
|
||||
| **私客列表(求租 Tab)** | `/clients/private/?tab=renting` | 列表页 | 同上 | 同上 |
|
||||
| **私客列表(暂缓 Tab,P2)** | `/clients/private/?tab=suspended` | 列表页 | 同上 | 同上 |
|
||||
| **公客列表(P2)** | `/clients/public/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无公客 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅店长/管理员 |
|
||||
| **成交客列表(P2)** | `/clients/transacted/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无成交客 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员 |
|
||||
| **重复客源** | `/clients/duplicates/?tab=transacted\|public` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)`, `Tab Navigation(标签页导航)` | **空**: 暂无重复 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员(成交/公客子集见 `ADR-20260604-002`) |
|
||||
| **客源回收站** | `/clients/deleted/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无回收 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员 |
|
||||
| **录入客源** | `/clients/create/` | 编辑页(独立) | `Tree Select / Cascading Dropdown(树形下拉选择器)`, `Multi-select Tag Input(多选标签选择器)` | **空**: 字段默认值 / **加载**: 表单 Loading / **错误**: 字段级 422 / 500 Toast / **权限**: 仅有权经纪人 |
|
||||
| **客源详情** | `/clients/<uuid>/` | 详情页 | `Tab Navigation(标签页导航)`, `Collapsible Card Grid(折叠展开面板)` | **空**: 客源不存在 / **加载**: 局部 Skeleton / **错误**: Toast / **权限**: 403 页面 |
|
||||
| **编辑客源** | `/clients/<uuid>/edit/` | 编辑页(独立) | `Tab Navigation(标签页导航)`, `Inline Edit Mode(页面级读写切换)`, `Tree Select / Cascading Dropdown(树形下拉选择器)` | **空**: 不适用 / **加载**: 表单 Loading / **错误**: 字段级 422 / **权限**: 仅归属人/首录人/管理员(其他重定向至详情 + Toast) |
|
||||
| **(Partial) 电话重复检测** | `POST /clients/check-duplicate-phone/` | API | — | **错误**: 返回橙色警告 Partial / **权限**: 仅有权经纪人 |
|
||||
| **(Partial) 跟进日志筛选/分页** | `/clients/<uuid>/follow-logs/partial/` | Partial | `Tab Navigation(标签页导航)` | **空**: 暂无跟进 / **错误**: Toast / **权限**: 仅参与经纪人 |
|
||||
| **(Partial) 带看记录筛选** | `/clients/<uuid>/viewings/partial/` | Partial | — | **空**: 暂无带看 / **错误**: Toast / **权限**: 仅参与经纪人 |
|
||||
| **(Partial) 客源解读刷新** | `/clients/<uuid>/insights/partial/` | Partial | — | **空**: 暂无洞察 / **错误**: Toast / **权限**: 仅参与经纪人 |
|
||||
| **(Partial) 配房筛选/分页** | `/clients/<uuid>/matches/partial/` | Partial | `Pagination(分页组件)` | **空**: 暂无匹配 / **错误**: Toast / **权限**: 仅参与经纪人 |
|
||||
| **(Partial) 查看号码** | `/clients/<uuid>/contacts/<cid>/reveal-phone/` | API | — | **错误**: 频次超限/无权 Toast / **权限**: 仅归属人/上级 |
|
||||
| **(Partial) 标记号码无效** | `PATCH /api/clients/<uuid>/contacts/<cid>/mark-invalid/` | API | — | **错误**: 422 / 500 Toast / **权限**: 仅归属人/管理员 |
|
||||
| **(Partial) 编辑基础信息弹窗** | `PATCH /api/clients/<uuid>/basic-info/` | Modal | `Modal Dialog(模态对话框)` | **错误**: 字段级 422 / **权限**: 仅归属人/管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 楼盘/区域管理模块 (Complex / Region)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/楼盘管理/楼盘列表_UI.md`](./楼盘管理/楼盘列表_UI.md) / [`楼盘详情_UI.md`](./楼盘管理/楼盘详情_UI.md) / [`区域管理_UI.md`](./楼盘管理/区域管理_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **楼盘列表** | `/complexes/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)`, `Toolbar(操作工具栏)` | **空**: 暂无楼盘 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 全员可见/不可改 |
|
||||
| **楼盘详情** | `/complexes/<uuid>/` | 详情页 | `Tab Navigation(标签页导航)`, `Collapsible Card Grid(折叠展开面板)` | **空**: 楼盘不存在 / **加载**: 局部 Skeleton / **错误**: Toast / **权限**: 全员可见 |
|
||||
| **区域/商圈管理** | `/regions/` | 设置页 | `Tree Select / Cascading Dropdown(树形下拉选择器)`, `Dynamic Form Table(动态可增删行表格)` | **空**: 暂无配置 / **加载**: 树形 Skeleton / **错误**: 保存失败 Toast / **权限**: 仅系统管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 组织人事模块 (Org / Staff)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/组织人事管理/组织人事_UI.md`](./组织人事管理/组织人事_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **组织架构** | `/org/` | 树形页 | `Tree Select / Cascading Dropdown(树形下拉选择器)`, `Drawer / Slide-over Panel(右侧抽屉面板)` | **空**: 暂无门店 / **加载**: 树形 Skeleton / **错误**: Toast / **权限**: 仅管理员 |
|
||||
| **人员列表** | `/staff/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)`, `Toolbar(操作工具栏)` | **空**: 暂无员工 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅管理员/店长 |
|
||||
| **人员详情** | `/staff/<uuid>/` | 详情页 | `Inline Edit Mode(页面级读写切换)`, `Collapsible Card Grid(折叠展开面板)` | **空**: 人员不存在 / **加载**: 局部 Skeleton / **错误**: Toast / **权限**: 仅本人/上级/管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 权限管理模块 (Permission)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/权限管理/权限管理_UI.md`](./权限管理/权限管理_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **角色权限配置** | `/permissions/roles/` | 设置页 | `Tab Navigation(标签页导航)`, `Dynamic Form Table(动态可增删行表格)`, `Drawer / Slide-over Panel(右侧抽屉面板)` | **空**: 暂无角色 / **加载**: 列表 Loading / **错误**: 配置失败 Toast / **权限**: 仅系统管理员 |
|
||||
| **人员权限分配** | `/permissions/assignments/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Tree Select / Cascading Dropdown(树形下拉选择器)` | **空**: 暂无分配 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅系统管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 系统配置模块 (Setting)
|
||||
|
||||
> 权威来源:[`UI_DESIGN/系统配置/系统配置_UI.md`](./系统配置/系统配置_UI.md) / [`首页设置_UI.md`](./系统配置/首页设置_UI.md)
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **全局参数配置** | `/settings/params/` | 设置页 | `Inline Edit Mode(页面级读写切换)`, `Dynamic Form Table(动态可增删行表格)`, `Multi-Table Independent Pagination(同页多表格独立分页)` | **空**: 暂无参数 / **加载**: 局部 Skeleton / **错误**: 保存失败 Toast / **权限**: 仅系统管理员 |
|
||||
| **首页设置** | `/settings/homepage/` | 设置页 | `Inline Edit Mode(页面级读写切换)`, `Collapsible Card Grid(折叠展开面板)` | **空**: 默认模板 / **加载**: 局部 Skeleton / **错误**: 保存失败 Toast / **权限**: 仅系统管理员 |
|
||||
| **关注楼盘** | `/settings/watch-complexes/` | 设置页 | `Tree Select / Cascading Dropdown(树形下拉选择器)`, `Multi-select Tag Input(多选标签选择器)` | **空**: 暂未关注 / **加载**: Tree Skeleton / **错误**: 保存失败 Toast / **权限**: 仅本人/管理员 |
|
||||
| **(Partial) 字段自定义** | `/settings/_partials/fields/` | Drawer | `Drawer / Slide-over Panel(右侧抽屉面板)`, `Sortable Table with Drag Handle(带拖拽手柄的可排序表格)` | **加载**: Drawer Loading / **错误**: 422 Toast / **权限**: 仅系统管理员 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 平台管理后台 (Platform Admin)
|
||||
|
||||
> 仅由平台超级管理员在 Public Schema 下访问,独立子域,统一前缀 `/admin/`。
|
||||
> 权威来源:[`UI_DESIGN/平台管理后台/平台管理后台_UI.md`](./平台管理后台/平台管理后台_UI.md) §3.1。
|
||||
|
||||
| 页面名称 | URL 路径 | 页面类型 | 复用组件 | 空/加载/错误/权限状态描述 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **平台管理员登录** | `/admin/login/` | 基础页 | 无 | **空**: 不适用 / **加载**: 提交按钮 Loading / **错误**: 凭证错误内联提示 / **权限**: 公开 |
|
||||
| **平台仪表盘** | `/admin/` | 统计页 | `Collapsible Card Grid(折叠展开面板)` | **空**: 暂无数据 / **加载**: Skeleton / **错误**: Toast / **权限**: 仅平台管理员 |
|
||||
| **租户列表** | `/admin/tenants/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)`, `Toolbar(操作工具栏)` | **空**: 暂无租户 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **新建租户** | `/admin/tenants/new/` | 编辑页(独立) | `Tab Navigation(标签页导航)`, `Multi-select Tag Input(多选标签选择器)` | **空**: 字段默认值 / **加载**: 表单 Loading / **错误**: 422 字段级 / **权限**: 仅平台超管 |
|
||||
| **租户详情 - 基本信息** | `/admin/tenants/<id>/` | 详情页 | `Tab Navigation(标签页导航)`, `Collapsible Card Grid(折叠展开面板)`, `Inline Edit Mode(页面级读写切换)` | **空**: 租户不存在 / **加载**: 局部 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **租户详情 - 用户管理** | `/admin/tenants/<id>/users/` | 子列表 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无用户 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **租户详情 - 套餐信息** | `/admin/tenants/<id>/plan/` | 子设置页 | `Inline Edit Mode(页面级读写切换)`, `Modal Dialog(模态对话框)` | **空**: 默认套餐 / **加载**: 局部 Skeleton / **错误**: 422 字段级 / **权限**: 仅平台超管 |
|
||||
| **租户详情 - 监控** | `/admin/tenants/<id>/monitoring/` | 子统计页 | `Collapsible Card Grid(折叠展开面板)` | **空**: 暂无指标 / **加载**: 图表 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **租户详情 - 备份记录** | `/admin/tenants/<id>/backups/` | 子列表 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无备份 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **租户详情 - 操作历史** | `/admin/tenants/<id>/history/` | 子列表 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无记录 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营/审计 |
|
||||
| **系统版本管理** | `/admin/system/versions/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)`, `Drawer / Slide-over Panel(右侧抽屉面板)` | **空**: 暂无版本 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管 |
|
||||
| **系统备份管理** | `/admin/system/backups/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)` | **空**: 暂无备份 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **监控与告警** | `/admin/monitoring/` | 统计页 | `Collapsible Card Grid(折叠展开面板)`, `Tab Navigation(标签页导航)` | **空**: 暂无告警 / **加载**: 图表 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营 |
|
||||
| **客户端版本管理** | `/admin/client-releases/` | 列表页 | `Data Table(数据表格)`, `Pagination(分页组件)`, `Drawer / Slide-over Panel(右侧抽屉面板)` | **空**: 暂无发布 / **加载**: 列表 Skeleton / **错误**: 发布失败 Toast / **权限**: 仅平台超管 |
|
||||
| **审计日志** | `/admin/audit-logs/` | 列表页 | `Data Table(数据表格)`, `Column Visibility Panel(自定义列显示)`, `Pagination(分页组件)` | **空**: 暂无日志 / **加载**: 表格 Skeleton / **错误**: Toast / **权限**: 仅平台超管/运营/审计 |
|
||||
| **管理员设置** | `/admin/settings/admins/` | 列表+设置 | `Data Table(数据表格)`, `Drawer / Slide-over Panel(右侧抽屉面板)`, `Inline Edit Mode(页面级读写切换)` | **空**: 暂无管理员 / **加载**: 表格 Skeleton / **错误**: 422 字段级 / **权限**: 仅平台超管 |
|
||||
|
||||
---
|
||||
|
||||
## X. 非 MVP 占位 (v2 规划)
|
||||
|
||||
- **移动端适配页**:`/m/` 起始的所有路由。
|
||||
- **合同管理**:`/contracts/`。
|
||||
- **财务结算**:`/finance/`。
|
||||
- **营销/三网发布**:`/marketing/`。
|
||||
- **新房模块**:`/new-houses/`。
|
||||
|
||||
---
|
||||
|
||||
## 附录 A: 页面状态定义 (Page States)
|
||||
|
||||
- **空 (Empty)**: 使用 `Empty State` 设计,包含图标、说明文案及主要行动点 (CTA)。
|
||||
- **加载 (Loading)**: 优先使用 `Skeleton` 骨架屏(针对表格、详情块);按钮操作使用 `Spinner` 及禁用态。
|
||||
- **错误 (Error)**:
|
||||
- 页面级:404/500 全屏错误页。
|
||||
- 异步/局部:通过 `HX-Trigger` 弹出 `fonrey:toast` 提示。
|
||||
- 表单:422 返回包含错误信息的 Partial,红色文字定位到字段。
|
||||
- **权限 (Permission)**:
|
||||
- 无权访问页面:重定向至 403 页面。
|
||||
- 无权操作按钮:不渲染该按钮或置灰。
|
||||
|
||||
---
|
||||
|
||||
## 附录 B: 页面类型定义 (Page Types)
|
||||
|
||||
- **列表页 (List)**: 主体为数据表格,含筛选、分页。
|
||||
- **详情页 (Detail)**: 多维展示单一资源,多为 Tab 布局。
|
||||
- **编辑页(独立) (Edit Page)**: 独立 URL 的全量表单页(非 Drawer/Modal)。
|
||||
- **设置页 (Setting)**: 多为左侧导航 + 右侧表单/列表,含读写切换。
|
||||
- **基础页 (Base)**: 独立布局,如登录、错误页。
|
||||
- **统计页 (Stats)**: 以指标卡 + 图表为主。
|
||||
- **子详情页 / 子列表 / 子设置页**: 嵌于某条记录上下文下的二级页面。
|
||||
- **Partial**: 供 HTMX 调用的局部 HTML 片段。
|
||||
- **API**: 仅返回 JSON / 局部 HTML 的端点,无独立页面。
|
||||
|
||||
---
|
||||
|
||||
## 附录 C: 与 UI_DESIGN 模块文档的对齐索引
|
||||
|
||||
| 模块 | 权威 UI 设计文档 |
|
||||
| :--- | :--- |
|
||||
| 登录 | [`UI_DESIGN/登录管理/登录_UI.md`](./登录管理/登录_UI.md) |
|
||||
| 房源 | [`房源列表_UI.md`](./房源管理/房源列表_UI.md) / [`房源详情_UI.md`](./房源管理/房源详情_UI.md) / [`新增房源_UI.md`](./房源管理/新增房源_UI.md) |
|
||||
| 客源 | [`客源列表_UI.md`](./客源管理/客源列表_UI.md) / [`客源详情_UI.md`](./客源管理/客源详情_UI.md) / [`新增客源_UI.md`](./客源管理/新增客源_UI.md) / [`编辑客源_UI.md`](./客源管理/编辑客源_UI.md) |
|
||||
| 楼盘/区域 | [`楼盘列表_UI.md`](./楼盘管理/楼盘列表_UI.md) / [`楼盘详情_UI.md`](./楼盘管理/楼盘详情_UI.md) / [`区域管理_UI.md`](./楼盘管理/区域管理_UI.md) |
|
||||
| 组织人事 | [`组织人事_UI.md`](./组织人事管理/组织人事_UI.md) |
|
||||
| 权限 | [`权限管理_UI.md`](./权限管理/权限管理_UI.md) |
|
||||
| 系统配置 | [`系统配置_UI.md`](./系统配置/系统配置_UI.md) / [`首页设置_UI.md`](./系统配置/首页设置_UI.md) |
|
||||
| 平台管理后台 | [`平台管理后台_UI.md`](./平台管理后台/平台管理后台_UI.md) |
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
#### 2.1.1 页面概述
|
||||
|
||||
- **URL**:`/properties/`(query params:`tab`, `status`, `grade`, `page`, `q`, `sort`, `order` 等)
|
||||
- **URL**:`/properties/`(query params:`tab`, `status`, `grade`, `cursor`, `q`, `sort`, `order` 等;分页采用 Keyset,详见 `ADR-20260604-001`)
|
||||
- **访问入口**:顶部全局导航栏「房源」菜单 → 默认进入全部房源列表
|
||||
- **页面职责**:展示经纪人名下(或门店/全司)的房源列表,支持多维度搜索筛选、批量操作、状态快览
|
||||
- **竞品参考截图**:
|
||||
@@ -738,7 +738,7 @@
|
||||
| 左侧 | 总条数「共 N 条」 |
|
||||
| 中间 | 页码导航:`← 上一页 [1] [2] [3] [4] [5] … [N] 下一页 →` |
|
||||
| 右侧 | 每页条数「20条/页 ▾」(选项:20/50/100)+ 跳页「跳至」+ 输入框 + 「页」 |
|
||||
| HTMX | `hx-get="/properties/" hx-vals='{"page": N}' hx-target="#property-list-container" hx-swap="innerHTML" hx-include="closest form"` |
|
||||
| HTMX | `hx-get="/properties/" hx-vals='{"cursor": LAST_ID}' hx-target="#property-list-container" hx-swap="innerHTML" hx-include="closest form"`(Keyset 分页,`LAST_ID` 为当前页最后一条 `id`;详见 `ADR-20260604-001`。MVP 过渡期允许保留页码 UI 表现,但 `cursor` 是后端主参数) |
|
||||
| 当前页 | `bg-primary-600 text-white rounded-md w-8 h-8 font-medium` |
|
||||
| 非当前页 | `text-neutral-600 hover:bg-neutral-100 rounded-md w-8 h-8` |
|
||||
|
||||
|
||||
175
Project/fonrey/Vibe Coding项目管理技巧.md
Normal file
175
Project/fonrey/Vibe Coding项目管理技巧.md
Normal file
@@ -0,0 +1,175 @@
|
||||
这是一个非常实际的问题。用 OpenCode(或类似 AI 编码工具)做长周期项目,核心挑战是**每次会话 AI 都是"失忆"的**,你需要一套机制让它快速恢复上下文。
|
||||
|
||||
以下是一套完整的项目管理方案:
|
||||
|
||||
---
|
||||
|
||||
## 核心思路:用文档作为 AI 的"外部记忆"
|
||||
|
||||
AI 没有跨会话记忆,但它每次都能读文件。所以你的目标是:**把项目状态写进文件,而不是靠 AI 记住。**
|
||||
|
||||
---
|
||||
|
||||
## 一、项目文档结构
|
||||
|
||||
在项目根目录维护以下几个关键文件:
|
||||
|
||||
```
|
||||
project-root/
|
||||
├── CLAUDE.md # AI 行为规则 + 项目概览(OpenCode 每次自动读取)
|
||||
├── TASK.md # 任务总表,P0/P1/P2 优先级
|
||||
├── PROGRESS.md # 每日进度日志(最重要)
|
||||
├── ARCHITECTURE.md # 技术架构
|
||||
└── .opencode/
|
||||
└── context.md # 会话级补充上下文(可选)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、最关键的文件:`PROGRESS.md`
|
||||
|
||||
这是你每天结束时必须更新的文件,格式建议如下:
|
||||
|
||||
```markdown
|
||||
# 项目进度日志
|
||||
|
||||
## 2025-01-15(今日)
|
||||
|
||||
### ✅ 已完成
|
||||
- [x] 实现了 PropertyListing 的 CRUD API
|
||||
- [x] 修复了权限校验的 bug(见 commit abc123)
|
||||
|
||||
### 🔄 进行中
|
||||
- [ ] 房源搜索功能(已完成 70%)
|
||||
- 已做:Elasticsearch 索引配置
|
||||
- 未做:前端搜索组件、过滤器逻辑
|
||||
- 卡点:全文搜索中文分词需要引入 IK 插件
|
||||
|
||||
### ⏭️ 明日计划
|
||||
- 完成搜索前端组件
|
||||
- 开始客源管理模块的数据模型
|
||||
|
||||
### 🐛 已知问题 / 技术债
|
||||
- PropertyImage 上传后缩略图生成有时失败,原因未查
|
||||
|
||||
### 📁 今日改动的关键文件
|
||||
- `apps/listings/views.py`
|
||||
- `apps/listings/serializers.py`
|
||||
- `templates/listings/search.html`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、`CLAUDE.md` — AI 的启动说明书
|
||||
|
||||
OpenCode 会自动读取项目根目录的 `CLAUDE.md`。把它写成"给 AI 的操作手册":
|
||||
|
||||
```markdown
|
||||
# Fonrey 项目 AI 开发规范
|
||||
|
||||
## 项目简介
|
||||
B2B SaaS 房产中介管理系统,Django + HTMX + Alpine.js + PostgreSQL
|
||||
|
||||
## 每次会话开始前,你必须做的事
|
||||
1. 阅读 `PROGRESS.md` 了解当前进度
|
||||
2. 阅读 `TASK.md` 了解当前 Sprint 目标
|
||||
3. 确认今天要完成哪个具体任务后再写代码
|
||||
|
||||
## 技术约束
|
||||
- 前端:HTMX + Alpine.js + Tailwind,禁止引入 React/Vue
|
||||
- 文件上传:统一用 FilePond
|
||||
- 权限:使用自定义 RBAC,不使用 django-guardian
|
||||
|
||||
## 代码规范
|
||||
- 所有新文件必须有注释说明用途
|
||||
- 每完成一个功能,更新 PROGRESS.md
|
||||
|
||||
## 禁止事项
|
||||
- 不要修改 DATA_MODEL.md 中已定稳的数据表结构
|
||||
- 不要在没有确认的情况下重构已有模块
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、每日工作流程
|
||||
|
||||
### 早上开始(2 分钟)
|
||||
|
||||
给 AI 发这条固定的"启动 prompt":
|
||||
|
||||
```
|
||||
请阅读 PROGRESS.md 和 TASK.md,告诉我:
|
||||
1. 昨天完成了什么
|
||||
2. 今天应该继续做什么
|
||||
3. 有没有未解决的卡点
|
||||
|
||||
然后我们开始今天的工作。
|
||||
```
|
||||
|
||||
AI 读完文件后会给你一个摘要,你确认后直接开工。
|
||||
|
||||
### 晚上结束(5 分钟)
|
||||
|
||||
让 AI 帮你更新进度日志:
|
||||
|
||||
```
|
||||
今天的工作完成了,请帮我更新 PROGRESS.md:
|
||||
- 完成了:[你说]
|
||||
- 未完成的:[你说]
|
||||
- 明天继续:[你说]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、处理"卡点"和"上下文切换"
|
||||
|
||||
### 当你在一个功能里遇到复杂问题时
|
||||
|
||||
创建一个临时文件 `SCRATCH.md`:
|
||||
|
||||
```markdown
|
||||
# 当前卡点:中文全文搜索
|
||||
|
||||
## 问题描述
|
||||
PostgreSQL tsvector 对中文分词支持差
|
||||
|
||||
## 已尝试的方案
|
||||
1. 方案A:用 zhparser - 失败,原因 xxx
|
||||
2. 方案B:用 pg_jieba - 待验证
|
||||
|
||||
## 当前倾向
|
||||
方案B,明天继续
|
||||
```
|
||||
|
||||
下次会话告诉 AI:"先读 SCRATCH.md",秒回上下文。
|
||||
|
||||
### 当你需要切换模块时
|
||||
|
||||
在 PROGRESS.md 里明确标记"暂停点",记录文件名和函数名,这比描述更精确。
|
||||
|
||||
---
|
||||
|
||||
## 六、可选增强:Git commit 作为进度锚点
|
||||
|
||||
养成每完成一个小功能就 commit 的习惯,commit message 写清楚:
|
||||
|
||||
```
|
||||
feat(listings): 完成房源搜索 API,支持关键词+区域过滤
|
||||
|
||||
TODO: 前端搜索组件待完成
|
||||
```
|
||||
|
||||
这样 AI 可以通过 `git log --oneline -20` 快速看到最近的工作轨迹,作为 PROGRESS.md 的补充。
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
|文件|作用|更新频率|
|
||||
|---|---|---|
|
||||
|`CLAUDE.md`|AI 行为规范,一次写好|很少改|
|
||||
|`TASK.md`|任务总表|每周调整|
|
||||
|`PROGRESS.md`|每日进度日志|**每天必更新**|
|
||||
|`SCRATCH.md`|当前卡点临时笔记|按需|
|
||||
|
||||
**最核心的一句话:每天花 5 分钟更新 `PROGRESS.md`,比什么方法都有效。** AI 能读文件,但它读不了你的脑子——把脑子里的状态写进文件,问题就解决了。
|
||||
Reference in New Issue
Block a user