docs: add P7 character graph and P9 writing analytics design spec for v1.0.0
Define Cytoscape relationship graph MVP, writing_sessions telemetry, and cockpit analytics cards for the v1.0.0 release. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,444 @@
|
||||
# 笔临 P7 角色关系图谱 + P9 个人写作分析 设计规格
|
||||
|
||||
**版本**:1.0
|
||||
**日期**:2026-07-08
|
||||
**范围**:§7 角色关系图谱 MVP + §9 个人写作分析 MVP(含 `writing_sessions` 精确采集)
|
||||
**前置**:P5.3 + P6.1 已交付(v0.9.0,`d4122c8`);P5.2 写作日志 / 热力图 / 番茄(v0.8.0)
|
||||
**参考**:`design/readme.md` v1.1 §7 / §9、`design/ui_pc.html` `#graphModal` / `#dashboardModal`
|
||||
|
||||
**目标版本**:v1.0.0
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 阶段定位
|
||||
|
||||
v0.9.0 已完成作家工作流核心链路(驾驶舱、日志、番茄、知识库、AI 上下文、注入历史)。`design/readme.md` §7 **角色关系图谱** 与 §9 **个人写作分析** 仍为概念/原型状态(`#graphModal` 为静态 demo,分析卡片无真实数据源)。
|
||||
|
||||
本阶段(v1.0.0)统一 MVP 交付:
|
||||
|
||||
- **P7(§7)**:基于 `settings` 角色设定 + `properties.relationships` 的可视化关系图谱
|
||||
- **P9(§9)**:基于 `writing_sessions` + 现有 `writing_logs` / `pomodoro_daily` 的驾驶舱分析区
|
||||
|
||||
### 1.2 已确认决策(Brainstorming 2026-07-08)
|
||||
|
||||
| 维度 | 决策 |
|
||||
|------|------|
|
||||
| 交付策略 | **方案 3**:C + D 统一 MVP,单版 v1.0.0 |
|
||||
| 分析数据采集 | **方案 A**:新增 `writing_sessions` 表,编辑活跃时精确记录 |
|
||||
| 关系存储 | **`settings.properties.relationships[]` JSON**,不新增每书关系表 |
|
||||
| 每书 schema | **保持 v8**,不迁移;`chapters.pov_character_id` 已有,补 UI |
|
||||
| 全局 sqlite | **扩展 `writing_logs.sqlite`**(与 `writing_logs` / `pomodoro_daily` 同库) |
|
||||
| 图谱库 | **Cytoscape.js + cose-bilkent**(渲染进程) |
|
||||
| Session 合并 | 同一书籍连续写作,间隔 **≤ 5 分钟** 合并为同一 session |
|
||||
| 图谱上限 | **100 角色节点**;超出 toast 提示,仍可按「仅有关系的节点」筛选展示 |
|
||||
| 边去重 | 单向存储;渲染时 A↔B 去重,取较高 `intimacy` |
|
||||
| 分析入口 | **仅驾驶舱内嵌卡片**,不做独立全屏分析页 |
|
||||
| POV | 章节元数据下拉绑定 `pov_character_id` → 分析 POV 字数分布 |
|
||||
|
||||
### 1.3 验收标准
|
||||
|
||||
用户能完成:
|
||||
|
||||
1. 在设定面板为角色添加/编辑/删除关系(目标角色、描述、亲密度 1–5),保存后在关系图谱中可见对应边
|
||||
2. 打开 **角色关系图谱** 全屏模态,看到力导向布局下的角色节点与关系边;可切换 grid / circle 布局
|
||||
3. 点击节点 → 侧栏显示角色名与「编辑设定」跳转;点击边 → 侧栏编辑关系描述与亲密度
|
||||
4. 在章节编辑区设置 **POV 角色**,驾驶舱 POV 分布反映该角色章节字数
|
||||
5. 在章节编辑器写作并保存后,驾驶舱 **今日写作速度**(字/分钟)> 0;**24 小时时段热力**有数据
|
||||
6. 驾驶舱展示:7 日字数趋势、番茄今日次数与均字/次、按卷字数占比(与现有字数聚合一致)
|
||||
|
||||
### 1.4 本规格不实现(明确排除)
|
||||
|
||||
| 项 | 归属 |
|
||||
|----|------|
|
||||
| AI 章节分析后自动关系建议(§7.2-3) | v1.1+ |
|
||||
| 图谱中右键拖拽连线创建关系 | v1.1+ |
|
||||
| 知识抽取面板「关系建议」一键添加 | v1.1+ |
|
||||
| 预计完本日期 | §9 后续 |
|
||||
| 角色弧线简报三节时间线(§20.3) | v1.1+ |
|
||||
| 独立全屏「数据分析」页、书籍设置分析 Tab | 后续 |
|
||||
| 导入导出、章节模板(§10 / §11) | 其他阶段 |
|
||||
| 故事时间线模态(§5.7) | 其他阶段 |
|
||||
| 设定条目(非 character)进入关系图谱 | 排除 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 架构
|
||||
|
||||
### 2.1 进程模型
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 主进程(userData writing_logs.sqlite 扩展) │
|
||||
│ · WritingSessionRepository / WritingSessionService │
|
||||
│ · WritingAnalyticsService(聚合 sessions + logs + pomodoro + 章节) │
|
||||
│ · ChapterWritingTracker.recordDelta → session.recordActivity │
|
||||
└──────────────────────────────┬──────────────────────────────────────┘
|
||||
│
|
||||
┌──────────────────────────────▼──────────────────────────────────────┐
|
||||
│ 主进程(每书 .sqlite,schema v8) │
|
||||
│ · CharacterGraphService(读 settings,写 properties.relationships) │
|
||||
│ · SettingRepository(已有) │
|
||||
│ · ChapterRepository.pov_character_id(已有) │
|
||||
└──────────────────────────────┬──────────────────────────────────────┘
|
||||
│ IPC
|
||||
┌──────────────────────────────▼──────────────────────────────────────┐
|
||||
│ 渲染进程 │
|
||||
│ · CharacterGraphModal(Cytoscape + 侧栏) │
|
||||
│ · SettingRelationshipsEditor(角色设定页关系 CRUD) │
|
||||
│ · CockpitModal 扩展 analytics 区块 │
|
||||
│ · ChapterHeader / ChapterList:POV 下拉 │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 模块边界
|
||||
|
||||
| 模块 | 职责 | 依赖 |
|
||||
|------|------|------|
|
||||
| `WritingSessionService` | 活跃 session 状态机;5 分钟 idle 切分;`recordActivity` | `WritingSessionRepository` |
|
||||
| `WritingAnalyticsService` | `getSummary(bookId)` 聚合分析指标 | sessions, logs, pomodoro, chapters, settings |
|
||||
| `CharacterGraphService` | 构建 nodes/edges;CRUD 关系;边去重 | `SettingRepository` |
|
||||
| `ChapterWritingTracker` | 已有字数 delta → **扩展**调用 session | `WritingLogService`, `WritingSessionService` |
|
||||
| `CharacterGraphModal` | Cytoscape 渲染与布局切换 | preload `graph.*` |
|
||||
| `CockpitModal` | 展示 `WritingAnalyticsSummary` | preload `analytics.getSummary` |
|
||||
|
||||
**原则**:
|
||||
|
||||
- Session 写入与 `writing_logs` 共用 `recordDelta` 路径,**不重复计字**
|
||||
- 图谱数据以 `settings` 为唯一真相源;Cytoscape 元素由 IPC 返回的 DTO 构建
|
||||
- 分析服务只读;失败时驾驶舱分析区显示占位/空态,不阻断驾驶舱其他卡片
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据模型
|
||||
|
||||
### 3.1 全局 userData:扩展 `writing_logs.sqlite`
|
||||
|
||||
在 `WritingLogRepository.migrate()` 追加:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS writing_sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
book_id TEXT NOT NULL,
|
||||
chapter_id TEXT,
|
||||
started_at TEXT NOT NULL,
|
||||
ended_at TEXT NOT NULL,
|
||||
word_delta INTEGER NOT NULL DEFAULT 0,
|
||||
date TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_book_date
|
||||
ON writing_sessions (book_id, date);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_book_started
|
||||
ON writing_sessions (book_id, started_at);
|
||||
```
|
||||
|
||||
**Session 状态机**(`WritingSessionService`):
|
||||
|
||||
| 事件 | 行为 |
|
||||
|------|------|
|
||||
| `recordActivity(bookId, chapterId, delta)` | 若无活跃 session 或距上次 `ended_at` > 5min → `INSERT` 新 session;否则 `UPDATE ended_at, word_delta += delta` |
|
||||
| `endActive(bookId)` | 书籍切换 / 应用退出前结束活跃 session |
|
||||
| `delta === 0` | 忽略(不创建空 session) |
|
||||
|
||||
活跃 session 可在主进程内存缓存 `{ bookId, sessionId, lastEndedAt }`,DB 为持久真相。
|
||||
|
||||
### 3.2 角色关系 JSON(每书 `settings.properties`)
|
||||
|
||||
```typescript
|
||||
interface CharacterRelationship {
|
||||
id: string
|
||||
targetId: string
|
||||
label: string
|
||||
intimacy: 1 | 2 | 3 | 4 | 5
|
||||
}
|
||||
|
||||
// SettingEntry.properties.relationships?: CharacterRelationship[]
|
||||
// 仅 type === 'character' 时读写
|
||||
```
|
||||
|
||||
**边去重规则**(渲染):对无序对 `{A,B}` 仅输出一条边;若 A→B 与 B→A 均存在,取 `max(intimacy)`,`label` 优先取较高亲密度源的 label。
|
||||
|
||||
**CRUD**:
|
||||
|
||||
- `upsertRelationship(sourceId, { id?, targetId, label, intimacy })` — 更新源角色 `properties.relationships`
|
||||
- `deleteRelationship(sourceId, relationshipId)`
|
||||
- 禁止 `targetId === sourceId`;禁止指向非 character 设定
|
||||
|
||||
### 3.3 POV(已有)
|
||||
|
||||
- DB 列:`chapters.pov_character_id`(schema v8 已有 `tryAlter`)
|
||||
- UI:章节编辑器工具栏或章节列表元数据区,`select` 绑定 `type='character'` 设定
|
||||
- IPC:复用 `chapter.update` patch `{ povCharacterId }`
|
||||
|
||||
### 3.4 类型扩展(`src/shared/types.ts`)
|
||||
|
||||
```typescript
|
||||
export interface CharacterGraphNode {
|
||||
id: string
|
||||
label: string
|
||||
}
|
||||
|
||||
export interface CharacterGraphEdge {
|
||||
id: string
|
||||
source: string
|
||||
target: string
|
||||
label: string
|
||||
intimacy: 1 | 2 | 3 | 4 | 5
|
||||
}
|
||||
|
||||
export interface CharacterGraphData {
|
||||
nodes: CharacterGraphNode[]
|
||||
edges: CharacterGraphEdge[]
|
||||
truncated: boolean
|
||||
nodeCount: number
|
||||
}
|
||||
|
||||
export interface WritingAnalyticsSummary {
|
||||
todayWords: number
|
||||
todaySpeedWpm: number | null
|
||||
weekTrend: { date: string; words: number }[]
|
||||
hourlyHeatmap: number[] // length 24
|
||||
pomodoroToday: number
|
||||
pomodoroAvgWords: number | null
|
||||
povDistribution: { characterId: string; name: string; words: number }[]
|
||||
volumeDistribution: { volumeId: string; title: string; words: number }[]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 服务层设计
|
||||
|
||||
### 4.1 WritingAnalyticsService
|
||||
|
||||
```typescript
|
||||
getSummary(bookId: string): WritingAnalyticsSummary
|
||||
```
|
||||
|
||||
| 字段 | 计算方式 |
|
||||
|------|----------|
|
||||
| `todayWords` | `WritingLogService.getStats(bookId).todayWords` |
|
||||
| `todaySpeedWpm` | 今日 sessions:`sum(word_delta) / sum(minutes(ended_at - started_at))`;无 session 或零时长 → `null` |
|
||||
| `weekTrend` | 近 7 天 `writing_logs` 按 date |
|
||||
| `hourlyHeatmap` | 近 30 天 sessions,按 `started_at` 小时 bucket 累加 `word_delta`(24 槽) |
|
||||
| `pomodoroToday` | `PomodoroDailyRepository.getTodayCount` |
|
||||
| `pomodoroAvgWords` | 今日 `total_words / completed_count`;count=0 → `null` |
|
||||
| `povDistribution` | chapters GROUP BY `pov_character_id` SUM `word_count`,JOIN character name |
|
||||
| `volumeDistribution` | chapters GROUP BY `volume_id` SUM `word_count` |
|
||||
|
||||
未设置 POV 的章节计入 `{ characterId: '__none__', name: i18n未指定 }` 或单独过滤(实现时选 **单独「未指定」桶**)。
|
||||
|
||||
### 4.2 CharacterGraphService
|
||||
|
||||
```typescript
|
||||
getData(bookId: string, filter?: 'all' | 'connected'): CharacterGraphData
|
||||
upsertRelationship(bookId, sourceId, input): CharacterRelationship
|
||||
deleteRelationship(bookId, sourceId, relationshipId): void
|
||||
```
|
||||
|
||||
- `filter: 'connected'`:仅包含有至少一条边的节点(用于超 100 节点时的降级展示)
|
||||
- `truncated: true` 当 character 总数 > 100
|
||||
|
||||
### 4.3 ChapterWritingTracker 扩展
|
||||
|
||||
```typescript
|
||||
recordDelta(chapterId: string, newWordCount: number): void {
|
||||
// 现有 writing_logs delta 逻辑不变
|
||||
if (delta !== 0) {
|
||||
this.writingLogs.addToday(this.bookId, delta)
|
||||
this.sessions.recordActivity(this.bookId, chapterId, delta)
|
||||
}
|
||||
// snapshot upsert 不变
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. IPC 与 preload
|
||||
|
||||
```typescript
|
||||
// ipc-channels.ts
|
||||
GRAPH_GET_DATA: 'graph:getData',
|
||||
GRAPH_UPSERT_RELATIONSHIP: 'graph:upsertRelationship',
|
||||
GRAPH_DELETE_RELATIONSHIP: 'graph:deleteRelationship',
|
||||
ANALYTICS_SUMMARY: 'analytics:summary',
|
||||
```
|
||||
|
||||
| 通道 | 参数 | 返回 |
|
||||
|------|------|------|
|
||||
| `graph:getData` | `{ bookId, filter? }` | `IpcResult<CharacterGraphData>` |
|
||||
| `graph:upsertRelationship` | `{ bookId, sourceId, relationship }` | `IpcResult<CharacterRelationship>` |
|
||||
| `graph:deleteRelationship` | `{ bookId, sourceId, relationshipId }` | `IpcResult<void>` |
|
||||
| `analytics:summary` | `{ bookId }` | `IpcResult<WritingAnalyticsSummary>` |
|
||||
|
||||
`cockpit:getSummary` **不合并** analytics(保持单一职责);驾驶舱 UI 并行请求 `cockpit.getSummary` + `analytics.getSummary`,或在 renderer 层 `Promise.all`。
|
||||
|
||||
---
|
||||
|
||||
## 6. UI 规格
|
||||
|
||||
### 6.1 角色关系图谱(`CharacterGraphModal`)
|
||||
|
||||
参考 `design/ui_pc.html` `#graphModal`。
|
||||
|
||||
| 元素 | testid | 说明 |
|
||||
|------|--------|------|
|
||||
| 模态 | `character-graph-modal` | 宽屏 `modal-content--wide` |
|
||||
| Cytoscape 容器 | `character-graph-cy` | 最小高度 480px |
|
||||
| 布局按钮 | `graph-layout-cose` / `grid` / `circle` | |
|
||||
| 侧栏 | `character-graph-sidebar` | 节点/边详情 |
|
||||
| 设定入口按钮 | `setting-open-graph` | 设定面板工具栏 |
|
||||
|
||||
**亲密度配色**(边 `line-color`):
|
||||
|
||||
| intimacy | 颜色 |
|
||||
|----------|------|
|
||||
| 1 | `#4ea8de` 蓝 |
|
||||
| 2 | `#45b7aa` 青 |
|
||||
| 3 | `#3fb950` 绿 |
|
||||
| 4 | `#f0883e` 橙 |
|
||||
| 5 | `#e0556a` 红 |
|
||||
|
||||
**Cytoscape 依赖**(渲染进程):`cytoscape`、`cytoscape-cose-bilkent`;destroy 于 modal 关闭。
|
||||
|
||||
### 6.2 设定面板关系编辑(`SettingRelationshipsEditor`)
|
||||
|
||||
- 嵌入角色设定编辑区(TipTap 下方或侧栏,当 `type === 'character'`)
|
||||
- 列表:目标角色名、label、亲密度、删除
|
||||
- 添加:目标角色下拉(排除自身)、label 输入、intimacy range 1–5
|
||||
- testid:`setting-relationships`、`setting-relationship-add`
|
||||
|
||||
### 6.3 驾驶舱分析区(`CockpitModal` 扩展)
|
||||
|
||||
| 卡片 | testid | 内容 |
|
||||
|------|--------|------|
|
||||
| 分析区容器 | `cockpit-analytics` | |
|
||||
| 今日速度 | `cockpit-speed-today` | `{{wpm}} 字/分钟` 或 `—` |
|
||||
| 时段热力 | `cockpit-hourly-heatmap` | 24 格横条 |
|
||||
| POV 分布 | `cockpit-pov-chart` | Top 5 横向条 |
|
||||
| 按卷占比 | `cockpit-volume-chart` | 卷名字 + 字数 |
|
||||
| 7 日趋势 | `cockpit-week-trend` | 7 柱 mini chart |
|
||||
|
||||
驾驶舱底部增加「打开关系图谱」按钮:`cockpit-open-graph`。
|
||||
|
||||
### 6.4 章节 POV
|
||||
|
||||
- 位置:章节编辑器标题栏或 `#editor-statusbar` 附近
|
||||
- testid:`chapter-pov-select`
|
||||
- 选项:空(未指定)+ 所有 character 设定
|
||||
- 变更时 debounce 调用 `chapter.update`
|
||||
|
||||
---
|
||||
|
||||
## 7. i18n 键(节选)
|
||||
|
||||
```json
|
||||
"graph.title": "角色关系图谱",
|
||||
"graph.layout.cose": "力导向",
|
||||
"graph.layout.grid": "网格",
|
||||
"graph.layout.circle": "圆形",
|
||||
"graph.truncated": "角色过多,仅显示前 {{count}} 个",
|
||||
"graph.sidebar.node": "角色:{{name}}",
|
||||
"graph.sidebar.edge": "关系:{{label}}",
|
||||
"graph.editSetting": "编辑设定",
|
||||
"relationship.title": "角色关系",
|
||||
"relationship.add": "添加关系",
|
||||
"relationship.target": "目标角色",
|
||||
"relationship.label": "关系描述",
|
||||
"relationship.intimacy": "亲密度",
|
||||
"analytics.title": "写作分析",
|
||||
"analytics.speedToday": "今日 {{wpm}} 字/分钟",
|
||||
"analytics.speedUnknown": "暂无速度数据",
|
||||
"analytics.hourlyHeatmap": "写作时段(近30天)",
|
||||
"analytics.povDistribution": "视角字数分布",
|
||||
"analytics.volumeDistribution": "按卷字数",
|
||||
"analytics.weekTrend": "近 7 日字数",
|
||||
"analytics.povUnassigned": "未指定视角",
|
||||
"chapter.pov": "视角角色",
|
||||
"cockpit.openGraph": "角色关系图谱"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 测试要求
|
||||
|
||||
### 8.1 单元 / 集成
|
||||
|
||||
| 用例ID | 层级 | 场景 | 预期 |
|
||||
|--------|------|------|------|
|
||||
| UT-SESSION-01 | 单元 | 5min 内两次 recordActivity | 同一 session,word_delta 累加 |
|
||||
| UT-SESSION-02 | 单元 | 间隔 6min 两次 recordActivity | 两个 session |
|
||||
| UT-SESSION-03 | 单元 | delta=0 | 不创建 session |
|
||||
| UT-GRAPH-01 | 单元 | 3 角色 2 关系 getData | nodes=3, edges=2 |
|
||||
| UT-GRAPH-02 | 单元 | A→B 与 B→A 双向存储 | 渲染 1 条边,intimacy 取 max |
|
||||
| UT-GRAPH-03 | 单元 | 101 个 character | truncated=true |
|
||||
| UT-ANALYTICS-01 | 单元 | 2 个 session 共 100 字 / 10 分钟 | todaySpeedWpm=10 |
|
||||
| UT-ANALYTICS-02 | 单元 | hourlyHeatmap | 24 长度,对应小时有值 |
|
||||
| IT-ANALYTICS-01 | 集成 | chapter update → recordDelta → getSummary | todaySpeedWpm > 0 |
|
||||
| IT-GRAPH-01 | 集成 | upsertRelationship → getData | 边可见 |
|
||||
|
||||
### 8.2 E2E
|
||||
|
||||
| 用例ID | 场景 | 预期 |
|
||||
|--------|------|------|
|
||||
| E2E-GRAPH-01 | 打开关系图谱 | 力导向图可见节点 |
|
||||
| E2E-GRAPH-02 | 点击节点 | 侧栏显示角色名 |
|
||||
| E2E-GRAPH-03 | 切换圆形布局 | 布局变化 |
|
||||
| E2E-GRAPH-04 | 设定面板添加关系 | 图谱出现新边 |
|
||||
| E2E-ANALYTICS-01 | 写作保存后打开驾驶舱 | `cockpit-speed-today` 有数值 |
|
||||
| E2E-ANALYTICS-02 | 设置 POV 后刷新驾驶舱 | POV chart 含该角色 |
|
||||
|
||||
**E2E 图谱**:不依赖 AI / LM Studio。
|
||||
|
||||
---
|
||||
|
||||
## 9. 文件清单(实现阶段参考)
|
||||
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| `src/main/db/repositories/writing-session.repo.ts` | sessions CRUD |
|
||||
| `src/main/services/writing-session.service.ts` | 状态机 |
|
||||
| `src/main/services/writing-analytics.service.ts` | 分析聚合 |
|
||||
| `src/main/services/character-graph.service.ts` | 图谱 DTO + 关系 CRUD |
|
||||
| `src/main/ipc/handlers/graph.handler.ts` | 图谱 IPC |
|
||||
| `src/main/ipc/handlers/analytics.handler.ts` | 分析 IPC |
|
||||
| `src/renderer/components/graph/CharacterGraphModal.tsx` | Cytoscape UI |
|
||||
| `src/renderer/components/setting/SettingRelationshipsEditor.tsx` | 关系 CRUD |
|
||||
| `src/renderer/components/cockpit/CockpitAnalytics.tsx` | 分析卡片 |
|
||||
| `src/renderer/components/cockpit/HourlyHeatmap.tsx` | 24 槽热力 |
|
||||
| `tests/main/writing-session.test.ts` | UT-SESSION-* |
|
||||
| `tests/main/character-graph.test.ts` | UT-GRAPH-* |
|
||||
| `tests/main/writing-analytics.test.ts` | UT-ANALYTICS-* |
|
||||
| `e2e/character-graph.spec.ts` | E2E-GRAPH-* |
|
||||
| `e2e/writing-analytics.spec.ts` | E2E-ANALYTICS-* |
|
||||
|
||||
---
|
||||
|
||||
## 10. Definition of Done
|
||||
|
||||
- [ ] `writing_sessions` 表与 Session 状态机落地
|
||||
- [ ] 角色关系 CRUD + Cytoscape 图谱模态
|
||||
- [ ] 驾驶舱分析区(速度 / 时段 / POV / 卷 / 7 日)
|
||||
- [ ] 章节 POV 选择 UI
|
||||
- [ ] UT / IT / E2E 用例通过
|
||||
- [ ] i18n zh-CN / en 键齐全
|
||||
- [ ] `npm run build` + `npm run test` 全绿
|
||||
- [ ] 版本号 **1.0.0**(`package.json` / README / Settings 关于页)
|
||||
|
||||
---
|
||||
|
||||
## 11. Spec Coverage(design/readme.md)
|
||||
|
||||
| 设计章节 | 本 spec 覆盖 |
|
||||
|----------|-------------|
|
||||
| §7.1 力导向图、节点/边、布局 | ✅ MVP |
|
||||
| §7.2-1 设定面板手动添加 | ✅ |
|
||||
| §7.2-2 图谱拖拽连线 | ❌ v1.1 |
|
||||
| §7.2-3 AI 关系建议 | ❌ v1.1 |
|
||||
| §7.3 E2E-GRAPH-01~04 | ✅(04 改为设定面板添加) |
|
||||
| §9 写作速度仪表盘 | ✅ 今日速度 + 时段热力 |
|
||||
| §9 习惯追踪 | 部分(连更/番茄已有;session 时长留待后续展示) |
|
||||
| §9 POV 字数分布 | ✅ |
|
||||
| §9 角色弧线简报 | ❌ v1.1 |
|
||||
| §20.3 角色弧线 | ❌ v1.1 |
|
||||
Reference in New Issue
Block a user