dsh-hams 0.1.3 → 0.1.4

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 (50) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/README.md +4 -0
  3. package/dist/index.js +11335 -0
  4. package/package.json +9 -5
  5. package/src/domain/check.ts +0 -193
  6. package/src/domain/errors.ts +0 -59
  7. package/src/domain/evidence.ts +0 -134
  8. package/src/domain/ids.ts +0 -31
  9. package/src/host/chat-runtime.ts +0 -489
  10. package/src/host/dsh-adapter.ts +0 -867
  11. package/src/host/session-adapter.ts +0 -276
  12. package/src/http/handler.ts +0 -1132
  13. package/src/index.js +0 -53
  14. package/src/service/audit.ts +0 -92
  15. package/src/service/chat.ts +0 -1100
  16. package/src/service/contracts.ts +0 -193
  17. package/src/service/defaults.ts +0 -182
  18. package/src/service/deliverables.ts +0 -240
  19. package/src/service/hams.ts +0 -3103
  20. package/src/service/knowledge.ts +0 -940
  21. package/src/service/member-config.ts +0 -39
  22. package/src/service/members.ts +0 -506
  23. package/src/service/memory.ts +0 -375
  24. package/src/service/permissions.ts +0 -118
  25. package/src/service/project-lifecycle.ts +0 -233
  26. package/src/service/projects.ts +0 -840
  27. package/src/service/receipts.ts +0 -63
  28. package/src/service/templates.ts +0 -140
  29. package/src/service/tick.ts +0 -751
  30. package/src/service/tools.ts +0 -711
  31. package/src/service/types.ts +0 -219
  32. package/src/service/work-item-create.ts +0 -159
  33. package/src/service/workspace-profile.ts +0 -443
  34. package/src/store/backup.ts +0 -239
  35. package/src/store/bootstrap.ts +0 -225
  36. package/src/store/db.ts +0 -179
  37. package/src/store/lock.ts +0 -194
  38. package/src/store/migrations.ts +0 -211
  39. package/src/store/schema/001_p1.sql +0 -846
  40. package/src/store/schema/001_p1.sql.ts +0 -865
  41. package/src/store/schema/002_knowledge.sql +0 -54
  42. package/src/store/schema/002_knowledge.sql.ts +0 -68
  43. package/src/store/schema/003_projects.sql.ts +0 -3
  44. package/src/store/schema/004_team.sql.ts +0 -50
  45. package/src/store/schema/005_target_check.sql.ts +0 -22
  46. package/src/store/schema/006_target_flow.sql.ts +0 -19
  47. package/src/store/schema/007_project_delete.sql.ts +0 -17
  48. package/src/store/schema/008_memory.sql.ts +0 -47
  49. package/src/store/schema/generate-projects.mjs +0 -16
  50. package/src/store/seed.ts +0 -114
@@ -1,211 +0,0 @@
1
- /**
2
- * 迁移框架:`PRAGMA user_version` 做版本号,显式数组做迁移链。
3
- *
4
- * 规则(backend-design §8 / engineering-design §6.4):
5
- * - 每步一个事务,DDL 与 `PRAGMA user_version = N` 同一事务提交,失败整体回滚;
6
- * - `user_version` 高于代码支持上限时拒绝启动,绝不让旧代码碰新库(错误码 SCHEMA_TOO_NEW);
7
- * - 迁移里不许调外部 IO、不许多语句拼业务逻辑,只放 DDL 与必要的基线种子。
8
- *
9
- * v1 的 DDL 由 `scripts/split-schema.mjs` 从 docs/schema-2026-11-14.sql 生成:
10
- * 只取 [P1] 的 41 张表 / 30 索引 / 31 触发器,以及系统主体与 36 条状态转换两条种子。
11
- */
12
- import type { DatabaseSync } from 'node:sqlite'
13
- import { PROJECTS_SCHEMA_SQL, PROJECTS_SCHEMA_META } from './schema/003_projects.sql.ts'
14
- import { TEAM_SCHEMA_SQL, TEAM_SCHEMA_META } from './schema/004_team.sql.ts'
15
- import { TARGET_CHECK_SCHEMA_SQL, TARGET_CHECK_SCHEMA_META } from './schema/005_target_check.sql.ts'
16
- import { TARGET_FLOW_SCHEMA_SQL, TARGET_FLOW_SCHEMA_META } from './schema/006_target_flow.sql.ts'
17
- import { PROJECT_DELETE_SCHEMA_SQL, PROJECT_DELETE_SCHEMA_META } from './schema/007_project_delete.sql.ts'
18
- import { MEMORY_SCHEMA_SQL, MEMORY_SCHEMA_META } from './schema/008_memory.sql.ts'
19
- import { P1_SCHEMA_SQL, P1_SCHEMA_META } from './schema/001_p1.sql.ts'
20
- import { KNOWLEDGE_SCHEMA_SQL, KNOWLEDGE_SCHEMA_META } from './schema/002_knowledge.sql.ts'
21
- import {
22
- listObjects,
23
- setUserVersion,
24
- tableNames,
25
- transaction,
26
- userVersion,
27
- StoreError,
28
- } from './db.ts'
29
-
30
- export interface Migration {
31
- version: number
32
- name: string
33
- sql: string
34
- }
35
-
36
- export const MIGRATIONS: readonly Migration[] = Object.freeze([
37
- { version: 1, name: 'p1-baseline', sql: P1_SCHEMA_SQL },
38
- // v2:知识的四张表(kb_table / kb_doc / kb_skill / kb_skill_version)。
39
- // 从权威 DDL 的 [P2] 知识子集生成,不手抄;界面「知识」屏需要真实落库才能接版本与发布。
40
- { version: 2, name: 'knowledge', sql: KNOWLEDGE_SCHEMA_SQL },
41
- { version: 3, name: 'project-lifecycle', sql: PROJECTS_SCHEMA_SQL },
42
- // v4:项目群团队(参与者 / 合并消息 / 会话游标)+ 临时 bot 的归属列。
43
- { version: 4, name: 'project-team', sql: TEAM_SCHEMA_SQL },
44
- // v5:阶段目标的检验提交记录(项目经理提交结果 + 报告链接)。
45
- { version: 5, name: 'target-check', sql: TARGET_CHECK_SCHEMA_SQL },
46
- // v6:目标详情字段 + 检验提交的审批字段(提交检验走审批,不再直接生成结果)。
47
- { version: 6, name: 'target-flow', sql: TARGET_FLOW_SCHEMA_SQL },
48
- // v7:归档项目的「删除」标记(软删;工作项解绑保留,审计与证据不动)。
49
- { version: 7, name: 'project-delete', sql: PROJECT_DELETE_SCHEMA_SQL },
50
- // v8:项目记忆(自动/手工/工具收集)+ 能力类记忆同步给 bot。
51
- { version: 8, name: 'project-memory', sql: MEMORY_SCHEMA_SQL },
52
- ])
53
-
54
- export const TARGET_VERSION: number = MIGRATIONS[MIGRATIONS.length - 1].version
55
-
56
- export { P1_SCHEMA_META, P1_SCHEMA_SQL, KNOWLEDGE_SCHEMA_META, KNOWLEDGE_SCHEMA_SQL, PROJECTS_SCHEMA_META, PROJECTS_SCHEMA_SQL, TEAM_SCHEMA_META, TEAM_SCHEMA_SQL, TARGET_CHECK_SCHEMA_META, TARGET_CHECK_SCHEMA_SQL, TARGET_FLOW_SCHEMA_META, TARGET_FLOW_SCHEMA_SQL, PROJECT_DELETE_SCHEMA_META, PROJECT_DELETE_SCHEMA_SQL, MEMORY_SCHEMA_META, MEMORY_SCHEMA_SQL }
57
-
58
- export class SchemaTooNewError extends StoreError {
59
- found: number
60
- supported: number
61
-
62
- constructor(found: number, supported: number) {
63
- super(
64
- 'SCHEMA_TOO_NEW',
65
- `数据库版本 ${found} 高于代码支持的上限 ${supported};拒绝启动,避免旧代码改坏新库`,
66
- )
67
- this.found = found
68
- this.supported = supported
69
- }
70
- }
71
-
72
- export class SchemaIncompleteError extends StoreError {
73
- missing: string[]
74
-
75
- constructor(missing: string[]) {
76
- super('SCHEMA_INCOMPLETE', `user_version 已是当前版本,但缺少基线表:${missing.join(', ')}`)
77
- this.missing = missing
78
- }
79
- }
80
-
81
- export interface MigrateOptions {
82
- migrations?: readonly Migration[]
83
- /** 默认 true:迁移链与内置链一致且无待执行项时,校验 P1 基线表是否齐全。 */
84
- verifyBaseline?: boolean
85
- }
86
-
87
- export interface MigrateReport {
88
- fromVersion: number
89
- toVersion: number
90
- applied: { version: number; name: string }[]
91
- migrated: boolean
92
- checkedBaseline: boolean
93
- }
94
-
95
- function tablesUpTo(version: number): string[] {
96
- const tables = [...P1_SCHEMA_META.tableNames]
97
- if (version >= 2) tables.push(...KNOWLEDGE_SCHEMA_META.tableNames)
98
- if (version >= 3) tables.push(...PROJECTS_SCHEMA_META.tableNames)
99
- if (version >= 4) tables.push(...TEAM_SCHEMA_META.tableNames)
100
- if (version >= 5) tables.push(...TARGET_CHECK_SCHEMA_META.tableNames)
101
- if (version >= 6) tables.push(...TARGET_FLOW_SCHEMA_META.tableNames)
102
- return tables
103
- }
104
-
105
- export function validateChain(migrations: readonly Migration[]): void {
106
- if (migrations.length === 0) throw new StoreError('BAD_MIGRATIONS', '迁移链为空')
107
- let expected = 1
108
- for (const migration of migrations) {
109
- if (migration.version !== expected) {
110
- throw new StoreError(
111
- 'BAD_MIGRATIONS',
112
- `迁移链必须从 1 连续递增:期望 ${expected},收到 ${migration.version}(${migration.name})`,
113
- )
114
- }
115
- if (!migration.sql.trim()) throw new StoreError('BAD_MIGRATIONS', `迁移 ${migration.version} 的 SQL 为空`)
116
- expected += 1
117
- }
118
- }
119
-
120
- export function pendingMigrations(
121
- current: number,
122
- migrations: readonly Migration[] = MIGRATIONS,
123
- ): Migration[] {
124
- return migrations.filter((migration) => migration.version > current)
125
- }
126
-
127
- /**
128
- * 在给定连接上把库迁移到链尾版本。调用方负责先拿单写者锁(见 lock.ts / bootstrap.ts)。
129
- * 返回报告;没有待执行项时是幂等 no-op,并做一次基线完整性校验。
130
- */
131
- export function migrate(db: DatabaseSync, options: MigrateOptions = {}): MigrateReport {
132
- const migrations = options.migrations ?? MIGRATIONS
133
- const useBuiltin = migrations === MIGRATIONS
134
- const verifyBaseline = options.verifyBaseline ?? useBuiltin
135
-
136
- validateChain(migrations)
137
- const target = migrations[migrations.length - 1].version
138
- const from = userVersion(db)
139
-
140
- if (from > target) throw new SchemaTooNewError(from, target)
141
-
142
- const pending = pendingMigrations(from, migrations)
143
- const applied: { version: number; name: string }[] = []
144
-
145
- // 已有库先核对「它声称的版本」对应的表是否齐全:user_version 说有 v1、实际表没了,
146
- // 应该报 SCHEMA_INCOMPLETE,而不是硬在空库上继续加列/加表。
147
- if (from >= 1 && verifyBaseline && useBuiltin) {
148
- const expected = tablesUpTo(from)
149
- const present = new Set(tableNames(db))
150
- const missing = expected.filter((name) => !present.has(name))
151
- if (missing.length) throw new SchemaIncompleteError(missing)
152
- }
153
-
154
- for (const migration of pending) {
155
- transaction(db, () => {
156
- db.exec(migration.sql)
157
- setUserVersion(db, migration.version)
158
- // hams_meta 在 v1 才存在;镜像一份便于诊断页只查表不查 pragma。
159
- if (tableNames(db).includes('hams_meta')) {
160
- db.prepare(
161
- `INSERT INTO hams_meta (key, value) VALUES ('schema_version', ?)
162
- ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
163
- ).run(String(migration.version))
164
- }
165
- })
166
- applied.push({ version: migration.version, name: migration.name })
167
- }
168
-
169
- let checkedBaseline = false
170
- if (verifyBaseline && useBuiltin) {
171
- const present = new Set(tableNames(db))
172
- const missing = tablesUpTo(target).filter((name) => !present.has(name))
173
- if (missing.length) throw new SchemaIncompleteError([...missing])
174
- checkedBaseline = true
175
- }
176
-
177
- return {
178
- fromVersion: from,
179
- toVersion: userVersion(db),
180
- applied,
181
- migrated: applied.length > 0,
182
- checkedBaseline,
183
- }
184
- }
185
-
186
- export interface BaselineSummary {
187
- userVersion: number
188
- tables: number
189
- indexes: number
190
- triggers: number
191
- systemMember: boolean
192
- transitions: number
193
- }
194
-
195
- /** 冒烟与测试共用的基线摘要,用于一眼判断「这个库是不是已经按 v1 建好」。 */
196
- export function baselineSummary(db: DatabaseSync): BaselineSummary {
197
- const objects = listObjects(db)
198
- const systemMember =
199
- (db.prepare("SELECT COUNT(*) AS c FROM member WHERE id = 'system' AND kind = 'system'").get() as {
200
- c: number
201
- }).c === 1
202
- const transitions = (db.prepare('SELECT COUNT(*) AS c FROM work_item_transition').get() as { c: number }).c
203
- return {
204
- userVersion: userVersion(db),
205
- tables: objects.filter((object) => object.type === 'table').length,
206
- indexes: objects.filter((object) => object.type === 'index').length,
207
- triggers: objects.filter((object) => object.type === 'trigger').length,
208
- systemMember,
209
- transitions: Number(transitions),
210
- }
211
- }