@whispering233/ai-editor-db 0.0.52 → 0.0.53
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.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/migrations/009_decompose.d.ts +4 -0
- package/dist/migrations/009_decompose.d.ts.map +1 -0
- package/dist/migrations/009_decompose.js +47 -0
- package/dist/migrations/009_decompose.js.map +1 -0
- package/dist/migrations/index.d.ts +2 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +7 -3
- package/dist/migrations/index.js.map +1 -1
- package/dist/queries/decompose.d.ts +144 -0
- package/dist/queries/decompose.d.ts.map +1 -0
- package/dist/queries/decompose.js +310 -0
- package/dist/queries/decompose.js.map +1 -0
- package/dist/schema.d.ts +3 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +3 -1
- package/dist/schema.js.map +1 -1
- package/dist/tables.d.ts +357 -2
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +62 -4
- package/dist/tables.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,4EAA4E;AAC5E,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,4EAA4E;AAC5E,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"009_decompose.d.ts","sourceRoot":"","sources":["../../src/migrations/009_decompose.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA8B5C,QAAA,MAAM,YAAY,EAAE,SAKnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// 迁移 009:拆解小说两表——新增 decompose_jobs / decompose_batches(2026-09)
|
|
2
|
+
//
|
|
3
|
+
// 纯 DDL 迁移(无数据搬移):v8 库补建两张新表,既有表与数据一概不动。
|
|
4
|
+
// 拆解是新增能力,旧项目没有 job 行,**无需回填**(见 docs/db/schema.md
|
|
5
|
+
// 「decompose_jobs / decompose_batches」段)。
|
|
6
|
+
//
|
|
7
|
+
// 幂等:CREATE TABLE IF NOT EXISTS——手工回退版本号后重跑(异常重试路径)不报错;
|
|
8
|
+
// 正常路径由 user_version 门控(版本已到 9 不再执行)。事务由 runMigrations 保证
|
|
9
|
+
// (up + setUserVersion 原子提交)。
|
|
10
|
+
//
|
|
11
|
+
// DDL 与 tables.ts 的 CREATE_TABLES_SQL 中的同名段必须逐字同形——新库走 createTables、
|
|
12
|
+
// 旧库走本迁移,两条路径建出的表结构需一致(schema.test.ts 的 DDL 对齐断言锁住声明层)。
|
|
13
|
+
/** v9 拆解两表 DDL(列序与 CREATE_TABLES_SQL 一致) */
|
|
14
|
+
const DECOMPOSE_TABLES_DDL = `
|
|
15
|
+
CREATE TABLE IF NOT EXISTS decompose_jobs (
|
|
16
|
+
id TEXT PRIMARY KEY, -- 'job-*'
|
|
17
|
+
status TEXT NOT NULL, -- pending | running | paused | done | failed(枚举值少且稳定,不加 CHECK)
|
|
18
|
+
scope_start INTEGER NOT NULL, -- 分析范围起始章序(1-based,文件位置序)
|
|
19
|
+
scope_end INTEGER NOT NULL,
|
|
20
|
+
batch_target_chars INTEGER NOT NULL, -- 组批目标字数快照(续拆/重跑按同一口径重算批次)
|
|
21
|
+
model TEXT, -- 本次使用的模型(provider/id),审计用
|
|
22
|
+
merge_written TEXT, -- JSON: 上次归并写入清单(幂等/重跑三路比对)
|
|
23
|
+
error TEXT, -- job 级失败摘要
|
|
24
|
+
created_at TEXT NOT NULL, -- ISO 8601,应用层写入
|
|
25
|
+
updated_at TEXT NOT NULL
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE IF NOT EXISTS decompose_batches (
|
|
29
|
+
job_id TEXT NOT NULL, -- → decompose_jobs.id
|
|
30
|
+
seq INTEGER NOT NULL, -- 1-based 批序号(文件位置序)
|
|
31
|
+
chapter_ids TEXT NOT NULL, -- JSON: 本批覆盖的章节点 id 列表(顺序 = 文件序)
|
|
32
|
+
status TEXT NOT NULL, -- pending | running | done | failed
|
|
33
|
+
result TEXT, -- JSON: 该批抽取结果(逐章对齐;未完成 = NULL)
|
|
34
|
+
attempts INTEGER NOT NULL DEFAULT 0,-- 已尝试次数(重试上限见设计文档)
|
|
35
|
+
error TEXT, -- 该批失败摘要
|
|
36
|
+
updated_at TEXT NOT NULL,
|
|
37
|
+
PRIMARY KEY (job_id, seq)
|
|
38
|
+
)
|
|
39
|
+
`;
|
|
40
|
+
const migration009 = {
|
|
41
|
+
version: 9,
|
|
42
|
+
up(db) {
|
|
43
|
+
db.exec(DECOMPOSE_TABLES_DDL);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export default migration009;
|
|
47
|
+
//# sourceMappingURL=009_decompose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"009_decompose.js","sourceRoot":"","sources":["../../src/migrations/009_decompose.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,yCAAyC;AACzC,mDAAmD;AACnD,0CAA0C;AAC1C,EAAE;AACF,wDAAwD;AACxD,0DAA0D;AAC1D,8BAA8B;AAC9B,EAAE;AACF,qEAAqE;AACrE,wDAAwD;AAKxD,4CAA4C;AAC5C,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyB5B,CAAC;AAEF,MAAM,YAAY,GAAc;IAC9B,OAAO,EAAE,CAAC;IACV,EAAE,CAAC,EAAM;QACP,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAChC,CAAC;CACF,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -12,6 +12,7 @@ export interface Migration {
|
|
|
12
12
|
}
|
|
13
13
|
/** 全量迁移集(按 version 升序:002 时间轴事件、003 时间标签点实体化(G2)、
|
|
14
14
|
* 004 设定分类字段 tags(K2 修订)、005 参考资料 reference、006 对话历史出库、
|
|
15
|
-
* 007 角色能力面板(旧 abilities 标签迁为 ability_panel)、008 块文档表(document_records
|
|
15
|
+
* 007 角色能力面板(旧 abilities 标签迁为 ability_panel)、008 块文档表(document_records)、
|
|
16
|
+
* 009 拆解两表(decompose_jobs / decompose_batches)) */
|
|
16
17
|
export declare const MIGRATIONS: readonly Migration[];
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAU3C,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAChC,0DAA0D;IACzD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC9C,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC7C;AAED;;;mDAGmD;AACnD,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAS1C,CAAC"}
|
package/dist/migrations/index.js
CHANGED
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
// - 失败 → 该迁移回滚 + 版本停在前一迁移后,下次 open 重试
|
|
17
17
|
// - 无迁移路径的旧版本(如 v0 且无 0→1 条目)保持删库重建兜底
|
|
18
18
|
//
|
|
19
|
-
// **当前状态**:SCHEMA_VERSION =
|
|
19
|
+
// **当前状态**:SCHEMA_VERSION = 9;真实迁移 002(v1→v2:entities 表 CHECK 扩为 5 种 +
|
|
20
20
|
// sort_order 列,时间轴)、003(v2→v3:entities CHECK 扩 6 种含 timepoint +
|
|
21
21
|
// event.data.time_label 迁移为 timepoint 实体 + occurs_at 挂载关系,G2)、
|
|
22
22
|
// 004(v3→v4:setting 旧 rules 分类值 → data.tags,仅 data JSON)、005(v4→v5:CHECK 扩
|
|
23
23
|
// 'reference')、006(v5→v6:对话历史出库——chat_messages 导出为 sessions/<id>.jsonl 后 DROP 表)、
|
|
24
24
|
// 007(v6→v7:character 旧 abilities[] → ability_panel,仅 data JSON)、
|
|
25
|
-
// 008(v7→v8:新增 document_records 块文档表,纯 DDL
|
|
25
|
+
// 008(v7→v8:新增 document_records 块文档表,纯 DDL)、
|
|
26
|
+
// 009(v8→v9:新增 decompose_jobs / decompose_batches 拆解两表,纯 DDL)。
|
|
26
27
|
// v0 库无 0→1 迁移条目,仍走删库重建兜底。
|
|
27
28
|
import migration002 from "./002_event_timeline.js";
|
|
28
29
|
import migration003 from "./003_timepoint.js";
|
|
@@ -31,9 +32,11 @@ import migration005 from "./005_reference.js";
|
|
|
31
32
|
import migration006 from "./006_sessions_jsonl.js";
|
|
32
33
|
import migration007 from "./007_character_ability_panel.js";
|
|
33
34
|
import migration008 from "./008_document_records.js";
|
|
35
|
+
import migration009 from "./009_decompose.js";
|
|
34
36
|
/** 全量迁移集(按 version 升序:002 时间轴事件、003 时间标签点实体化(G2)、
|
|
35
37
|
* 004 设定分类字段 tags(K2 修订)、005 参考资料 reference、006 对话历史出库、
|
|
36
|
-
* 007 角色能力面板(旧 abilities 标签迁为 ability_panel)、008 块文档表(document_records
|
|
38
|
+
* 007 角色能力面板(旧 abilities 标签迁为 ability_panel)、008 块文档表(document_records)、
|
|
39
|
+
* 009 拆解两表(decompose_jobs / decompose_batches)) */
|
|
37
40
|
export const MIGRATIONS = [
|
|
38
41
|
migration002,
|
|
39
42
|
migration003,
|
|
@@ -42,5 +45,6 @@ export const MIGRATIONS = [
|
|
|
42
45
|
migration006,
|
|
43
46
|
migration007,
|
|
44
47
|
migration008,
|
|
48
|
+
migration009,
|
|
45
49
|
];
|
|
46
50
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AACzD,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,8DAA8D;AAC9D,EAAE;AACF,kDAAkD;AAClD,wDAAwD;AACxD,uDAAuD;AACvD,sCAAsC;AACtC,sCAAsC;AACtC,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,+DAA+D;AAC/D,2EAA2E;AAC3E,kFAAkF;AAClF,kEAAkE;AAClE,6CAA6C;AAC7C,2BAA2B;AAG3B,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,YAAY,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AACzD,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,8DAA8D;AAC9D,EAAE;AACF,kDAAkD;AAClD,wDAAwD;AACxD,uDAAuD;AACvD,sCAAsC;AACtC,sCAAsC;AACtC,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,+DAA+D;AAC/D,2EAA2E;AAC3E,kFAAkF;AAClF,kEAAkE;AAClE,6CAA6C;AAC7C,+DAA+D;AAC/D,2BAA2B;AAG3B,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,YAAY,MAAM,2BAA2B,CAAC;AACrD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAe9C;;;mDAGmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;CACb,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { DecomposeBatchRes, DecomposeBatchResult, DecomposeJobRes } from "@whispering233/ai-editor-shared";
|
|
2
|
+
import { type Db } from "../connection.js";
|
|
3
|
+
/** job id 前缀(api-public id 约定 `{前缀}-{nanoid}`;job 用 `job-`) */
|
|
4
|
+
export declare const DECOMPOSE_JOB_ID_PREFIX = "job-";
|
|
5
|
+
/** job 状态(pending → running → (paused | done | failed)) */
|
|
6
|
+
export type DecomposeJobStatus = DecomposeJobRes["status"];
|
|
7
|
+
/** 批状态(pending → running → done | failed) */
|
|
8
|
+
export type DecomposeBatchStatus = DecomposeBatchRes["status"];
|
|
9
|
+
/** `merge_written` 项(JSON 形状,字段名与库列同口径)——上次归并写入清单(实体 + 关系 + 报告) */
|
|
10
|
+
export interface DecomposeMergeWrittenEntry {
|
|
11
|
+
id: string;
|
|
12
|
+
type: string;
|
|
13
|
+
/** 写入时的 `updated_at`(重跑三路比对的快照;变了 = 用户手工编辑过) */
|
|
14
|
+
updated_at: string;
|
|
15
|
+
}
|
|
16
|
+
/** decompose_jobs 行(列名与 DDL 同形;`merge_written` 已解析为清单) */
|
|
17
|
+
export interface DecomposeJobRow {
|
|
18
|
+
id: string;
|
|
19
|
+
status: DecomposeJobStatus;
|
|
20
|
+
scope_start: number;
|
|
21
|
+
scope_end: number;
|
|
22
|
+
batch_target_chars: number;
|
|
23
|
+
model: string | null;
|
|
24
|
+
merge_written: DecomposeMergeWrittenEntry[];
|
|
25
|
+
error: string | null;
|
|
26
|
+
created_at: string;
|
|
27
|
+
updated_at: string;
|
|
28
|
+
}
|
|
29
|
+
/** decompose_batches 行(**不含 result**——列表口径,批结果正文按需另取) */
|
|
30
|
+
export interface DecomposeBatchRow {
|
|
31
|
+
job_id: string;
|
|
32
|
+
seq: number;
|
|
33
|
+
/** 本批覆盖的章节点 id 列表(顺序 = 文件序) */
|
|
34
|
+
chapter_ids: string[];
|
|
35
|
+
status: DecomposeBatchStatus;
|
|
36
|
+
/** 已尝试次数 */
|
|
37
|
+
attempts: number;
|
|
38
|
+
error: string | null;
|
|
39
|
+
updated_at: string;
|
|
40
|
+
}
|
|
41
|
+
/** 单批详情 = 批行 + 抽取结果(未完成 → null) */
|
|
42
|
+
export interface DecomposeBatchDetailRow extends DecomposeBatchRow {
|
|
43
|
+
result: DecomposeBatchResult | null;
|
|
44
|
+
}
|
|
45
|
+
/** 创建 job 入参:范围/组批口径快照 + 批规划(S1 组批结果);job 初始状态恒为 pending */
|
|
46
|
+
export interface CreateDecomposeJobInput {
|
|
47
|
+
/** 分析范围起始章序(1-based,文件位置序) */
|
|
48
|
+
scopeStart: number;
|
|
49
|
+
scopeEnd: number;
|
|
50
|
+
/** 组批目标字数快照(续拆/重跑按同一口径重算批次) */
|
|
51
|
+
batchTargetChars: number;
|
|
52
|
+
/** 本次使用的模型(provider/id,审计用);未配置 → null */
|
|
53
|
+
model: string | null;
|
|
54
|
+
/** 批规划(seq 升序,各批的章 id 列表按文件序) */
|
|
55
|
+
batches: readonly {
|
|
56
|
+
seq: number;
|
|
57
|
+
chapterIds: readonly string[];
|
|
58
|
+
}[];
|
|
59
|
+
now: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 创建 job 并落全部批行(S1 的组批结果)——**同一事务**:job 与批规划要么同时存在,要么都不存在。
|
|
63
|
+
* job 初始状态 = `pending`(启动 = `updateJobStatus(status='running')`);
|
|
64
|
+
* 批行初始状态 = `pending`、`attempts = 0`、`result = NULL`。
|
|
65
|
+
*
|
|
66
|
+
* @returns 落库后的 job 行(id 由本模块生成,`job-` 前缀 + nanoid)
|
|
67
|
+
*/
|
|
68
|
+
export declare function createDecomposeJob(db: Db, input: CreateDecomposeJobInput): DecomposeJobRow;
|
|
69
|
+
/**
|
|
70
|
+
* 读当前项目的 job(进度轮询、端点解析用)。
|
|
71
|
+
* 一项目一 job 是业务层不变式(`docs/db/schema.md`);多行时取最新创建的一条。
|
|
72
|
+
* @returns 行对象;从未开始拆解 → null(端点侧 404 `DECOMPOSE_JOB_NOT_FOUND`)
|
|
73
|
+
*/
|
|
74
|
+
export declare function getDecomposeJob(db: Db): DecomposeJobRow | null;
|
|
75
|
+
/**
|
|
76
|
+
* 读**全部** job 行(创建时间升序,同时间按 id)——S3 三路比对的**跨轮 baseline** 面:
|
|
77
|
+
* 「历史全部 job 的 `merge_written` 并集(同一 id 取最新一次记录的时间戳)」按此顺序覆盖取并
|
|
78
|
+
* (`docs/design/60-decompose.md` §6.1)。
|
|
79
|
+
*/
|
|
80
|
+
export declare function listDecomposeJobs(db: Db): DecomposeJobRow[];
|
|
81
|
+
/**
|
|
82
|
+
* job 状态流转(pending → running → paused/done/failed;前置状态校验归端点/runner,
|
|
83
|
+
* 状态字面量集见 `DecomposeJobStatus`)。同时推进 `updated_at`(进度轮询的时间戳)。
|
|
84
|
+
* @returns 影响行数(0 = job 不存在)
|
|
85
|
+
*/
|
|
86
|
+
export declare function updateJobStatus(db: Db, jobId: string, status: DecomposeJobStatus, now: string): number;
|
|
87
|
+
/**
|
|
88
|
+
* 写 job 级错误摘要(`null` = 清除,如续拆/重跑开工时)。
|
|
89
|
+
* @returns 影响行数(0 = job 不存在)
|
|
90
|
+
*/
|
|
91
|
+
export declare function setJobError(db: Db, jobId: string, error: string | null, now: string): number;
|
|
92
|
+
/**
|
|
93
|
+
* **状态归一**(打开项目时调用):把残留的 `running` 改判为 `paused`——进程内已无在跑 job
|
|
94
|
+
* (服务端重启 / 进程崩溃),UI 提示「上次拆解中断,可续拆」(`docs/design/60-decompose.md` §7)。
|
|
95
|
+
*
|
|
96
|
+
* 批行不动:续拆从第一个未完成批继续,`startBatchAttempt` 对残留 `running` 批同样成立
|
|
97
|
+
* (重新计入一次尝试),无需单独归一。
|
|
98
|
+
*
|
|
99
|
+
* @returns 被归一的 job 条数(正常路径 0)
|
|
100
|
+
*/
|
|
101
|
+
export declare function pauseRunningJobs(db: Db, now: string): number;
|
|
102
|
+
/**
|
|
103
|
+
* 写 `merge_written` 清单(上次归并写入的实体/关系/报告 id + 写入时 `updated_at`)——
|
|
104
|
+
* 重跑 S3 的三路比对快照(§6.1)。
|
|
105
|
+
* @returns 影响行数(0 = job 不存在)
|
|
106
|
+
*/
|
|
107
|
+
export declare function writeMergeWritten(db: Db, jobId: string, entries: readonly DecomposeMergeWrittenEntry[], now: string): number;
|
|
108
|
+
/**
|
|
109
|
+
* 删除 job 及其全部批行(**同事务**;无外键,孤儿批行只能由本函数拦住)。
|
|
110
|
+
* 用于清场重来(重跑整套 / 重置拆解);删整本书走书目录删除、不经过本函数。
|
|
111
|
+
* @returns 删除的总行数(job 1 + 批 N;不存在 → 0,幂等)
|
|
112
|
+
*/
|
|
113
|
+
export declare function deleteDecomposeJob(db: Db, jobId: string): number;
|
|
114
|
+
/**
|
|
115
|
+
* 读某 job 的批列表(**不含 `result`**,按 `seq` 升序)。
|
|
116
|
+
* 列表口径投影:不 SELECT `result`——数百批 × 每条千级 token 的结果正文不得进列表响应。
|
|
117
|
+
*/
|
|
118
|
+
export declare function listDecomposeBatches(db: Db, jobId: string): DecomposeBatchRow[];
|
|
119
|
+
/** 读单批(含 `result`)——进度页展开行时按需拉取;批序号越界 → null(端点侧 404) */
|
|
120
|
+
export declare function getDecomposeBatch(db: Db, jobId: string, seq: number): DecomposeBatchDetailRow | null;
|
|
121
|
+
/**
|
|
122
|
+
* 开始一次尝试:批状态 → `running`、`attempts` 自增、清上一条错误摘要。
|
|
123
|
+
* 对 `pending` / `failed` / 残留 `running` 同样成立(续拆重取同一批即新一轮尝试)。
|
|
124
|
+
* @returns 自增后的尝试序号;批不存在 → null
|
|
125
|
+
*/
|
|
126
|
+
export declare function startBatchAttempt(db: Db, jobId: string, seq: number, now: string): number | null;
|
|
127
|
+
/** 批完成:抽取结果落库、状态 → `done`、清错误摘要 */
|
|
128
|
+
export declare function completeBatch(db: Db, input: {
|
|
129
|
+
jobId: string;
|
|
130
|
+
seq: number;
|
|
131
|
+
result: DecomposeBatchResult;
|
|
132
|
+
now: string;
|
|
133
|
+
}): number;
|
|
134
|
+
/**
|
|
135
|
+
* 批失败:状态 → `failed` + 失败摘要;`result` 置 **NULL**(契约口径「未完成 = NULL」——
|
|
136
|
+
* 重跑失败后不得留着上一轮结果冒充本批产物)。
|
|
137
|
+
*/
|
|
138
|
+
export declare function failBatch(db: Db, input: {
|
|
139
|
+
jobId: string;
|
|
140
|
+
seq: number;
|
|
141
|
+
error: string;
|
|
142
|
+
now: string;
|
|
143
|
+
}): number;
|
|
144
|
+
//# sourceMappingURL=decompose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decompose.d.ts","sourceRoot":"","sources":["../../src/queries/decompose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
// @whispering233/ai-editor-db 拆解小说 job / 批读写(卡 21.3)
|
|
2
|
+
//
|
|
3
|
+
// 契约:docs/db/schema.md「decompose_jobs / decompose_batches」(两表 DDL + 不变式表)、
|
|
4
|
+
// docs/design/60-decompose.md §7(状态机与续拆)、§6.1(merge_written 三路比对)。
|
|
5
|
+
// - **库写入唯一入口 = 本模块**(禁止绕过直接写表);查询经 queryDb 取 drizzle 实例。
|
|
6
|
+
// - JSON 列(chapter_ids / result / merge_written)保持 **text 模式**,行映射层防御解析
|
|
7
|
+
// (坏行 → 空数组 / null,与 entity.ts parseDataColumn 同口径)——坏 JSON 不得打挂查询。
|
|
8
|
+
// - 时间约定:ISO 8601 应用层写入(`now` 由调用方传入,模块内不生成时间)。
|
|
9
|
+
// - 状态字面量单一来源 = shared API 契约(`DecomposeJobRes` / `DecomposeBatchRes` 的状态投影),
|
|
10
|
+
// 本模块不复抄清单、DDL 也不加 CHECK。
|
|
11
|
+
// - 批行只由本模块写;批结果(`result`)是 S2 的暂存中间产物,业务表只由 S3 写。
|
|
12
|
+
import { generateId } from "@whispering233/ai-editor-shared";
|
|
13
|
+
import { and, asc, desc, eq, sql } from "drizzle-orm";
|
|
14
|
+
import { withTransaction } from "../connection.js";
|
|
15
|
+
import { queryDb } from "../query-db.js";
|
|
16
|
+
import { decomposeBatches, decomposeJobs } from "../tables.js";
|
|
17
|
+
/** job id 前缀(api-public id 约定 `{前缀}-{nanoid}`;job 用 `job-`) */
|
|
18
|
+
export const DECOMPOSE_JOB_ID_PREFIX = "job-";
|
|
19
|
+
// ============ 行映射(JSON 列防御解析) ============
|
|
20
|
+
/** 解析 JSON 字符串数组(坏 JSON / 非数组 / 非字符串项 → 丢弃,返回空数组) */
|
|
21
|
+
function parseStringArray(value) {
|
|
22
|
+
if (typeof value !== "string")
|
|
23
|
+
return [];
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(value);
|
|
26
|
+
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** 单项形状守卫(坏清单项丢弃,不阻断整行读取) */
|
|
33
|
+
function isMergeWrittenEntry(value) {
|
|
34
|
+
if (typeof value !== "object" || value === null)
|
|
35
|
+
return false;
|
|
36
|
+
const entry = value;
|
|
37
|
+
return typeof entry.id === "string" && typeof entry.type === "string" && typeof entry.updated_at === "string";
|
|
38
|
+
}
|
|
39
|
+
/** 解析 merge_written 清单(坏 JSON / 非数组 → 空数组 = 从未归并) */
|
|
40
|
+
function parseMergeWritten(value) {
|
|
41
|
+
if (typeof value !== "string")
|
|
42
|
+
return [];
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(value);
|
|
45
|
+
return Array.isArray(parsed) ? parsed.filter(isMergeWrittenEntry) : [];
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 解析批抽取结果(坏 JSON / 非对象 → null = 未完成)。
|
|
53
|
+
* 形状校验归 server 的抽取层(模型原始输出在落库前已归一),本包只保证**坏 JSON 不抛错**。
|
|
54
|
+
*/
|
|
55
|
+
function parseBatchResult(value) {
|
|
56
|
+
if (typeof value !== "string")
|
|
57
|
+
return null;
|
|
58
|
+
try {
|
|
59
|
+
const parsed = JSON.parse(value);
|
|
60
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** 行 → job 行(坏 JSON 防御见 parseMergeWritten) */
|
|
67
|
+
function toJobRow(row) {
|
|
68
|
+
return {
|
|
69
|
+
id: row.id,
|
|
70
|
+
status: row.status,
|
|
71
|
+
scope_start: row.scope_start,
|
|
72
|
+
scope_end: row.scope_end,
|
|
73
|
+
batch_target_chars: row.batch_target_chars,
|
|
74
|
+
model: row.model ?? null,
|
|
75
|
+
merge_written: parseMergeWritten(row.merge_written),
|
|
76
|
+
error: row.error ?? null,
|
|
77
|
+
created_at: row.created_at,
|
|
78
|
+
updated_at: row.updated_at,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** 行 → 批行(不含 result) */
|
|
82
|
+
function toBatchRow(row) {
|
|
83
|
+
return {
|
|
84
|
+
job_id: row.job_id,
|
|
85
|
+
seq: row.seq,
|
|
86
|
+
chapter_ids: parseStringArray(row.chapter_ids),
|
|
87
|
+
status: row.status,
|
|
88
|
+
attempts: row.attempts,
|
|
89
|
+
error: row.error ?? null,
|
|
90
|
+
updated_at: row.updated_at,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// ============ job ============
|
|
94
|
+
/**
|
|
95
|
+
* 创建 job 并落全部批行(S1 的组批结果)——**同一事务**:job 与批规划要么同时存在,要么都不存在。
|
|
96
|
+
* job 初始状态 = `pending`(启动 = `updateJobStatus(status='running')`);
|
|
97
|
+
* 批行初始状态 = `pending`、`attempts = 0`、`result = NULL`。
|
|
98
|
+
*
|
|
99
|
+
* @returns 落库后的 job 行(id 由本模块生成,`job-` 前缀 + nanoid)
|
|
100
|
+
*/
|
|
101
|
+
export function createDecomposeJob(db, input) {
|
|
102
|
+
const id = generateId(DECOMPOSE_JOB_ID_PREFIX);
|
|
103
|
+
withTransaction(db, () => {
|
|
104
|
+
const q = queryDb(db);
|
|
105
|
+
q.insert(decomposeJobs)
|
|
106
|
+
.values({
|
|
107
|
+
id,
|
|
108
|
+
status: "pending",
|
|
109
|
+
scope_start: input.scopeStart,
|
|
110
|
+
scope_end: input.scopeEnd,
|
|
111
|
+
batch_target_chars: input.batchTargetChars,
|
|
112
|
+
model: input.model,
|
|
113
|
+
merge_written: null,
|
|
114
|
+
error: null,
|
|
115
|
+
created_at: input.now,
|
|
116
|
+
updated_at: input.now,
|
|
117
|
+
})
|
|
118
|
+
.run();
|
|
119
|
+
if (input.batches.length > 0) {
|
|
120
|
+
q.insert(decomposeBatches)
|
|
121
|
+
.values(input.batches.map((batch) => ({
|
|
122
|
+
job_id: id,
|
|
123
|
+
seq: batch.seq,
|
|
124
|
+
chapter_ids: JSON.stringify(batch.chapterIds),
|
|
125
|
+
status: "pending",
|
|
126
|
+
result: null,
|
|
127
|
+
attempts: 0,
|
|
128
|
+
error: null,
|
|
129
|
+
updated_at: input.now,
|
|
130
|
+
})))
|
|
131
|
+
.run();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
const row = selectJobRow(db, id);
|
|
135
|
+
if (row === null)
|
|
136
|
+
throw new Error(`createDecomposeJob: job ${id} 落库后读取失败`);
|
|
137
|
+
return row;
|
|
138
|
+
}
|
|
139
|
+
/** 按 id 读 job 行(内部:创建后回读) */
|
|
140
|
+
function selectJobRow(db, jobId) {
|
|
141
|
+
const row = queryDb(db).select().from(decomposeJobs).where(eq(decomposeJobs.id, jobId)).get();
|
|
142
|
+
return row === undefined ? null : toJobRow(row);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 读当前项目的 job(进度轮询、端点解析用)。
|
|
146
|
+
* 一项目一 job 是业务层不变式(`docs/db/schema.md`);多行时取最新创建的一条。
|
|
147
|
+
* @returns 行对象;从未开始拆解 → null(端点侧 404 `DECOMPOSE_JOB_NOT_FOUND`)
|
|
148
|
+
*/
|
|
149
|
+
export function getDecomposeJob(db) {
|
|
150
|
+
const row = queryDb(db)
|
|
151
|
+
.select()
|
|
152
|
+
.from(decomposeJobs)
|
|
153
|
+
.orderBy(desc(decomposeJobs.created_at), desc(decomposeJobs.id))
|
|
154
|
+
.limit(1)
|
|
155
|
+
.get();
|
|
156
|
+
return row === undefined ? null : toJobRow(row);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 读**全部** job 行(创建时间升序,同时间按 id)——S3 三路比对的**跨轮 baseline** 面:
|
|
160
|
+
* 「历史全部 job 的 `merge_written` 并集(同一 id 取最新一次记录的时间戳)」按此顺序覆盖取并
|
|
161
|
+
* (`docs/design/60-decompose.md` §6.1)。
|
|
162
|
+
*/
|
|
163
|
+
export function listDecomposeJobs(db) {
|
|
164
|
+
const rows = queryDb(db)
|
|
165
|
+
.select()
|
|
166
|
+
.from(decomposeJobs)
|
|
167
|
+
.orderBy(asc(decomposeJobs.created_at), asc(decomposeJobs.id))
|
|
168
|
+
.all();
|
|
169
|
+
return rows.map(toJobRow);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* job 状态流转(pending → running → paused/done/failed;前置状态校验归端点/runner,
|
|
173
|
+
* 状态字面量集见 `DecomposeJobStatus`)。同时推进 `updated_at`(进度轮询的时间戳)。
|
|
174
|
+
* @returns 影响行数(0 = job 不存在)
|
|
175
|
+
*/
|
|
176
|
+
export function updateJobStatus(db, jobId, status, now) {
|
|
177
|
+
return queryDb(db)
|
|
178
|
+
.update(decomposeJobs)
|
|
179
|
+
.set({ status, updated_at: now })
|
|
180
|
+
.where(eq(decomposeJobs.id, jobId))
|
|
181
|
+
.run().changes;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 写 job 级错误摘要(`null` = 清除,如续拆/重跑开工时)。
|
|
185
|
+
* @returns 影响行数(0 = job 不存在)
|
|
186
|
+
*/
|
|
187
|
+
export function setJobError(db, jobId, error, now) {
|
|
188
|
+
return queryDb(db)
|
|
189
|
+
.update(decomposeJobs)
|
|
190
|
+
.set({ error, updated_at: now })
|
|
191
|
+
.where(eq(decomposeJobs.id, jobId))
|
|
192
|
+
.run().changes;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* **状态归一**(打开项目时调用):把残留的 `running` 改判为 `paused`——进程内已无在跑 job
|
|
196
|
+
* (服务端重启 / 进程崩溃),UI 提示「上次拆解中断,可续拆」(`docs/design/60-decompose.md` §7)。
|
|
197
|
+
*
|
|
198
|
+
* 批行不动:续拆从第一个未完成批继续,`startBatchAttempt` 对残留 `running` 批同样成立
|
|
199
|
+
* (重新计入一次尝试),无需单独归一。
|
|
200
|
+
*
|
|
201
|
+
* @returns 被归一的 job 条数(正常路径 0)
|
|
202
|
+
*/
|
|
203
|
+
export function pauseRunningJobs(db, now) {
|
|
204
|
+
return queryDb(db)
|
|
205
|
+
.update(decomposeJobs)
|
|
206
|
+
.set({ status: "paused", updated_at: now })
|
|
207
|
+
.where(eq(decomposeJobs.status, "running"))
|
|
208
|
+
.run().changes;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 写 `merge_written` 清单(上次归并写入的实体/关系/报告 id + 写入时 `updated_at`)——
|
|
212
|
+
* 重跑 S3 的三路比对快照(§6.1)。
|
|
213
|
+
* @returns 影响行数(0 = job 不存在)
|
|
214
|
+
*/
|
|
215
|
+
export function writeMergeWritten(db, jobId, entries, now) {
|
|
216
|
+
return queryDb(db)
|
|
217
|
+
.update(decomposeJobs)
|
|
218
|
+
.set({ merge_written: JSON.stringify(entries), updated_at: now })
|
|
219
|
+
.where(eq(decomposeJobs.id, jobId))
|
|
220
|
+
.run().changes;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* 删除 job 及其全部批行(**同事务**;无外键,孤儿批行只能由本函数拦住)。
|
|
224
|
+
* 用于清场重来(重跑整套 / 重置拆解);删整本书走书目录删除、不经过本函数。
|
|
225
|
+
* @returns 删除的总行数(job 1 + 批 N;不存在 → 0,幂等)
|
|
226
|
+
*/
|
|
227
|
+
export function deleteDecomposeJob(db, jobId) {
|
|
228
|
+
return withTransaction(db, () => {
|
|
229
|
+
const q = queryDb(db);
|
|
230
|
+
const batches = q.delete(decomposeBatches).where(eq(decomposeBatches.job_id, jobId)).run().changes;
|
|
231
|
+
const jobs = q.delete(decomposeJobs).where(eq(decomposeJobs.id, jobId)).run().changes;
|
|
232
|
+
return jobs + batches;
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
// ============ 批 ============
|
|
236
|
+
/**
|
|
237
|
+
* 读某 job 的批列表(**不含 `result`**,按 `seq` 升序)。
|
|
238
|
+
* 列表口径投影:不 SELECT `result`——数百批 × 每条千级 token 的结果正文不得进列表响应。
|
|
239
|
+
*/
|
|
240
|
+
export function listDecomposeBatches(db, jobId) {
|
|
241
|
+
const rows = queryDb(db)
|
|
242
|
+
.select({
|
|
243
|
+
job_id: decomposeBatches.job_id,
|
|
244
|
+
seq: decomposeBatches.seq,
|
|
245
|
+
chapter_ids: decomposeBatches.chapter_ids,
|
|
246
|
+
status: decomposeBatches.status,
|
|
247
|
+
attempts: decomposeBatches.attempts,
|
|
248
|
+
error: decomposeBatches.error,
|
|
249
|
+
updated_at: decomposeBatches.updated_at,
|
|
250
|
+
})
|
|
251
|
+
.from(decomposeBatches)
|
|
252
|
+
.where(eq(decomposeBatches.job_id, jobId))
|
|
253
|
+
.orderBy(asc(decomposeBatches.seq))
|
|
254
|
+
.all();
|
|
255
|
+
return rows.map(toBatchRow);
|
|
256
|
+
}
|
|
257
|
+
/** 读单批(含 `result`)——进度页展开行时按需拉取;批序号越界 → null(端点侧 404) */
|
|
258
|
+
export function getDecomposeBatch(db, jobId, seq) {
|
|
259
|
+
const row = queryDb(db)
|
|
260
|
+
.select()
|
|
261
|
+
.from(decomposeBatches)
|
|
262
|
+
.where(and(eq(decomposeBatches.job_id, jobId), eq(decomposeBatches.seq, seq)))
|
|
263
|
+
.get();
|
|
264
|
+
if (row === undefined)
|
|
265
|
+
return null;
|
|
266
|
+
return { ...toBatchRow(row), result: parseBatchResult(row.result) };
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 开始一次尝试:批状态 → `running`、`attempts` 自增、清上一条错误摘要。
|
|
270
|
+
* 对 `pending` / `failed` / 残留 `running` 同样成立(续拆重取同一批即新一轮尝试)。
|
|
271
|
+
* @returns 自增后的尝试序号;批不存在 → null
|
|
272
|
+
*/
|
|
273
|
+
export function startBatchAttempt(db, jobId, seq, now) {
|
|
274
|
+
return withTransaction(db, () => {
|
|
275
|
+
const q = queryDb(db);
|
|
276
|
+
const changes = q
|
|
277
|
+
.update(decomposeBatches)
|
|
278
|
+
.set({ status: "running", attempts: sql `${decomposeBatches.attempts} + 1`, error: null, updated_at: now })
|
|
279
|
+
.where(and(eq(decomposeBatches.job_id, jobId), eq(decomposeBatches.seq, seq)))
|
|
280
|
+
.run().changes;
|
|
281
|
+
if (changes === 0)
|
|
282
|
+
return null;
|
|
283
|
+
const row = q
|
|
284
|
+
.select({ attempts: decomposeBatches.attempts })
|
|
285
|
+
.from(decomposeBatches)
|
|
286
|
+
.where(and(eq(decomposeBatches.job_id, jobId), eq(decomposeBatches.seq, seq)))
|
|
287
|
+
.get();
|
|
288
|
+
return row?.attempts ?? null;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/** 批完成:抽取结果落库、状态 → `done`、清错误摘要 */
|
|
292
|
+
export function completeBatch(db, input) {
|
|
293
|
+
return queryDb(db)
|
|
294
|
+
.update(decomposeBatches)
|
|
295
|
+
.set({ status: "done", result: JSON.stringify(input.result), error: null, updated_at: input.now })
|
|
296
|
+
.where(and(eq(decomposeBatches.job_id, input.jobId), eq(decomposeBatches.seq, input.seq)))
|
|
297
|
+
.run().changes;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* 批失败:状态 → `failed` + 失败摘要;`result` 置 **NULL**(契约口径「未完成 = NULL」——
|
|
301
|
+
* 重跑失败后不得留着上一轮结果冒充本批产物)。
|
|
302
|
+
*/
|
|
303
|
+
export function failBatch(db, input) {
|
|
304
|
+
return queryDb(db)
|
|
305
|
+
.update(decomposeBatches)
|
|
306
|
+
.set({ status: "failed", result: null, error: input.error, updated_at: input.now })
|
|
307
|
+
.where(and(eq(decomposeBatches.job_id, input.jobId), eq(decomposeBatches.seq, input.seq)))
|
|
308
|
+
.run().changes;
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=decompose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../src/queries/decompose.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -16,8 +16,10 @@ import type Database from "better-sqlite3";
|
|
|
16
16
|
* 迁为 `ability_panel` 顶层分组「能力」下的叶子(migrations/007_character_ability_panel.ts)。
|
|
17
17
|
* v7 → v8(块文档,2026-09):新增 `document_records` 表(章正文 / 参考资料正文,
|
|
18
18
|
* 纯 DDL 无数据搬移,migrations/008_document_records.ts)。
|
|
19
|
+
* v8 → v9(拆解小说,2026-09):新增 `decompose_jobs` / `decompose_batches` 两表
|
|
20
|
+
* (job 状态与批结果暂存,纯 DDL 无数据搬移,migrations/009_decompose.ts)。
|
|
19
21
|
*/
|
|
20
|
-
export declare const SCHEMA_VERSION =
|
|
22
|
+
export declare const SCHEMA_VERSION = 9;
|
|
21
23
|
/**
|
|
22
24
|
* 建表:执行全部 DDL(CREATE TABLE/INDEX IF NOT EXISTS,定义于 tables.ts),幂等,可重复调用。
|
|
23
25
|
* 打开数据库后由 connection.openDatabase 自动调用。
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAExD;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAK3E"}
|
package/dist/schema.js
CHANGED
|
@@ -21,8 +21,10 @@ import { CREATE_TABLES_SQL } from "./tables.js";
|
|
|
21
21
|
* 迁为 `ability_panel` 顶层分组「能力」下的叶子(migrations/007_character_ability_panel.ts)。
|
|
22
22
|
* v7 → v8(块文档,2026-09):新增 `document_records` 表(章正文 / 参考资料正文,
|
|
23
23
|
* 纯 DDL 无数据搬移,migrations/008_document_records.ts)。
|
|
24
|
+
* v8 → v9(拆解小说,2026-09):新增 `decompose_jobs` / `decompose_batches` 两表
|
|
25
|
+
* (job 状态与批结果暂存,纯 DDL 无数据搬移,migrations/009_decompose.ts)。
|
|
24
26
|
*/
|
|
25
|
-
export const SCHEMA_VERSION =
|
|
27
|
+
export const SCHEMA_VERSION = 9; // +拆解两表 decompose_jobs / decompose_batches(009_decompose.ts 纯 DDL)
|
|
26
28
|
/**
|
|
27
29
|
* 建表:执行全部 DDL(CREATE TABLE/INDEX IF NOT EXISTS,定义于 tables.ts),幂等,可重复调用。
|
|
28
30
|
* 打开数据库后由 connection.openDatabase 自动调用。
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,kDAAkD;AAClD,oCAAoC;AACpC,kFAAkF;AAGlF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,kDAAkD;AAClD,oCAAoC;AACpC,kFAAkF;AAGlF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC,mEAAmE;AAEpG;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAAqB;IAChD,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAC7B,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,cAAc,CAAC,EAAqB;IAClD,OAAO,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAqB,EAAE,OAAe;IACnE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;AACzC,CAAC"}
|
package/dist/tables.d.ts
CHANGED
|
@@ -678,8 +678,363 @@ export declare const documentRecords: import("drizzle-orm/sqlite-core").SQLiteTa
|
|
|
678
678
|
dialect: "sqlite";
|
|
679
679
|
}>;
|
|
680
680
|
/**
|
|
681
|
-
*
|
|
681
|
+
* decompose_jobs:拆解小说 job(导入式批量管线,设计见 docs/design/60-decompose.md)。
|
|
682
|
+
* 一项目一 job(业务层保证,不设唯一约束):状态机 pending → running → (paused | done | failed),
|
|
683
|
+
* 范围与组批口径是 S1 的快照(续拆/重跑按同一口径重算批次);无 deleted_at——撤销 = 删书或恢复备份。
|
|
684
|
+
*/
|
|
685
|
+
export declare const decomposeJobs: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
686
|
+
name: "decompose_jobs";
|
|
687
|
+
schema: undefined;
|
|
688
|
+
columns: {
|
|
689
|
+
id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
690
|
+
name: "id";
|
|
691
|
+
tableName: "decompose_jobs";
|
|
692
|
+
dataType: "string";
|
|
693
|
+
columnType: "SQLiteText";
|
|
694
|
+
data: string;
|
|
695
|
+
driverParam: string;
|
|
696
|
+
notNull: true;
|
|
697
|
+
hasDefault: false;
|
|
698
|
+
isPrimaryKey: true;
|
|
699
|
+
isAutoincrement: false;
|
|
700
|
+
hasRuntimeDefault: false;
|
|
701
|
+
enumValues: [string, ...string[]];
|
|
702
|
+
baseColumn: never;
|
|
703
|
+
identity: undefined;
|
|
704
|
+
generated: undefined;
|
|
705
|
+
}, {}, {
|
|
706
|
+
length: number | undefined;
|
|
707
|
+
}>;
|
|
708
|
+
status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
709
|
+
name: "status";
|
|
710
|
+
tableName: "decompose_jobs";
|
|
711
|
+
dataType: "string";
|
|
712
|
+
columnType: "SQLiteText";
|
|
713
|
+
data: string;
|
|
714
|
+
driverParam: string;
|
|
715
|
+
notNull: true;
|
|
716
|
+
hasDefault: false;
|
|
717
|
+
isPrimaryKey: false;
|
|
718
|
+
isAutoincrement: false;
|
|
719
|
+
hasRuntimeDefault: false;
|
|
720
|
+
enumValues: [string, ...string[]];
|
|
721
|
+
baseColumn: never;
|
|
722
|
+
identity: undefined;
|
|
723
|
+
generated: undefined;
|
|
724
|
+
}, {}, {
|
|
725
|
+
length: number | undefined;
|
|
726
|
+
}>;
|
|
727
|
+
scope_start: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
728
|
+
name: "scope_start";
|
|
729
|
+
tableName: "decompose_jobs";
|
|
730
|
+
dataType: "number";
|
|
731
|
+
columnType: "SQLiteInteger";
|
|
732
|
+
data: number;
|
|
733
|
+
driverParam: number;
|
|
734
|
+
notNull: true;
|
|
735
|
+
hasDefault: false;
|
|
736
|
+
isPrimaryKey: false;
|
|
737
|
+
isAutoincrement: false;
|
|
738
|
+
hasRuntimeDefault: false;
|
|
739
|
+
enumValues: undefined;
|
|
740
|
+
baseColumn: never;
|
|
741
|
+
identity: undefined;
|
|
742
|
+
generated: undefined;
|
|
743
|
+
}, {}, {}>;
|
|
744
|
+
scope_end: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
745
|
+
name: "scope_end";
|
|
746
|
+
tableName: "decompose_jobs";
|
|
747
|
+
dataType: "number";
|
|
748
|
+
columnType: "SQLiteInteger";
|
|
749
|
+
data: number;
|
|
750
|
+
driverParam: number;
|
|
751
|
+
notNull: true;
|
|
752
|
+
hasDefault: false;
|
|
753
|
+
isPrimaryKey: false;
|
|
754
|
+
isAutoincrement: false;
|
|
755
|
+
hasRuntimeDefault: false;
|
|
756
|
+
enumValues: undefined;
|
|
757
|
+
baseColumn: never;
|
|
758
|
+
identity: undefined;
|
|
759
|
+
generated: undefined;
|
|
760
|
+
}, {}, {}>;
|
|
761
|
+
batch_target_chars: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
762
|
+
name: "batch_target_chars";
|
|
763
|
+
tableName: "decompose_jobs";
|
|
764
|
+
dataType: "number";
|
|
765
|
+
columnType: "SQLiteInteger";
|
|
766
|
+
data: number;
|
|
767
|
+
driverParam: number;
|
|
768
|
+
notNull: true;
|
|
769
|
+
hasDefault: false;
|
|
770
|
+
isPrimaryKey: false;
|
|
771
|
+
isAutoincrement: false;
|
|
772
|
+
hasRuntimeDefault: false;
|
|
773
|
+
enumValues: undefined;
|
|
774
|
+
baseColumn: never;
|
|
775
|
+
identity: undefined;
|
|
776
|
+
generated: undefined;
|
|
777
|
+
}, {}, {}>;
|
|
778
|
+
model: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
779
|
+
name: "model";
|
|
780
|
+
tableName: "decompose_jobs";
|
|
781
|
+
dataType: "string";
|
|
782
|
+
columnType: "SQLiteText";
|
|
783
|
+
data: string;
|
|
784
|
+
driverParam: string;
|
|
785
|
+
notNull: false;
|
|
786
|
+
hasDefault: false;
|
|
787
|
+
isPrimaryKey: false;
|
|
788
|
+
isAutoincrement: false;
|
|
789
|
+
hasRuntimeDefault: false;
|
|
790
|
+
enumValues: [string, ...string[]];
|
|
791
|
+
baseColumn: never;
|
|
792
|
+
identity: undefined;
|
|
793
|
+
generated: undefined;
|
|
794
|
+
}, {}, {
|
|
795
|
+
length: number | undefined;
|
|
796
|
+
}>;
|
|
797
|
+
merge_written: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
798
|
+
name: "merge_written";
|
|
799
|
+
tableName: "decompose_jobs";
|
|
800
|
+
dataType: "string";
|
|
801
|
+
columnType: "SQLiteText";
|
|
802
|
+
data: string;
|
|
803
|
+
driverParam: string;
|
|
804
|
+
notNull: false;
|
|
805
|
+
hasDefault: false;
|
|
806
|
+
isPrimaryKey: false;
|
|
807
|
+
isAutoincrement: false;
|
|
808
|
+
hasRuntimeDefault: false;
|
|
809
|
+
enumValues: [string, ...string[]];
|
|
810
|
+
baseColumn: never;
|
|
811
|
+
identity: undefined;
|
|
812
|
+
generated: undefined;
|
|
813
|
+
}, {}, {
|
|
814
|
+
length: number | undefined;
|
|
815
|
+
}>;
|
|
816
|
+
error: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
817
|
+
name: "error";
|
|
818
|
+
tableName: "decompose_jobs";
|
|
819
|
+
dataType: "string";
|
|
820
|
+
columnType: "SQLiteText";
|
|
821
|
+
data: string;
|
|
822
|
+
driverParam: string;
|
|
823
|
+
notNull: false;
|
|
824
|
+
hasDefault: false;
|
|
825
|
+
isPrimaryKey: false;
|
|
826
|
+
isAutoincrement: false;
|
|
827
|
+
hasRuntimeDefault: false;
|
|
828
|
+
enumValues: [string, ...string[]];
|
|
829
|
+
baseColumn: never;
|
|
830
|
+
identity: undefined;
|
|
831
|
+
generated: undefined;
|
|
832
|
+
}, {}, {
|
|
833
|
+
length: number | undefined;
|
|
834
|
+
}>;
|
|
835
|
+
created_at: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
836
|
+
name: "created_at";
|
|
837
|
+
tableName: "decompose_jobs";
|
|
838
|
+
dataType: "string";
|
|
839
|
+
columnType: "SQLiteText";
|
|
840
|
+
data: string;
|
|
841
|
+
driverParam: string;
|
|
842
|
+
notNull: true;
|
|
843
|
+
hasDefault: false;
|
|
844
|
+
isPrimaryKey: false;
|
|
845
|
+
isAutoincrement: false;
|
|
846
|
+
hasRuntimeDefault: false;
|
|
847
|
+
enumValues: [string, ...string[]];
|
|
848
|
+
baseColumn: never;
|
|
849
|
+
identity: undefined;
|
|
850
|
+
generated: undefined;
|
|
851
|
+
}, {}, {
|
|
852
|
+
length: number | undefined;
|
|
853
|
+
}>;
|
|
854
|
+
updated_at: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
855
|
+
name: "updated_at";
|
|
856
|
+
tableName: "decompose_jobs";
|
|
857
|
+
dataType: "string";
|
|
858
|
+
columnType: "SQLiteText";
|
|
859
|
+
data: string;
|
|
860
|
+
driverParam: string;
|
|
861
|
+
notNull: true;
|
|
862
|
+
hasDefault: false;
|
|
863
|
+
isPrimaryKey: false;
|
|
864
|
+
isAutoincrement: false;
|
|
865
|
+
hasRuntimeDefault: false;
|
|
866
|
+
enumValues: [string, ...string[]];
|
|
867
|
+
baseColumn: never;
|
|
868
|
+
identity: undefined;
|
|
869
|
+
generated: undefined;
|
|
870
|
+
}, {}, {
|
|
871
|
+
length: number | undefined;
|
|
872
|
+
}>;
|
|
873
|
+
};
|
|
874
|
+
dialect: "sqlite";
|
|
875
|
+
}>;
|
|
876
|
+
/**
|
|
877
|
+
* decompose_batches:批规划与批结果暂存(S2 的中间产物,不是待确认草稿)。
|
|
878
|
+
* 批结果只落 `result`(业务数据由 S3 写);无外键——job 行删除时批行由 helper 连带删。
|
|
879
|
+
*/
|
|
880
|
+
export declare const decomposeBatches: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
881
|
+
name: "decompose_batches";
|
|
882
|
+
schema: undefined;
|
|
883
|
+
columns: {
|
|
884
|
+
job_id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
885
|
+
name: "job_id";
|
|
886
|
+
tableName: "decompose_batches";
|
|
887
|
+
dataType: "string";
|
|
888
|
+
columnType: "SQLiteText";
|
|
889
|
+
data: string;
|
|
890
|
+
driverParam: string;
|
|
891
|
+
notNull: true;
|
|
892
|
+
hasDefault: false;
|
|
893
|
+
isPrimaryKey: false;
|
|
894
|
+
isAutoincrement: false;
|
|
895
|
+
hasRuntimeDefault: false;
|
|
896
|
+
enumValues: [string, ...string[]];
|
|
897
|
+
baseColumn: never;
|
|
898
|
+
identity: undefined;
|
|
899
|
+
generated: undefined;
|
|
900
|
+
}, {}, {
|
|
901
|
+
length: number | undefined;
|
|
902
|
+
}>;
|
|
903
|
+
seq: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
904
|
+
name: "seq";
|
|
905
|
+
tableName: "decompose_batches";
|
|
906
|
+
dataType: "number";
|
|
907
|
+
columnType: "SQLiteInteger";
|
|
908
|
+
data: number;
|
|
909
|
+
driverParam: number;
|
|
910
|
+
notNull: true;
|
|
911
|
+
hasDefault: false;
|
|
912
|
+
isPrimaryKey: false;
|
|
913
|
+
isAutoincrement: false;
|
|
914
|
+
hasRuntimeDefault: false;
|
|
915
|
+
enumValues: undefined;
|
|
916
|
+
baseColumn: never;
|
|
917
|
+
identity: undefined;
|
|
918
|
+
generated: undefined;
|
|
919
|
+
}, {}, {}>;
|
|
920
|
+
chapter_ids: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
921
|
+
name: "chapter_ids";
|
|
922
|
+
tableName: "decompose_batches";
|
|
923
|
+
dataType: "string";
|
|
924
|
+
columnType: "SQLiteText";
|
|
925
|
+
data: string;
|
|
926
|
+
driverParam: string;
|
|
927
|
+
notNull: true;
|
|
928
|
+
hasDefault: false;
|
|
929
|
+
isPrimaryKey: false;
|
|
930
|
+
isAutoincrement: false;
|
|
931
|
+
hasRuntimeDefault: false;
|
|
932
|
+
enumValues: [string, ...string[]];
|
|
933
|
+
baseColumn: never;
|
|
934
|
+
identity: undefined;
|
|
935
|
+
generated: undefined;
|
|
936
|
+
}, {}, {
|
|
937
|
+
length: number | undefined;
|
|
938
|
+
}>;
|
|
939
|
+
status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
940
|
+
name: "status";
|
|
941
|
+
tableName: "decompose_batches";
|
|
942
|
+
dataType: "string";
|
|
943
|
+
columnType: "SQLiteText";
|
|
944
|
+
data: string;
|
|
945
|
+
driverParam: string;
|
|
946
|
+
notNull: true;
|
|
947
|
+
hasDefault: false;
|
|
948
|
+
isPrimaryKey: false;
|
|
949
|
+
isAutoincrement: false;
|
|
950
|
+
hasRuntimeDefault: false;
|
|
951
|
+
enumValues: [string, ...string[]];
|
|
952
|
+
baseColumn: never;
|
|
953
|
+
identity: undefined;
|
|
954
|
+
generated: undefined;
|
|
955
|
+
}, {}, {
|
|
956
|
+
length: number | undefined;
|
|
957
|
+
}>;
|
|
958
|
+
result: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
959
|
+
name: "result";
|
|
960
|
+
tableName: "decompose_batches";
|
|
961
|
+
dataType: "string";
|
|
962
|
+
columnType: "SQLiteText";
|
|
963
|
+
data: string;
|
|
964
|
+
driverParam: string;
|
|
965
|
+
notNull: false;
|
|
966
|
+
hasDefault: false;
|
|
967
|
+
isPrimaryKey: false;
|
|
968
|
+
isAutoincrement: false;
|
|
969
|
+
hasRuntimeDefault: false;
|
|
970
|
+
enumValues: [string, ...string[]];
|
|
971
|
+
baseColumn: never;
|
|
972
|
+
identity: undefined;
|
|
973
|
+
generated: undefined;
|
|
974
|
+
}, {}, {
|
|
975
|
+
length: number | undefined;
|
|
976
|
+
}>;
|
|
977
|
+
attempts: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
978
|
+
name: "attempts";
|
|
979
|
+
tableName: "decompose_batches";
|
|
980
|
+
dataType: "number";
|
|
981
|
+
columnType: "SQLiteInteger";
|
|
982
|
+
data: number;
|
|
983
|
+
driverParam: number;
|
|
984
|
+
notNull: true;
|
|
985
|
+
hasDefault: true;
|
|
986
|
+
isPrimaryKey: false;
|
|
987
|
+
isAutoincrement: false;
|
|
988
|
+
hasRuntimeDefault: false;
|
|
989
|
+
enumValues: undefined;
|
|
990
|
+
baseColumn: never;
|
|
991
|
+
identity: undefined;
|
|
992
|
+
generated: undefined;
|
|
993
|
+
}, {}, {}>;
|
|
994
|
+
error: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
995
|
+
name: "error";
|
|
996
|
+
tableName: "decompose_batches";
|
|
997
|
+
dataType: "string";
|
|
998
|
+
columnType: "SQLiteText";
|
|
999
|
+
data: string;
|
|
1000
|
+
driverParam: string;
|
|
1001
|
+
notNull: false;
|
|
1002
|
+
hasDefault: false;
|
|
1003
|
+
isPrimaryKey: false;
|
|
1004
|
+
isAutoincrement: false;
|
|
1005
|
+
hasRuntimeDefault: false;
|
|
1006
|
+
enumValues: [string, ...string[]];
|
|
1007
|
+
baseColumn: never;
|
|
1008
|
+
identity: undefined;
|
|
1009
|
+
generated: undefined;
|
|
1010
|
+
}, {}, {
|
|
1011
|
+
length: number | undefined;
|
|
1012
|
+
}>;
|
|
1013
|
+
updated_at: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
1014
|
+
name: "updated_at";
|
|
1015
|
+
tableName: "decompose_batches";
|
|
1016
|
+
dataType: "string";
|
|
1017
|
+
columnType: "SQLiteText";
|
|
1018
|
+
data: string;
|
|
1019
|
+
driverParam: string;
|
|
1020
|
+
notNull: true;
|
|
1021
|
+
hasDefault: false;
|
|
1022
|
+
isPrimaryKey: false;
|
|
1023
|
+
isAutoincrement: false;
|
|
1024
|
+
hasRuntimeDefault: false;
|
|
1025
|
+
enumValues: [string, ...string[]];
|
|
1026
|
+
baseColumn: never;
|
|
1027
|
+
identity: undefined;
|
|
1028
|
+
generated: undefined;
|
|
1029
|
+
}, {}, {
|
|
1030
|
+
length: number | undefined;
|
|
1031
|
+
}>;
|
|
1032
|
+
};
|
|
1033
|
+
dialect: "sqlite";
|
|
1034
|
+
}>;
|
|
1035
|
+
/**
|
|
1036
|
+
* 全部业务表 + 索引的建表 SQL(幂等:CREATE TABLE/INDEX IF NOT EXISTS)——建表执行的事实来源。
|
|
682
1037
|
* 与上方 sqliteTable 定义必须同步(schema.test.ts 对齐断言覆盖)。
|
|
683
1038
|
*/
|
|
684
|
-
export declare const CREATE_TABLES_SQL = "\n-- entities\uFF1A\u5B9E\u4F53\u8868\uFF08\u4EBA\u7269/\u8BBE\u5B9A/\u5730\u70B9/\u4F0F\u7B14/\u65F6\u95F4\u8F74\u4E8B\u4EF6/\u65F6\u95F4\u6807\u7B7E\u70B9\uFF09\nCREATE TABLE IF NOT EXISTS entities (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL CHECK(type IN ('character', 'setting', 'location', 'hook', 'event', 'timepoint', 'reference')),\n name TEXT NOT NULL,\n data TEXT NOT NULL DEFAULT '{}', -- JSON: \u5404\u7C7B\u578B\u7684\u4E13\u5C5E\u5B57\u6BB5\n sort_order INTEGER, -- \u65F6\u95F4\u8F74\u7EBF\u6027\u5E8F\uFF08G2 \u4FEE\u8BA2\uFF09\uFF1Aevent \u4E0E timepoint \u5404\u7C7B\u578B\u5185\u7EBF\u6027\uFF08\u5404\u81EA 0..n-1\uFF09\uFF0C\u5176\u4F59\u7C7B\u578B\u6052\u4E3A NULL\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF09\n deleted_at TEXT -- \u8F6F\u5220\u6807\u8BB0\uFF0CNULL \u8868\u793A\u672A\u5220\u9664\uFF1B\u975E NULL \u65F6\u8BE5\u5B9E\u4F53\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u672C\u4F53\u4FDD\u7559\u53EF\u8FD8\u539F\n);\n\n-- relation_records\uFF1A\u901A\u7528\u5173\u7CFB\u8868\nCREATE TABLE IF NOT EXISTS relation_records (\n id TEXT PRIMARY KEY,\n source_type TEXT NOT NULL, -- \u7AEF\u70B9\u7C7B\u578B\uFF1A\u5B9E\u4F53 'character'|'setting'|'location'|'hook'|'event'\uFF0C\u5927\u7EB2\u8282\u70B9 'outline_node'\n source_id TEXT NOT NULL,\n target_type TEXT NOT NULL,\n target_id TEXT NOT NULL,\n relation_type TEXT NOT NULL,\n metadata TEXT, -- JSON \u6269\u5C55\u5143\u6570\u636E\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF1B\u8F6F\u5220/\u8FD8\u539F\u4EA6\u66F4\u65B0\uFF09\n deleted_at TEXT -- \u7EA7\u8054\u8F6F\u5220\u6807\u8BB0\uFF1A\u4EC5\u5B9E\u4F53/\u8282\u70B9\u7EA7\u8054\u5220\u9664\u65F6\u5199\u5165\uFF1B\n -- \u624B\u52A8\u5220\u9664\u5173\u7CFB = \u7269\u7406\u5220\uFF08\u4E0D\u7F6E deleted_at\uFF0C\u4E0D\u8FDB\u5165\u56DE\u6536\u7AD9\uFF09\n);\n\n-- \u7D22\u5F15\uFF08\u8865\uFF09\uFF1Ak \u8DF3\u904D\u5386\u4E0E\u9AD8\u9891\u5173\u7CFB\u67E5\u8BE2\uFF08\u90E8\u5206\u7D22\u5F15\uFF0C\u4EC5\u8986\u76D6\u672A\u8F6F\u5220\u884C\uFF09\nCREATE INDEX IF NOT EXISTS idx_relation_source ON relation_records(source_id) WHERE deleted_at IS NULL;\nCREATE INDEX IF NOT EXISTS idx_relation_target ON relation_records(target_id) WHERE deleted_at IS NULL;\nCREATE INDEX IF NOT EXISTS idx_relation_type ON relation_records(relation_type) WHERE deleted_at IS NULL;\n\n-- delta_records\uFF1A\u5C5E\u6027\u53D8\u66F4\u8868\nCREATE TABLE IF NOT EXISTS delta_records (\n id TEXT PRIMARY KEY,\n node_id TEXT NOT NULL, -- \u89E6\u53D1\u53D8\u66F4\u7684\u5927\u7EB2\u8282\u70B9\n target_type TEXT NOT NULL,\n target_id TEXT NOT NULL,\n changes TEXT NOT NULL, -- JSON: [{field, op, from?, to?, value?}]\n description TEXT NOT NULL, -- \u4EBA\u7C7B\u53EF\u8BFB\u63CF\u8FF0\n \"order\" INTEGER NOT NULL DEFAULT 0, -- \u540C\u4E00\u8282\u70B9\u5185\u591A\u4E2A Delta \u7684\u6392\u5E8F\uFF08\u5168\u5C40\u5355\u8C03\u9012\u589E\uFF0C\u670D\u52A1\u7AEF\u751F\u6210\uFF09\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF09\n deleted_at TEXT -- \u7EA7\u8054\u8F6F\u5220\u6807\u8BB0\uFF1A\u4EC5\u5B9E\u4F53/\u8282\u70B9\u7EA7\u8054\u5220\u9664\u65F6\u5199\u5165\u3002\n -- \u53EF\u89C1\u6027\u8054\u52A8\u89E6\u53D1\u8282\u70B9\u4E0E\u76EE\u6807\u5B9E\u4F53\uFF1A\u4EFB\u4E00\u7AEF\u8F6F\u5220\u5373\u4E0D\u53EF\u89C1\n);\n\n-- document_records\uFF1A\u5757\u6587\u6863\u8868\uFF08\u7AE0\u6B63\u6587 / \u53C2\u8003\u8D44\u6599\u6B63\u6587\uFF0C2026-09\uFF09\nCREATE TABLE IF NOT EXISTS document_records (\n owner_kind TEXT NOT NULL, -- 'chapter' | 'reference'\uFF08\u679A\u4E3E\u503C\u5C11\u4E14\u7A33\u5B9A\uFF0C\u4E0D\u52A0 CHECK\uFF09\n owner_id TEXT NOT NULL, -- 'ch-*'\uFF08\u7AE0\u8282\u70B9 id\uFF09| 'ref-*'\uFF08\u53C2\u8003\u8D44\u6599\u5B9E\u4F53 id\uFF09\n content TEXT NOT NULL, -- \u5757\u6570\u7EC4 JSON \u5B57\u7B26\u4E32\uFF08\u771F\u76F8\uFF1B\u670D\u52A1\u7AEF\u8BFB\u8DEF\u5F84\u4E0D\u89E3\u6790\uFF09\n content_text TEXT NOT NULL, -- \u670D\u52A1\u7AEF\u6D3E\u751F\u7684\u8F7B\u91CF md \u6295\u5F71\uFF08AI \u8BFB\u53D6/\u5217\u8868\u6458\u8981/\u641C\u7D22/\u5B57\u6570\uFF09\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u7248\u672C\u6233\uFF1A\u591A\u6807\u7B7E\u9875\u9632\u8986\u76D6\uFF09\n PRIMARY KEY (owner_kind, owner_id) -- \u4E00 owner \u4E00\u884C\uFF08upsert \u8986\u76D6\uFF0C\u884C\u968F owner \u751F\u547D\u5468\u671F\uFF09\n);\n";
|
|
1039
|
+
export declare const CREATE_TABLES_SQL = "\n-- entities\uFF1A\u5B9E\u4F53\u8868\uFF08\u4EBA\u7269/\u8BBE\u5B9A/\u5730\u70B9/\u4F0F\u7B14/\u65F6\u95F4\u8F74\u4E8B\u4EF6/\u65F6\u95F4\u6807\u7B7E\u70B9\uFF09\nCREATE TABLE IF NOT EXISTS entities (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL CHECK(type IN ('character', 'setting', 'location', 'hook', 'event', 'timepoint', 'reference')),\n name TEXT NOT NULL,\n data TEXT NOT NULL DEFAULT '{}', -- JSON: \u5404\u7C7B\u578B\u7684\u4E13\u5C5E\u5B57\u6BB5\n sort_order INTEGER, -- \u65F6\u95F4\u8F74\u7EBF\u6027\u5E8F\uFF08G2 \u4FEE\u8BA2\uFF09\uFF1Aevent \u4E0E timepoint \u5404\u7C7B\u578B\u5185\u7EBF\u6027\uFF08\u5404\u81EA 0..n-1\uFF09\uFF0C\u5176\u4F59\u7C7B\u578B\u6052\u4E3A NULL\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF09\n deleted_at TEXT -- \u8F6F\u5220\u6807\u8BB0\uFF0CNULL \u8868\u793A\u672A\u5220\u9664\uFF1B\u975E NULL \u65F6\u8BE5\u5B9E\u4F53\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u672C\u4F53\u4FDD\u7559\u53EF\u8FD8\u539F\n);\n\n-- relation_records\uFF1A\u901A\u7528\u5173\u7CFB\u8868\nCREATE TABLE IF NOT EXISTS relation_records (\n id TEXT PRIMARY KEY,\n source_type TEXT NOT NULL, -- \u7AEF\u70B9\u7C7B\u578B\uFF1A\u5B9E\u4F53 'character'|'setting'|'location'|'hook'|'event'\uFF0C\u5927\u7EB2\u8282\u70B9 'outline_node'\n source_id TEXT NOT NULL,\n target_type TEXT NOT NULL,\n target_id TEXT NOT NULL,\n relation_type TEXT NOT NULL,\n metadata TEXT, -- JSON \u6269\u5C55\u5143\u6570\u636E\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF1B\u8F6F\u5220/\u8FD8\u539F\u4EA6\u66F4\u65B0\uFF09\n deleted_at TEXT -- \u7EA7\u8054\u8F6F\u5220\u6807\u8BB0\uFF1A\u4EC5\u5B9E\u4F53/\u8282\u70B9\u7EA7\u8054\u5220\u9664\u65F6\u5199\u5165\uFF1B\n -- \u624B\u52A8\u5220\u9664\u5173\u7CFB = \u7269\u7406\u5220\uFF08\u4E0D\u7F6E deleted_at\uFF0C\u4E0D\u8FDB\u5165\u56DE\u6536\u7AD9\uFF09\n);\n\n-- \u7D22\u5F15\uFF08\u8865\uFF09\uFF1Ak \u8DF3\u904D\u5386\u4E0E\u9AD8\u9891\u5173\u7CFB\u67E5\u8BE2\uFF08\u90E8\u5206\u7D22\u5F15\uFF0C\u4EC5\u8986\u76D6\u672A\u8F6F\u5220\u884C\uFF09\nCREATE INDEX IF NOT EXISTS idx_relation_source ON relation_records(source_id) WHERE deleted_at IS NULL;\nCREATE INDEX IF NOT EXISTS idx_relation_target ON relation_records(target_id) WHERE deleted_at IS NULL;\nCREATE INDEX IF NOT EXISTS idx_relation_type ON relation_records(relation_type) WHERE deleted_at IS NULL;\n\n-- delta_records\uFF1A\u5C5E\u6027\u53D8\u66F4\u8868\nCREATE TABLE IF NOT EXISTS delta_records (\n id TEXT PRIMARY KEY,\n node_id TEXT NOT NULL, -- \u89E6\u53D1\u53D8\u66F4\u7684\u5927\u7EB2\u8282\u70B9\n target_type TEXT NOT NULL,\n target_id TEXT NOT NULL,\n changes TEXT NOT NULL, -- JSON: [{field, op, from?, to?, value?}]\n description TEXT NOT NULL, -- \u4EBA\u7C7B\u53EF\u8BFB\u63CF\u8FF0\n \"order\" INTEGER NOT NULL DEFAULT 0, -- \u540C\u4E00\u8282\u70B9\u5185\u591A\u4E2A Delta \u7684\u6392\u5E8F\uFF08\u5168\u5C40\u5355\u8C03\u9012\u589E\uFF0C\u670D\u52A1\u7AEF\u751F\u6210\uFF09\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u63D0\u6848\u5FEB\u7167\u6BD4\u5BF9\uFF09\n deleted_at TEXT -- \u7EA7\u8054\u8F6F\u5220\u6807\u8BB0\uFF1A\u4EC5\u5B9E\u4F53/\u8282\u70B9\u7EA7\u8054\u5220\u9664\u65F6\u5199\u5165\u3002\n -- \u53EF\u89C1\u6027\u8054\u52A8\u89E6\u53D1\u8282\u70B9\u4E0E\u76EE\u6807\u5B9E\u4F53\uFF1A\u4EFB\u4E00\u7AEF\u8F6F\u5220\u5373\u4E0D\u53EF\u89C1\n);\n\n-- document_records\uFF1A\u5757\u6587\u6863\u8868\uFF08\u7AE0\u6B63\u6587 / \u53C2\u8003\u8D44\u6599\u6B63\u6587\uFF0C2026-09\uFF09\nCREATE TABLE IF NOT EXISTS document_records (\n owner_kind TEXT NOT NULL, -- 'chapter' | 'reference'\uFF08\u679A\u4E3E\u503C\u5C11\u4E14\u7A33\u5B9A\uFF0C\u4E0D\u52A0 CHECK\uFF09\n owner_id TEXT NOT NULL, -- 'ch-*'\uFF08\u7AE0\u8282\u70B9 id\uFF09| 'ref-*'\uFF08\u53C2\u8003\u8D44\u6599\u5B9E\u4F53 id\uFF09\n content TEXT NOT NULL, -- \u5757\u6570\u7EC4 JSON \u5B57\u7B26\u4E32\uFF08\u771F\u76F8\uFF1B\u670D\u52A1\u7AEF\u8BFB\u8DEF\u5F84\u4E0D\u89E3\u6790\uFF09\n content_text TEXT NOT NULL, -- \u670D\u52A1\u7AEF\u6D3E\u751F\u7684\u8F7B\u91CF md \u6295\u5F71\uFF08AI \u8BFB\u53D6/\u5217\u8868\u6458\u8981/\u641C\u7D22/\u5B57\u6570\uFF09\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\uFF08\u7248\u672C\u6233\uFF1A\u591A\u6807\u7B7E\u9875\u9632\u8986\u76D6\uFF09\n PRIMARY KEY (owner_kind, owner_id) -- \u4E00 owner \u4E00\u884C\uFF08upsert \u8986\u76D6\uFF0C\u884C\u968F owner \u751F\u547D\u5468\u671F\uFF09\n);\n\n-- decompose_jobs\uFF1A\u62C6\u89E3\u5C0F\u8BF4 job\uFF08\u4E00\u9879\u76EE\u4E00 job\uFF0C2026-09\uFF09\nCREATE TABLE IF NOT EXISTS decompose_jobs (\n id TEXT PRIMARY KEY, -- 'job-*'\n status TEXT NOT NULL, -- pending | running | paused | done | failed\uFF08\u679A\u4E3E\u503C\u5C11\u4E14\u7A33\u5B9A\uFF0C\u4E0D\u52A0 CHECK\uFF09\n scope_start INTEGER NOT NULL, -- \u5206\u6790\u8303\u56F4\u8D77\u59CB\u7AE0\u5E8F\uFF081-based\uFF0C\u6587\u4EF6\u4F4D\u7F6E\u5E8F\uFF09\n scope_end INTEGER NOT NULL,\n batch_target_chars INTEGER NOT NULL, -- \u7EC4\u6279\u76EE\u6807\u5B57\u6570\u5FEB\u7167\uFF08\u7EED\u62C6/\u91CD\u8DD1\u6309\u540C\u4E00\u53E3\u5F84\u91CD\u7B97\u6279\u6B21\uFF09\n model TEXT, -- \u672C\u6B21\u4F7F\u7528\u7684\u6A21\u578B\uFF08provider/id\uFF09\uFF0C\u5BA1\u8BA1\u7528\n merge_written TEXT, -- JSON: \u4E0A\u6B21\u5F52\u5E76\u5199\u5165\u6E05\u5355\uFF08\u5E42\u7B49/\u91CD\u8DD1\u4E09\u8DEF\u6BD4\u5BF9\uFF09\n error TEXT, -- job \u7EA7\u5931\u8D25\u6458\u8981\n created_at TEXT NOT NULL, -- ISO 8601\uFF0C\u5E94\u7528\u5C42\u5199\u5165\n updated_at TEXT NOT NULL\n);\n\n-- decompose_batches\uFF1A\u6279\u89C4\u5212\u4E0E\u6279\u7ED3\u679C\u6682\u5B58\uFF08S2 \u4E2D\u95F4\u4EA7\u7269\uFF1B\u65E0\u5916\u952E\uFF0C\u6279\u884C\u7531 helper \u8FDE\u5E26\u5220\uFF09\nCREATE TABLE IF NOT EXISTS decompose_batches (\n job_id TEXT NOT NULL, -- \u2192 decompose_jobs.id\n seq INTEGER NOT NULL, -- 1-based \u6279\u5E8F\u53F7\uFF08\u6587\u4EF6\u4F4D\u7F6E\u5E8F\uFF09\n chapter_ids TEXT NOT NULL, -- JSON: \u672C\u6279\u8986\u76D6\u7684\u7AE0\u8282\u70B9 id \u5217\u8868\uFF08\u987A\u5E8F = \u6587\u4EF6\u5E8F\uFF09\n status TEXT NOT NULL, -- pending | running | done | failed\n result TEXT, -- JSON: \u8BE5\u6279\u62BD\u53D6\u7ED3\u679C\uFF08\u9010\u7AE0\u5BF9\u9F50\uFF1B\u672A\u5B8C\u6210 = NULL\uFF09\n attempts INTEGER NOT NULL DEFAULT 0,-- \u5DF2\u5C1D\u8BD5\u6B21\u6570\uFF08\u91CD\u8BD5\u4E0A\u9650\u89C1\u8BBE\u8BA1\u6587\u6863\uFF09\n error TEXT, -- \u8BE5\u6279\u5931\u8D25\u6458\u8981\n updated_at TEXT NOT NULL,\n PRIMARY KEY (job_id, seq)\n);\n";
|
|
685
1040
|
//# sourceMappingURL=tables.d.ts.map
|
package/dist/tables.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"AAiBA,iDAAiD;AACjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBpB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoB3B,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcxB,CAAC;AAEF,mEAAmE;AAEnE;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"AAiBA,iDAAiD;AACjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBpB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoB3B,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcxB,CAAC;AAEF,mEAAmE;AAEnE;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,y8OAqF7B,CAAC"}
|
package/dist/tables.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// 由 schema.test.ts「DDL 与定义对齐」断言锁住(列名/类型/notNull/主键机械比对)。
|
|
6
6
|
//
|
|
7
7
|
// 边界:
|
|
8
|
-
// - JSON 列(data/changes/metadata)一律 **text
|
|
9
|
-
// drizzle 的 json mode 对坏 JSON 直接 JSON.parse
|
|
10
|
-
//
|
|
8
|
+
// - JSON 列(data/changes/metadata 与拆解三列 chapter_ids/result/merge_written)一律 **text 模式**,
|
|
9
|
+
// 不用 drizzle `mode:'json'`——drizzle 的 json mode 对坏 JSON 直接 JSON.parse 抛错,
|
|
10
|
+
// 会打挂整表查询;防御在 queries 的行映射层(entity.ts parseDataColumn / decompose.ts parse*)。
|
|
11
11
|
// - 对话历史**不在库内**(项目目录 `sessions/*.jsonl`,见 sessions.ts / docs/db/schema.md)。
|
|
12
12
|
// - 标识符由 drizzle escapeName 双引号包裹输出(`"order"` 关键字列安全,无需特殊转义)。
|
|
13
13
|
// - CHECK 约束与部分索引两处都声明(drizzle 侧供对齐核对;真实建表以 DDL 常量为准)。
|
|
@@ -74,7 +74,38 @@ export const documentRecords = sqliteTable("document_records", {
|
|
|
74
74
|
updated_at: text("updated_at").notNull(), // 版本戳:多标签页防覆盖(base_updated_at 比对)
|
|
75
75
|
}, (t) => [primaryKey({ columns: [t.owner_kind, t.owner_id] })]);
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* decompose_jobs:拆解小说 job(导入式批量管线,设计见 docs/design/60-decompose.md)。
|
|
78
|
+
* 一项目一 job(业务层保证,不设唯一约束):状态机 pending → running → (paused | done | failed),
|
|
79
|
+
* 范围与组批口径是 S1 的快照(续拆/重跑按同一口径重算批次);无 deleted_at——撤销 = 删书或恢复备份。
|
|
80
|
+
*/
|
|
81
|
+
export const decomposeJobs = sqliteTable("decompose_jobs", {
|
|
82
|
+
id: text("id").primaryKey(), // 'job-*'
|
|
83
|
+
status: text("status").notNull(), // pending | running | paused | done | failed(枚举值少且稳定,不加 CHECK)
|
|
84
|
+
scope_start: integer("scope_start").notNull(), // 分析范围起始章序(1-based,文件位置序)
|
|
85
|
+
scope_end: integer("scope_end").notNull(),
|
|
86
|
+
batch_target_chars: integer("batch_target_chars").notNull(), // 组批目标字数快照
|
|
87
|
+
model: text("model"), // 本次使用的模型(provider/id),审计用
|
|
88
|
+
merge_written: text("merge_written"), // JSON: 上次归并写入清单(幂等/重跑三路比对;text 模式)
|
|
89
|
+
error: text("error"), // job 级失败摘要
|
|
90
|
+
created_at: text("created_at").notNull(),
|
|
91
|
+
updated_at: text("updated_at").notNull(),
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* decompose_batches:批规划与批结果暂存(S2 的中间产物,不是待确认草稿)。
|
|
95
|
+
* 批结果只落 `result`(业务数据由 S3 写);无外键——job 行删除时批行由 helper 连带删。
|
|
96
|
+
*/
|
|
97
|
+
export const decomposeBatches = sqliteTable("decompose_batches", {
|
|
98
|
+
job_id: text("job_id").notNull(), // → decompose_jobs.id
|
|
99
|
+
seq: integer("seq").notNull(), // 1-based 批序号(文件位置序)
|
|
100
|
+
chapter_ids: text("chapter_ids").notNull(), // JSON: 本批覆盖的章节点 id 列表(顺序 = 文件序;text 模式)
|
|
101
|
+
status: text("status").notNull(), // pending | running | done | failed
|
|
102
|
+
result: text("result"), // JSON: 该批抽取结果(逐章对齐;未完成 = NULL;text 模式)
|
|
103
|
+
attempts: integer("attempts").notNull().default(0), // 已尝试次数(重试上限见设计文档)
|
|
104
|
+
error: text("error"), // 该批失败摘要
|
|
105
|
+
updated_at: text("updated_at").notNull(),
|
|
106
|
+
}, (t) => [primaryKey({ columns: [t.job_id, t.seq] })]);
|
|
107
|
+
/**
|
|
108
|
+
* 全部业务表 + 索引的建表 SQL(幂等:CREATE TABLE/INDEX IF NOT EXISTS)——建表执行的事实来源。
|
|
78
109
|
* 与上方 sqliteTable 定义必须同步(schema.test.ts 对齐断言覆盖)。
|
|
79
110
|
*/
|
|
80
111
|
export const CREATE_TABLES_SQL = `
|
|
@@ -135,5 +166,32 @@ CREATE TABLE IF NOT EXISTS document_records (
|
|
|
135
166
|
updated_at TEXT NOT NULL, -- ISO 8601,应用层写入(版本戳:多标签页防覆盖)
|
|
136
167
|
PRIMARY KEY (owner_kind, owner_id) -- 一 owner 一行(upsert 覆盖,行随 owner 生命周期)
|
|
137
168
|
);
|
|
169
|
+
|
|
170
|
+
-- decompose_jobs:拆解小说 job(一项目一 job,2026-09)
|
|
171
|
+
CREATE TABLE IF NOT EXISTS decompose_jobs (
|
|
172
|
+
id TEXT PRIMARY KEY, -- 'job-*'
|
|
173
|
+
status TEXT NOT NULL, -- pending | running | paused | done | failed(枚举值少且稳定,不加 CHECK)
|
|
174
|
+
scope_start INTEGER NOT NULL, -- 分析范围起始章序(1-based,文件位置序)
|
|
175
|
+
scope_end INTEGER NOT NULL,
|
|
176
|
+
batch_target_chars INTEGER NOT NULL, -- 组批目标字数快照(续拆/重跑按同一口径重算批次)
|
|
177
|
+
model TEXT, -- 本次使用的模型(provider/id),审计用
|
|
178
|
+
merge_written TEXT, -- JSON: 上次归并写入清单(幂等/重跑三路比对)
|
|
179
|
+
error TEXT, -- job 级失败摘要
|
|
180
|
+
created_at TEXT NOT NULL, -- ISO 8601,应用层写入
|
|
181
|
+
updated_at TEXT NOT NULL
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
-- decompose_batches:批规划与批结果暂存(S2 中间产物;无外键,批行由 helper 连带删)
|
|
185
|
+
CREATE TABLE IF NOT EXISTS decompose_batches (
|
|
186
|
+
job_id TEXT NOT NULL, -- → decompose_jobs.id
|
|
187
|
+
seq INTEGER NOT NULL, -- 1-based 批序号(文件位置序)
|
|
188
|
+
chapter_ids TEXT NOT NULL, -- JSON: 本批覆盖的章节点 id 列表(顺序 = 文件序)
|
|
189
|
+
status TEXT NOT NULL, -- pending | running | done | failed
|
|
190
|
+
result TEXT, -- JSON: 该批抽取结果(逐章对齐;未完成 = NULL)
|
|
191
|
+
attempts INTEGER NOT NULL DEFAULT 0,-- 已尝试次数(重试上限见设计文档)
|
|
192
|
+
error TEXT, -- 该批失败摘要
|
|
193
|
+
updated_at TEXT NOT NULL,
|
|
194
|
+
PRIMARY KEY (job_id, seq)
|
|
195
|
+
);
|
|
138
196
|
`;
|
|
139
197
|
//# sourceMappingURL=tables.js.map
|
package/dist/tables.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,iEAAiE;AACjE,oEAAoE;AACpE,yDAAyD;AACzD,EAAE;AACF,MAAM;AACN,
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whispering233/ai-editor-db",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "数据库层:better-sqlite3 连接 / 建表 / 查询",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"postpack": "node ../../scripts/restore-package-json.mjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@whispering233/ai-editor-shared": "0.0.
|
|
29
|
+
"@whispering233/ai-editor-shared": "0.0.53",
|
|
30
30
|
"better-sqlite3": "^13.0.0",
|
|
31
31
|
"drizzle-orm": "0.45.2"
|
|
32
32
|
},
|