文档更新
This commit is contained in:
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`
|
||||
Reference in New Issue
Block a user