Files
KSP_project/reference/location_state_node_redesign.md
ArmorandClaude Opus 4.7 e1d601a774 chore: add reference docs, scripts, tests, demo, prototypes
- Reference docs: known issues, user journey, location redesign, mission merge plan
- Scripts: fill_location_state, merge_missions, migrate_location, migrate_state
- Tests: e2e test suite, asset entries unit tests
- Demo: location board, hifi prototypes, test screenshots
- Data backup: asset log entries and state nodes
- Update .gitignore

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 15:29:47 +08:00

86 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Location & State Label 从 Interval 迁移到 State Node
## 设计决策
**`location``state_label` 不再绑定到 `asset_log_entries`state interval),而绑定到 `asset_state_nodes`state node)。**
### 动机
合并 Outbound/Operations/Inbound 后,一个任务条目会跨越多个 location 和 state
- 出发段 → location=Transfer, state=Transfer
- 到达后 → location=Mars, state=Surface Expedition
- 返航段 → location=Transfer, state=Transfer
如果把 location/state_label 保留在 interval 级别,合并后的条目只能有一个 location 和一个 state_label,无法表达任务过程中的变化。
移到 state node 后,每个时间节点可以独立标注位置和状态,时间线渲染也更精准。
### 数据库变更
#### `asset_log_entries` — 删除列
```sql
ALTER TABLE asset_log_entries DROP COLUMN location;
ALTER TABLE asset_log_entries DROP COLUMN state_label;
```
#### `asset_state_nodes` — 新增列
```sql
ALTER TABLE asset_state_nodes ADD COLUMN location VARCHAR(255);
ALTER TABLE asset_state_nodes ADD COLUMN state_label VARCHAR(120);
```
### 数据迁移
现有 interval 的 `location``state_label` 迁移到该 interval 的第一个 state node
- 如果 interval 已有 state node → 将 location/state_label 写入按时间排序的第一个 node
- 如果 interval 无 state node → 创建一个 state nodeat_time = interval.start_at, title = interval.title),写入 location/state_label
### 后端变更
#### Model 层 (`app/models.py`)
```python
# AssetLogEntry: 删除 location 和 state_label 字段
class AssetLogEntry(TimestampMixin, db.Model):
# 删除: location, state_label
...
# AssetStateNode: 新增 location 和 state_label 字段
class AssetStateNode(TimestampMixin, db.Model):
...
location: Mapped[str | None] = mapped_column(String(255))
state_label: Mapped[str | None] = mapped_column(String(120))
```
#### 表单 (`app/templates/asset_entry_form.html`)
- 移除 interval 级别的 location / state_label 输入
- 在 state node 行内增加 location / state_label 输入(每个 node 独立设置)
- Event point 保留 location 字段(作为该时间点的快照)
#### 资产详情 (`app/templates/asset_detail.html`)
- 当前位置:从最近的一个 state node 的 location 派生(而非当前活跃 interval)
- 当前状态:同上,从最近 state node 的 state_label 派生
#### 看板 / 时间线
- 时间线上每个 state node 显示其自身的 location 和 state_label
- 看板按 location/state 分组时,以最新 state node 为准
### 对现有数据的影响
| 表 | 操作 |
|----|------|
| `asset_log_entries` | DROP location, state_label |
| `asset_state_nodes` | ADD location, state_label |
| 现有 interval 数据 | 迁移到首个 state node |
| 表单模板 | 重构 |
| 详情/看板/时间线 | 改为从 state node 读取 |
### 实施顺序
1. **先做合并**mission_merge_plan.md)— 减少条目数,简化后续迁移
2. **再做列迁移**(本文档)— 将 location/state_label 下沉到 state node
3. **最后改前端**— 表单、详情、看板、时间线逐一适配