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.
- package/CHANGELOG.md +3 -3
- package/README.md +4 -0
- package/dist/index.js +11335 -0
- package/package.json +9 -5
- package/src/domain/check.ts +0 -193
- package/src/domain/errors.ts +0 -59
- package/src/domain/evidence.ts +0 -134
- package/src/domain/ids.ts +0 -31
- package/src/host/chat-runtime.ts +0 -489
- package/src/host/dsh-adapter.ts +0 -867
- package/src/host/session-adapter.ts +0 -276
- package/src/http/handler.ts +0 -1132
- package/src/index.js +0 -53
- package/src/service/audit.ts +0 -92
- package/src/service/chat.ts +0 -1100
- package/src/service/contracts.ts +0 -193
- package/src/service/defaults.ts +0 -182
- package/src/service/deliverables.ts +0 -240
- package/src/service/hams.ts +0 -3103
- package/src/service/knowledge.ts +0 -940
- package/src/service/member-config.ts +0 -39
- package/src/service/members.ts +0 -506
- package/src/service/memory.ts +0 -375
- package/src/service/permissions.ts +0 -118
- package/src/service/project-lifecycle.ts +0 -233
- package/src/service/projects.ts +0 -840
- package/src/service/receipts.ts +0 -63
- package/src/service/templates.ts +0 -140
- package/src/service/tick.ts +0 -751
- package/src/service/tools.ts +0 -711
- package/src/service/types.ts +0 -219
- package/src/service/work-item-create.ts +0 -159
- package/src/service/workspace-profile.ts +0 -443
- package/src/store/backup.ts +0 -239
- package/src/store/bootstrap.ts +0 -225
- package/src/store/db.ts +0 -179
- package/src/store/lock.ts +0 -194
- package/src/store/migrations.ts +0 -211
- package/src/store/schema/001_p1.sql +0 -846
- package/src/store/schema/001_p1.sql.ts +0 -865
- package/src/store/schema/002_knowledge.sql +0 -54
- package/src/store/schema/002_knowledge.sql.ts +0 -68
- package/src/store/schema/003_projects.sql.ts +0 -3
- package/src/store/schema/004_team.sql.ts +0 -50
- package/src/store/schema/005_target_check.sql.ts +0 -22
- package/src/store/schema/006_target_flow.sql.ts +0 -19
- package/src/store/schema/007_project_delete.sql.ts +0 -17
- package/src/store/schema/008_memory.sql.ts +0 -47
- package/src/store/schema/generate-projects.mjs +0 -16
- package/src/store/seed.ts +0 -114
package/src/store/migrations.ts
DELETED
|
@@ -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
|
-
}
|