@whispering233/ai-editor-server 0.0.48 → 0.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/client-dist/assets/index-BOW1goPz.js +621 -0
  2. package/client-dist/assets/index-Dim9IXQC.css +1 -0
  3. package/client-dist/assets/module-RjUF93sV.js +716 -0
  4. package/client-dist/assets/native-48B9X9Wg.js +1 -0
  5. package/client-dist/index.html +2 -2
  6. package/dist/backup.d.ts +14 -11
  7. package/dist/backup.d.ts.map +1 -1
  8. package/dist/backup.js +40 -23
  9. package/dist/backup.js.map +1 -1
  10. package/dist/cloud/state.d.ts +18 -1
  11. package/dist/cloud/state.d.ts.map +1 -1
  12. package/dist/cloud/state.js +34 -3
  13. package/dist/cloud/state.js.map +1 -1
  14. package/dist/cloud/sync.d.ts +3 -3
  15. package/dist/cloud/sync.d.ts.map +1 -1
  16. package/dist/cloud/sync.js +4 -4
  17. package/dist/cloud/sync.js.map +1 -1
  18. package/dist/consistency.d.ts.map +1 -1
  19. package/dist/consistency.js +1 -4
  20. package/dist/consistency.js.map +1 -1
  21. package/dist/debug.d.ts +1 -1
  22. package/dist/debug.js +3 -3
  23. package/dist/debug.js.map +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +4 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/routes/chat.d.ts +4 -0
  28. package/dist/routes/chat.d.ts.map +1 -1
  29. package/dist/routes/chat.js +16 -2
  30. package/dist/routes/chat.js.map +1 -1
  31. package/dist/routes/cloud.js +1 -1
  32. package/dist/routes/cloud.js.map +1 -1
  33. package/dist/routes/entity.d.ts +1 -1
  34. package/dist/routes/entity.d.ts.map +1 -1
  35. package/dist/routes/entity.js +110 -90
  36. package/dist/routes/entity.js.map +1 -1
  37. package/dist/routes/manuscript.d.ts +4 -0
  38. package/dist/routes/manuscript.d.ts.map +1 -0
  39. package/dist/routes/manuscript.js +86 -0
  40. package/dist/routes/manuscript.js.map +1 -0
  41. package/dist/routes/names.js +5 -5
  42. package/dist/routes/names.js.map +1 -1
  43. package/dist/routes/outline.d.ts +5 -3
  44. package/dist/routes/outline.d.ts.map +1 -1
  45. package/dist/routes/outline.js +32 -7
  46. package/dist/routes/outline.js.map +1 -1
  47. package/dist/routes/project.js +2 -2
  48. package/dist/routes/project.js.map +1 -1
  49. package/dist/routes/trash.d.ts.map +1 -1
  50. package/dist/routes/trash.js +14 -26
  51. package/dist/routes/trash.js.map +1 -1
  52. package/dist/sql-placeholders.d.ts +2 -0
  53. package/dist/sql-placeholders.d.ts.map +1 -0
  54. package/dist/sql-placeholders.js +7 -0
  55. package/dist/sql-placeholders.js.map +1 -0
  56. package/package.json +5 -5
  57. package/client-dist/assets/index-DAzWamd7.css +0 -1
  58. package/client-dist/assets/index-DyrUkODP.js +0 -523
  59. package/dist/reference-files.d.ts +0 -87
  60. package/dist/reference-files.d.ts.map +0 -1
  61. package/dist/reference-files.js +0 -266
  62. package/dist/reference-files.js.map +0 -1
  63. package/dist/routes/reference.d.ts +0 -4
  64. package/dist/routes/reference.d.ts.map +0 -1
  65. package/dist/routes/reference.js +0 -23
  66. package/dist/routes/reference.js.map +0 -1
@@ -3,18 +3,17 @@
3
3
  //
4
4
  // (软删级联)、(时间轴事件:全局线性序 sort_order,仅 event 使用)、
5
5
  // G2 修订(时间标签点实体化:timepoint 全局线性序 + occurs_at 挂载 + 跨组拖拽复合端点)。
6
+ // reference 特例(2026-10,docs/api/30-api-entity.md):正文是块文档——`data.content` 拆写进
7
+ // document_records(owner_kind='reference',单事务),详情再装回;列表摘要读 content_text 投影。
6
8
  // 错误映射(对照 错误码):
7
9
  // type 参数非法 / 参数校验失败 → 400 VALIDATION_ERROR(zod 抛错由 errorHandler 统一映射,含 fields)
8
10
  // 实体不存在或已软删 → 404 ENTITY_NOT_FOUND
9
11
  import { Hono } from "hono";
10
- import { existsSync } from "node:fs";
11
- import { join } from "node:path";
12
- import { countDeltasForEntity, createEntity, createRelation, deleteRelation, eventOccursAt, getEntity, listEntities, listRelations, moveEvent, moveSetting, moveTimepoint, nowIso, RelationError, softDeleteEntity, updateEntity, withTransaction, } from "@whispering233/ai-editor-db";
13
- import { sanitizeReferenceFileName } from "@whispering233/ai-editor-shared";
12
+ import { countDeltasForEntity, createEntity, createRelation, deleteRelation, eventOccursAt, getDocument, getEntity, listEntities, listRelations, moveEvent, moveSetting, moveTimepoint, nowIso, RelationError, softDeleteEntity, updateEntity, upsertDocument, withTransaction, } from "@whispering233/ai-editor-db";
13
+ import { blocksToPlainMd, isBlockArray } from "@whispering233/ai-editor-shared";
14
14
  import { ENTITY_DATA_SCHEMAS, entityCreateReqSchema, entityListQuerySchema, entityMoveReqSchema, entityTypeSchema, entityUpdateReqSchema, eventMoveToReqSchema, settingMoveReqSchema } from "@whispering233/ai-editor-shared/schemas";
15
15
  import { HttpError, ok } from "../middleware/error.js";
16
16
  import { requireCurrentProject } from "../middleware/project.js";
17
- import { getReferenceRow, moveReferenceToTrash, readReferenceFile, REFERENCE_DIR, uniqueFileNameIn, writeReferenceFile, } from "../reference-files.js";
18
17
  import { mapRelationError } from "./relation.js";
19
18
  /** 实体路由(挂载于 /api/v1/entity,index.ts) */
20
19
  export const entityRoutes = new Hono();
@@ -33,6 +32,59 @@ function validateDataByType(type, data) {
33
32
  throw check.error; // → errorHandler → 400 VALIDATION_ERROR(含 fields)
34
33
  }
35
34
  }
35
+ /** 浅校验块文档 content(同章正文端点口径):JSON.parse 后必须是块数组(shared `isBlockArray`),
36
+ * 否则 400 VALIDATION_ERROR(服务端投影前先校验,坏块不得落库) */
37
+ function parseBlockContent(content) {
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(content);
41
+ }
42
+ catch {
43
+ throw new HttpError(400, "VALIDATION_ERROR", "content 必须是块数组 JSON 字符串");
44
+ }
45
+ if (!isBlockArray(parsed)) {
46
+ throw new HttpError(400, "VALIDATION_ERROR", "content 必须是块数组 JSON 字符串");
47
+ }
48
+ return parsed;
49
+ }
50
+ /**
51
+ * reference 的 data.content 拆分(2026-10 装载拆分,docs/api/30-api-entity.md「reference 特例」):
52
+ * `content` 是**端点对外字段名**,真相落 `document_records` ⇒ 返回的 data 已剔除 content。
53
+ * - content 未携带(字段不存在或非对象 data)→ `content` 为 null = **正文保持不动**
54
+ * (行内改标题/分类/标签场景,旧「先写文件后写库」链路的替代语义)
55
+ * - content 非字符串 → 400(referenceDataSchema 已拦,此处防御)
56
+ * - 非 reference 类型原样透传(其余类型无本字段语义)
57
+ */
58
+ function splitReferenceContent(type, data) {
59
+ if (type !== "reference" || data === undefined || data.content === undefined) {
60
+ return { data, content: null };
61
+ }
62
+ const raw = data.content;
63
+ if (typeof raw !== "string") {
64
+ throw new HttpError(400, "VALIDATION_ERROR", "content 必须是块数组 JSON 字符串");
65
+ }
66
+ // 服务端派生投影(唯一写入人);blocksToPlainMd 容错、绝不抛错 ⇒ 派生失败也不阻断保存
67
+ const text = blocksToPlainMd(parseBlockContent(raw));
68
+ const rest = { ...data };
69
+ delete rest.content;
70
+ return { data: rest, content: { raw, text } };
71
+ }
72
+ /**
73
+ * 剔除存量行遗留的 `data.content` 旧键(卡 12.7b):
74
+ * 旧版把参考资料正文写在 `entities.data.content` 里,12.7a 起正文真相 = `document_records`。
75
+ * `updateEntity` 的 data 浅合并只增不减 ⇒ 用 `content: undefined` 作为「删该键」的显式标记
76
+ * (落库走 `JSON.stringify`,值为 `undefined` 的键不写进 JSON ⇒ 旧键在下一次写入时消失),
77
+ * 行内其余字段照旧浅合并;「未带 content = 正文行(document_records)不动」语义不受影响。
78
+ * 无旧键(或非 reference / 实体不存在)→ 原样返回请求 data,走 updateEntity 缺省合并。
79
+ */
80
+ function stripLegacyReferenceContent(db, type, id, data) {
81
+ if (type !== "reference")
82
+ return data;
83
+ const existing = getEntity(db, id);
84
+ if (existing === null || !("content" in existing.data))
85
+ return data;
86
+ return { ...(data ?? {}), content: undefined };
87
+ }
36
88
  // GET /api/v1/entity/:type —— 列表(q/offset/limit/sort/order;响应 camelCase)
37
89
  entityRoutes.get("/:type", (c) => {
38
90
  const project = requireCurrentProject();
@@ -78,6 +130,8 @@ entityRoutes.get("/:type", (c) => {
78
130
  }));
79
131
  });
80
132
  // GET /api/v1/entity/:type/:id —— 详情(含紧邻 relations + deltaCount)
133
+ // reference 特例(2026-10):`data.content` 不在 entities.data 里,从 document_records 装回
134
+ // (写入侧拆分的逆操作)——库内无行(从未写过正文)→ 不附加 content 键(详情不凭空造空文档)
81
135
  entityRoutes.get("/:type/:id", (c) => {
82
136
  const project = requireCurrentProject();
83
137
  parseTypeParam(c.req.param("type"));
@@ -86,6 +140,7 @@ entityRoutes.get("/:type/:id", (c) => {
86
140
  if (row === null) {
87
141
  throw new HttpError(404, "ENTITY_NOT_FOUND", `实体不存在: ${id}`);
88
142
  }
143
+ const doc = row.type === "reference" ? getDocument(project.db, "reference", id) : null;
89
144
  const deltaCount = countDeltasForEntity(project.db, id);
90
145
  // relations 紧邻(S3.2:listRelations depth=1,任一端点软删即不可见;
91
146
  // outline.json 校验路径 = project.root)。
@@ -105,7 +160,7 @@ entityRoutes.get("/:type/:id", (c) => {
105
160
  id: row.id,
106
161
  type: row.type,
107
162
  name: row.name,
108
- data: row.data,
163
+ data: doc === null ? row.data : { ...row.data, content: doc.content },
109
164
  relations,
110
165
  deltaCount,
111
166
  createdAt: row.created_at,
@@ -113,8 +168,10 @@ entityRoutes.get("/:type/:id", (c) => {
113
168
  }));
114
169
  });
115
170
  // POST /api/v1/entity/:type —— 创建(name 必填 1-100;data 按类型精确校验;201)
116
- // reference 特例:kind 缺省视为 link(url 必填校验);kind='file' → 先落盘
117
- // references/<标题 sanitize>.md(frontmatter + 正文)再建索引(data 补 file_name/file_mtime/content 镜像)
171
+ // reference 特例(2026-10,docs/api/30-api-entity.md):`data.content`(块数组 JSON 字符串)
172
+ // **不进 entities.data**,与实体行同一事务拆写进 `document_records`(owner_kind='reference',
173
+ // 服务端派生 content_text 投影);未携带 content = 允许先建条目后写正文(不落文档行);
174
+ // url 可选(纯本地笔记不需外源链接)。
118
175
  entityRoutes.post("/:type", async (c) => {
119
176
  const project = requireCurrentProject();
120
177
  const type = parseTypeParam(c.req.param("type"));
@@ -125,38 +182,33 @@ entityRoutes.post("/:type", async (c) => {
125
182
  if (parsed.data.data !== undefined) {
126
183
  validateDataByType(type, parsed.data.data);
127
184
  }
128
- let data = parsed.data.data ?? {};
129
- if (type === "reference") {
130
- const kind = data.kind === "file" ? "file" : "link"; // 缺省视为 link
131
- if (kind === "link") {
132
- // link 类:url 必填(trim 非空)
133
- if (typeof data.url !== "string" || data.url.trim() === "") {
134
- throw new HttpError(400, "VALIDATION_ERROR", "外源链接参考资料必须提供 url");
135
- }
136
- data = { ...data, kind: "link", url: data.url.trim() };
137
- }
138
- else {
139
- // file 类:先原子写文件(frontmatter + 正文镜像),再建索引
140
- const base = sanitizeReferenceFileName(parsed.data.name);
141
- const fileName = uniqueFileNameIn(join(project.root, REFERENCE_DIR), base);
142
- const body = typeof data.content === "string" ? data.content : "";
143
- const { mtime } = writeReferenceFile(project.root, fileName, { title: parsed.data.name, category: data.type ?? "material", tags: Array.isArray(data.tags) ? data.tags : [] }, body);
144
- data = {
145
- ...data,
146
- kind: "file",
147
- file_name: fileName,
148
- file_mtime: mtime,
149
- content: body,
150
- };
185
+ const { data, content } = splitReferenceContent(type, parsed.data.data);
186
+ const row = withTransaction(project.db, () => {
187
+ const created = createEntity(project.db, { type, name: parsed.data.name, data: data ?? {} });
188
+ if (content !== null) {
189
+ upsertDocument(project.db, {
190
+ ownerKind: "reference",
191
+ ownerId: created.id,
192
+ content: content.raw, // 真相原样存(不重新序列化)
193
+ contentText: content.text,
194
+ now: nowIso(),
195
+ });
151
196
  }
152
- }
153
- const row = createEntity(project.db, { type, name: parsed.data.name, data });
154
- return c.json(ok({ id: row.id, type: row.type, name: row.name, data: row.data, createdAt: row.created_at }), 201);
197
+ return created;
198
+ });
199
+ return c.json(ok({
200
+ id: row.id,
201
+ type: row.type,
202
+ name: row.name,
203
+ // 对外形态不变:携带了 content 就回显(真相在文档表)
204
+ data: content === null ? row.data : { ...row.data, content: content.raw },
205
+ createdAt: row.created_at,
206
+ }), 201);
155
207
  });
156
208
  // PUT /api/v1/entity/:type/:id —— 部分更新(仅合并传入字段;data 浅合并)
157
- // reference file 类特例:**先原子写文件再更新 DB**——正文真相在文件:
158
- // 请求未携带 data.content 时(行内编辑标题/分类/标签)读原文件正文与最新元数据重写 frontmatter 保留正文;
159
- // 文件读失败(外部删除)→ 409 REFERENCE_FILE_MISSING 提示先扫描;文件名不随标题重命名(创建时确定)
209
+ // reference 特例(2026-10):`data.content` 传入 → 与实体行同一事务整篇覆盖文档行(单事务,
210
+ // 无「先写文件后写库」的先后性与自愈问题);**未携带 content 时正文保持不动**——
211
+ // 行内编辑标题/分类/标签不碰正文,也不再随写文件联动;存量行的遗留 `data.content` 旧键随本次写入剔除。
160
212
  entityRoutes.put("/:type/:id", async (c) => {
161
213
  const project = requireCurrentProject();
162
214
  const type = parseTypeParam(c.req.param("type"));
@@ -168,40 +220,26 @@ entityRoutes.put("/:type/:id", async (c) => {
168
220
  if (parsed.data.data !== undefined) {
169
221
  validateDataByType(type, parsed.data.data);
170
222
  }
171
- let name = parsed.data.name;
172
- let data = parsed.data.data;
173
- if (type === "reference") {
174
- const existing = getReferenceRow(project.db, id);
175
- if (existing === null) {
223
+ const { data, content } = splitReferenceContent(type, parsed.data.data);
224
+ const row = withTransaction(project.db, () => {
225
+ const updated = updateEntity(project.db, id, {
226
+ name: parsed.data.name,
227
+ data: stripLegacyReferenceContent(project.db, type, id, data),
228
+ });
229
+ if (updated === null) {
176
230
  throw new HttpError(404, "ENTITY_NOT_FOUND", `实体不存在: ${id}`);
177
231
  }
178
- if (existing.data.kind === "file" && typeof existing.data.file_name === "string") {
179
- const fileName = existing.data.file_name;
180
- const file = readReferenceFile(project.root, fileName);
181
- if (file === null) {
182
- throw new HttpError(409, "REFERENCE_FILE_MISSING", `参考资料文件缺失: references/${fileName}——可能已在文件管理器中被删除,请先扫描同步`);
183
- }
184
- // 元数据 = 请求新值 ?? 文件现状 ?? 索引现状;正文 = data.content 传入 ? 新值 : 文件正文
185
- const nextTitle = name ?? file.title ?? existing.row.name;
186
- const nextCategory = data?.type ?? file.category ?? "material";
187
- const nextTags = Array.isArray(data?.tags) ? data.tags : file.tags;
188
- const nextBody = typeof data?.content === "string" ? data.content : file.body;
189
- const { mtime } = writeReferenceFile(project.root, fileName, { title: nextTitle, category: nextCategory, tags: nextTags, extraLines: file.extraLines }, nextBody);
190
- // 服务端维护字段:kind/file_name/file_mtime 不接受客户端覆盖(防御)
191
- data = {
192
- ...(data ?? {}),
193
- kind: "file",
194
- file_name: fileName,
195
- file_mtime: mtime,
196
- content: nextBody,
197
- };
198
- name = nextTitle;
232
+ if (content !== null) {
233
+ upsertDocument(project.db, {
234
+ ownerKind: "reference",
235
+ ownerId: id,
236
+ content: content.raw,
237
+ contentText: content.text,
238
+ now: nowIso(),
239
+ });
199
240
  }
200
- }
201
- const row = updateEntity(project.db, id, { name, data });
202
- if (row === null) {
203
- throw new HttpError(404, "ENTITY_NOT_FOUND", `实体不存在: ${id}`);
204
- }
241
+ return updated;
242
+ });
205
243
  return c.json(ok({ id: row.id, updated: true }));
206
244
  });
207
245
  // PUT /api/v1/entity/event/:id/move —— 时间轴事件重排
@@ -340,31 +378,13 @@ entityRoutes.post("/event/:id/move_to", async (c) => {
340
378
  }
341
379
  });
342
380
  // DELETE /api/v1/entity/:type/:id —— 软删(级联软删关系与 Delta,本体保留可还原)
343
- // reference file 类特例:先移文件入 references/.trash/(冲突递增命名)再 DB 软删——
344
- // 文件移动失败 → 操作报错(文件未动、索引未删,可重试);DB 软删失败(罕见)→ 文件在 .trash/ 且
345
- // 索引未软删,scan 反向规则(references/ 下缺失 → 软删)自愈
381
+ // reference 特例(2026-10):正文行(document_records)**保留**——软删期间端点 404 不可见,
382
+ // 还原后原样可见;purge 时才随实体物理删(trash 路由)。此前「文件移入 references/.trash/」的
383
+ // 文件联动已随本卡移除(原属 12.7b 范围)。
346
384
  entityRoutes.delete("/:type/:id", (c) => {
347
385
  const project = requireCurrentProject();
348
- const type = parseTypeParam(c.req.param("type"));
386
+ parseTypeParam(c.req.param("type"));
349
387
  const id = c.req.param("id");
350
- if (type === "reference") {
351
- const existing = getReferenceRow(project.db, id);
352
- if (existing === null) {
353
- throw new HttpError(404, "ENTITY_NOT_FOUND", `实体不存在: ${id}`);
354
- }
355
- if (existing.data.kind === "file" && typeof existing.data.file_name === "string") {
356
- const fileName = existing.data.file_name;
357
- // 文件缺失(外部已删)→ 不阻塞软删(索引照删,scan 语义一致);文件在 → 移入 .trash/
358
- const full = join(project.root, REFERENCE_DIR, fileName);
359
- if (existsSync(full)) {
360
- const trashName = moveReferenceToTrash(project.root, fileName);
361
- // 冲突递增导致 .trash/ 实际名 ≠ 原 file_name → 更新索引 file_name(软删后仅回收站展示)
362
- if (trashName !== fileName) {
363
- updateEntity(project.db, id, { data: { file_name: trashName } });
364
- }
365
- }
366
- }
367
- }
368
388
  const result = softDeleteEntity(project.db, id, nowIso());
369
389
  if (result === null) {
370
390
  throw new HttpError(404, "ENTITY_NOT_FOUND", `实体不存在: ${id}`);
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Hono } from "hono";
2
+ /** 章正文路由(挂载于 /api/v1/manuscript,index.ts) */
3
+ export declare const manuscriptRoutes: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
4
+ //# sourceMappingURL=manuscript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manuscript.d.ts","sourceRoot":"","sources":["../../src/routes/manuscript.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,4EAAa,CAAC"}
@@ -0,0 +1,86 @@
1
+ // 章正文路由(卡 12.4):GET/PUT /api/v1/manuscript/:chapterNodeId
2
+ //
3
+ // 契约单一来源:docs/api/110-api-manuscript.md;表与派生口径见 docs/db/schema.md「document_records」。
4
+ // 口径:
5
+ // - **仅 chapter**——卷/场景 → 400 VALIDATION_ERROR(与 current_position / Delta 锚点 / 伏笔锚点同宽);
6
+ // - 节点不存在或已软删 → 404 OUTLINE_NODE_NOT_FOUND(软删章的行保留,还原后原样可见);
7
+ // - content 浅校验(JSON.parse 后必须是块数组,shared `isBlockArray`)→ 否则 400;
8
+ // - `base_updated_at` 仅在携带时比对(不一致 → 409 DOCUMENT_STALE);省略 = 覆盖保存(导入路径);
9
+ // - `content_text` 由服务端用 shared `blocksToPlainMd` 派生(其内部 try/catch 兜底、绝不抛错 ⇒
10
+ // 派生失败也不阻断保存),`charCount = content_text.length`;
11
+ // - 保存正文**不产生 Delta、不推进 current_position**(内容不是状态事实)。
12
+ import { Hono } from "hono";
13
+ import { findOutlineNode, getDocument, readOutlineFile, upsertDocument } from "@whispering233/ai-editor-db";
14
+ import { blocksToPlainMd, isBlockArray } from "@whispering233/ai-editor-shared";
15
+ import { manuscriptPutReqSchema } from "@whispering233/ai-editor-shared/schemas";
16
+ import { nowIso } from "@whispering233/ai-editor-db";
17
+ import { HttpError, ok } from "../middleware/error.js";
18
+ import { requireCurrentProject } from "../middleware/project.js";
19
+ /** 章正文路由(挂载于 /api/v1/manuscript,index.ts) */
20
+ export const manuscriptRoutes = new Hono();
21
+ /** 定位章节点:不存在/已软删 → 404;非章 → 400(正文章级口径,三层同宽) */
22
+ function requireChapterNode(project, nodeId) {
23
+ const node = findOutlineNode(readOutlineFile(project.root), nodeId);
24
+ if (node === undefined || node.deleted === true) {
25
+ throw new HttpError(404, "OUTLINE_NODE_NOT_FOUND", `大纲节点不存在: ${nodeId}`);
26
+ }
27
+ if (node.type !== "chapter") {
28
+ throw new HttpError(400, "VALIDATION_ERROR", `正文只能挂在章节点上: ${nodeId}`);
29
+ }
30
+ return node;
31
+ }
32
+ /** 浅校验 content:JSON.parse 后必须是块数组(shared `isBlockArray`:非 null 对象数组) */
33
+ function parseBlockContent(content) {
34
+ let parsed;
35
+ try {
36
+ parsed = JSON.parse(content);
37
+ }
38
+ catch {
39
+ throw new HttpError(400, "VALIDATION_ERROR", "content 必须是块数组 JSON 字符串");
40
+ }
41
+ if (!isBlockArray(parsed)) {
42
+ throw new HttpError(400, "VALIDATION_ERROR", "content 必须是块数组 JSON 字符串");
43
+ }
44
+ return parsed;
45
+ }
46
+ // GET /api/v1/manuscript/:chapterNodeId —— 读取正文(含版本戳;从未写过 = 空文档语义)
47
+ manuscriptRoutes.get("/:chapterNodeId", (c) => {
48
+ const project = requireCurrentProject();
49
+ const nodeId = c.req.param("chapterNodeId");
50
+ requireChapterNode(project, nodeId); // 404 / 400 前置(软删章不暴露正文)
51
+ const row = getDocument(project.db, "chapter", nodeId);
52
+ return c.json(ok({
53
+ chapterNodeId: nodeId,
54
+ content: row?.content ?? "",
55
+ updatedAt: row?.updated_at ?? null,
56
+ charCount: row?.content_text.length ?? 0,
57
+ }));
58
+ });
59
+ // PUT /api/v1/manuscript/:chapterNodeId —— 整篇覆盖保存(服务端派生投影 + 版本戳防覆盖)
60
+ manuscriptRoutes.put("/:chapterNodeId", async (c) => {
61
+ const project = requireCurrentProject();
62
+ const nodeId = c.req.param("chapterNodeId");
63
+ requireChapterNode(project, nodeId);
64
+ const raw = await c.req.json().catch(() => null);
65
+ const parsed = manuscriptPutReqSchema.safeParse(raw);
66
+ if (!parsed.success) {
67
+ throw parsed.error; // → 400 VALIDATION_ERROR(content 缺失/非字符串/未知字段)
68
+ }
69
+ const blocks = parseBlockContent(parsed.data.content);
70
+ // 版本戳比对:仅携带 base_updated_at 时校验(库内无行 ⇒ 现有版本戳为 null,传了非空 base 即不一致)
71
+ const existing = getDocument(project.db, "chapter", nodeId);
72
+ const base = parsed.data.base_updated_at;
73
+ if (base !== undefined && (existing?.updated_at ?? null) !== base) {
74
+ throw new HttpError(409, "DOCUMENT_STALE", "正文已被其他窗口修改");
75
+ }
76
+ const contentText = blocksToPlainMd(blocks); // 容错投影(绝不抛错);失败退化为尽力抽取的文本
77
+ const { updatedAt } = upsertDocument(project.db, {
78
+ ownerKind: "chapter",
79
+ ownerId: nodeId,
80
+ content: parsed.data.content, // 真相原样存(不重新序列化)
81
+ contentText,
82
+ now: nowIso(),
83
+ });
84
+ return c.json(ok({ updated: true, updatedAt, charCount: contentText.length }));
85
+ });
86
+ //# sourceMappingURL=manuscript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manuscript.js","sourceRoot":"","sources":["../../src/routes/manuscript.ts"],"names":[],"mappings":"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"}
@@ -9,16 +9,16 @@
9
9
  // 响应 names 键集 = 请求 ids 去重后全集(每个 id 必有条目,未命中 = null)
10
10
  import { Hono } from "hono";
11
11
  import { getEntity, findOutlineNode, readOutlineFile } from "@whispering233/ai-editor-db";
12
- import { ENTITY_TYPE_LABELS, OUTLINE_NODE_TYPE_LABELS } from "@whispering233/ai-editor-shared";
12
+ import { ENTITY_ID_PREFIX, ENTITY_TYPE_LABELS, OUTLINE_NODE_ID_PREFIX, OUTLINE_NODE_TYPE_LABELS } from "@whispering233/ai-editor-shared";
13
13
  import { namesResolveReqSchema } from "@whispering233/ai-editor-shared/schemas";
14
14
  import { ok } from "../middleware/error.js";
15
15
  import { requireCurrentProject } from "../middleware/project.js";
16
16
  /** 名称解析路由(挂载于 /api/v1/names,index.ts) */
17
17
  export const namesRoutes = new Hono();
18
- /** 实体 id 前缀(char-/set-/loc-/hook-/ev-/tp-/ref-,ENTITY_ID_PREFIX 同源) */
19
- const ENTITY_PREFIXES = ["char-", "set-", "loc-", "hook-", "ev-", "tp-", "ref-"];
20
- /** 大纲节点 id 前缀(vol-/ch-/sc) */
21
- const OUTLINE_PREFIXES = ["vol-", "ch-", "sc-"];
18
+ /** 实体 id 前缀(**派生 shared `ENTITY_ID_PREFIX`**——单一来源,禁止手抄) */
19
+ const ENTITY_PREFIXES = Object.values(ENTITY_ID_PREFIX);
20
+ /** 大纲节点 id 前缀(**派生 shared `OUTLINE_NODE_ID_PREFIX`**) */
21
+ const OUTLINE_PREFIXES = Object.values(OUTLINE_NODE_ID_PREFIX);
22
22
  /** 解析单个 id:未命中/未知前缀 → null */
23
23
  function resolveOne(id, project) {
24
24
  // 实体前缀分流(getEntity 过滤已软删行,软删 → null)
@@ -1 +1 @@
1
- {"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/routes/names.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/routes/names.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,2DAA2D;AAC3D,4CAA4C;AAC5C,wBAAwB;AACxB,mEAAmE;AACnE,iFAAiF;AACjF,uBAAuB;AACvB,yCAAyC;AACzC,oDAAoD;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AACzI,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAEhF,OAAO,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAuB,MAAM,0BAA0B,CAAC;AAEtF,yCAAyC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,eAAe,GAAa,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAElE,yDAAyD;AACzD,MAAM,gBAAgB,GAAa,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAEzE,8BAA8B;AAC9B,SAAS,UAAU,CAAC,EAAU,EAAE,OAAuB;IACtD,qCAAqC;IACpC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACtC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACvF,CAAC;IACH,CAAC;IACF,yDAAyD;IACxD,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,CAAgC,CAAC;YACtE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC7D,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1E,CAAC;IACH,CAAC;IACF,sDAAsD;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uCAAuC;AACvC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACvC,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B;IAC5E,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,iDAAiD;IACvE,CAAC;IACF,0BAA0B;IACzB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,KAAK,GAA2D,EAAE,CAAC;IACzE,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,KAAK,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC"}
@@ -2,10 +2,12 @@ import { Hono } from "hono";
2
2
  import type { OutlineFileTree } from "@whispering233/ai-editor-shared";
3
3
  /** 大纲路由(挂载于 /api/v1/outline,index.ts) */
4
4
  export declare const outlineRoutes: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
5
- /** 收集 nodeId 及其整棵子树的 id 集(含自身;供 relation/delta 级联软删/还原/清除用) */
5
+ /**
6
+ * 收集 nodeId 及其**全部后代**的 id 集(含自身;**不含祖先**——供 relation/delta 级联软删/还原/清除用)。
7
+ * 语义与函数名/docs 一致:「删卷必然带上卷下所有章与场景」「删场景不动祖先与兄弟」。
8
+ * 节点不存在 → 404 OUTLINE_NODE_NOT_FOUND。
9
+ */
6
10
  export declare function collectSubtreeIds(tree: OutlineFileTree, nodeId: string): string[];
7
- /** 生成 SQL IN 占位符串(id 集来自服务端生成的 nanoid,无注入面;空集返回 "(NULL)" 恒假) */
8
- export declare function inPlaceholders(ids: string[]): string;
9
11
  /** OutlineError → HttpError 映射(对照 错误码,文件头注释表) */
10
12
  export declare function mapOutlineError(err: unknown): never;
11
13
  //# sourceMappingURL=outline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/routes/outline.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAmB,eAAe,EAA6C,MAAM,iCAAiC,CAAC;AAanI,yCAAyC;AACzC,eAAO,MAAM,aAAa,4EAAa,CAAC;AA4BxC,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAajF;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAEpD;AA0LD,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAcnD"}
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/routes/outline.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,OAAO,KAAK,EAAmB,eAAe,EAA6C,MAAM,iCAAiC,CAAC;AAanI,yCAAyC;AACzC,eAAO,MAAM,aAAa,4EAAa,CAAC;AA4BxC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBjF;AAuMD,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAcnD"}
@@ -9,7 +9,9 @@
9
9
  // 级联软删(cascadeSoftDelete)保留在路由层——与软删端点同文件内联,S4.1 任务边界只下沉
10
10
  // 还原/清除两个 helper(trash.ts 路由直接 import @whispering233/ai-editor-db)。
11
11
  import { Hono } from "hono";
12
+ import { inPlaceholders } from "../sql-placeholders.js";
12
13
  import { findOutlineNode, readOutlineFile } from "@whispering233/ai-editor-db";
14
+ import { getDocumentTextLengths } from "@whispering233/ai-editor-db";
13
15
  import { getOutlinePathIds } from "@whispering233/ai-editor-db";
14
16
  import { createOutlineNode, deleteOutlineNode, moveOutlineNode, OutlineError, updateOutlineNodeInfo, } from "@whispering233/ai-editor-db";
15
17
  import { HOOK_RELATION_TYPES, mapOutlineFileToTree } from "@whispering233/ai-editor-shared";
@@ -42,15 +44,26 @@ function filterDeletedTree(tree) {
42
44
  // 此处断言收窄回 OutlineFileTree(storage 形态判别联合的已知递归映射限制)
43
45
  return { ...tree, children: filterNodes(tree.children) };
44
46
  }
45
- /** 收集 nodeId 及其整棵子树的 id 集(含自身;供 relation/delta 级联软删/还原/清除用) */
47
+ /**
48
+ * 收集 nodeId 及其**全部后代**的 id 集(含自身;**不含祖先**——供 relation/delta 级联软删/还原/清除用)。
49
+ * 语义与函数名/docs 一致:「删卷必然带上卷下所有章与场景」「删场景不动祖先与兄弟」。
50
+ * 节点不存在 → 404 OUTLINE_NODE_NOT_FOUND。
51
+ */
46
52
  export function collectSubtreeIds(tree, nodeId) {
47
53
  const ids = [];
54
+ const collectDescendants = (node) => {
55
+ ids.push(node.id);
56
+ for (const child of node.children ?? [])
57
+ collectDescendants(child);
58
+ };
48
59
  const visit = (nodes) => {
49
60
  for (const n of nodes) {
50
- if (n.id === nodeId || visit(n.children ?? [])) {
51
- ids.push(n.id);
61
+ if (n.id === nodeId) {
62
+ collectDescendants(n);
52
63
  return true;
53
64
  }
65
+ if (visit(n.children ?? []))
66
+ return true;
54
67
  }
55
68
  return false;
56
69
  };
@@ -58,10 +71,7 @@ export function collectSubtreeIds(tree, nodeId) {
58
71
  return ids;
59
72
  throw new HttpError(404, "OUTLINE_NODE_NOT_FOUND", `大纲节点不存在: ${nodeId}`);
60
73
  }
61
- /** 生成 SQL IN 占位符串(id 集来自服务端生成的 nanoid,无注入面;空集返回 "(NULL)" 恒假) */
62
- export function inPlaceholders(ids) {
63
- return ids.length === 0 ? "(NULL)" : `(${ids.map(() => "?").join(",")})`;
64
- }
74
+ /** 生成 SQL IN 占位符串(唯一实现见 `../sql-placeholders.js`) */
65
75
  /**
66
76
  * 级联软删该节点及子树关联的 relation/delta(任一端点软删即不可见):
67
77
  * - relations:source 或 target 命中子树任一节点 → 标 deleted_at(含 plot_edge 画布连线)
@@ -99,6 +109,8 @@ outlineRoutes.get("/", (c) => {
99
109
  * - hookCount:该节点出发的伏笔管理关系(plants/advances/resolves,source=outline_node → hook)
100
110
  * - charCount:appears_in 指向该节点的关系数(示例:char → 大纲节点)
101
111
  * - deltaCount:该节点触发的 Delta 数(delta_records.node_id)
112
+ * - textLength(仅章):正文字数(document_records.content_text 长度;无文档 = 0——**不读块 JSON 全文**,
113
+ * 一次批量取长度勿 N+1)
102
114
  * 均为运行时计算,不写回数据(_health 同款口径)。
103
115
  */
104
116
  function attachMetadata(tree, db) {
@@ -110,11 +122,24 @@ function attachMetadata(tree, db) {
110
122
  WHERE target_type = 'outline_node' AND target_id = ? AND relation_type = 'appears_in'
111
123
  AND deleted_at IS NULL`);
112
124
  const deltaStmt = db.prepare(`SELECT COUNT(*) AS c FROM delta_records WHERE node_id = ? AND deleted_at IS NULL`);
125
+ // 先收全部章 id(含存量直挂章),一次批量取正文长度
126
+ const chapterIds = [];
127
+ const collectChapters = (node) => {
128
+ if (node.type === "chapter")
129
+ chapterIds.push(node.id);
130
+ for (const child of node.children ?? [])
131
+ collectChapters(child);
132
+ };
133
+ for (const vol of tree.children)
134
+ collectChapters(vol);
135
+ const textLengths = getDocumentTextLengths(db, "chapter", chapterIds);
113
136
  const visit = (node) => {
114
137
  const metadata = {};
115
138
  metadata.hookCount = hookStmt.get(node.id, ...HOOK_RELATION_TYPES).c;
116
139
  metadata.charCount = charStmt.get(node.id).c;
117
140
  metadata.deltaCount = deltaStmt.get(node.id).c;
141
+ if (node.type === "chapter")
142
+ metadata.textLength = textLengths.get(node.id) ?? 0;
118
143
  node.metadata = metadata;
119
144
  for (const child of node.children ?? [])
120
145
  visit(child);