|
7 | 7 | import type Database from 'better-sqlite3'; |
8 | 8 | import { logger } from '../logger.js'; |
9 | 9 |
|
10 | | -export const SCHEMA_VERSION = 8; |
| 10 | +export const SCHEMA_VERSION = 10; |
11 | 11 |
|
12 | 12 | export const SCHEMA_DDL = /* sql */ ` |
13 | 13 | CREATE TABLE IF NOT EXISTS pomodoro_sessions ( |
@@ -204,6 +204,82 @@ CREATE TABLE IF NOT EXISTS imports ( |
204 | 204 | settled_at TEXT NOT NULL |
205 | 205 | ); |
206 | 206 | CREATE INDEX IF NOT EXISTS idx_imports_settled_at ON imports(settled_at); |
| 207 | +-- v9:SOP 标准作业流程模板/步骤/执行记录 + 统一收件箱(Wave 0 地基) |
| 208 | +CREATE TABLE IF NOT EXISTS sop_templates ( |
| 209 | + id TEXT PRIMARY KEY, |
| 210 | + name TEXT NOT NULL, |
| 211 | + description TEXT NOT NULL DEFAULT '', |
| 212 | + icon TEXT NOT NULL DEFAULT '', |
| 213 | + category TEXT NOT NULL DEFAULT '', |
| 214 | + source TEXT NOT NULL DEFAULT 'user' CHECK (source IN ('builtin','user')), |
| 215 | + created_at TEXT NOT NULL, |
| 216 | + updated_at TEXT NOT NULL |
| 217 | +); |
| 218 | +CREATE TABLE IF NOT EXISTS sop_steps ( |
| 219 | + id TEXT PRIMARY KEY, |
| 220 | + template_id TEXT NOT NULL, |
| 221 | + step_type TEXT NOT NULL, |
| 222 | + title TEXT NOT NULL DEFAULT '', |
| 223 | + config TEXT NOT NULL DEFAULT '{}', |
| 224 | + "order" INTEGER NOT NULL DEFAULT 0, |
| 225 | + FOREIGN KEY (template_id) REFERENCES sop_templates(id) ON DELETE CASCADE |
| 226 | +); |
| 227 | +CREATE TABLE IF NOT EXISTS sop_runs ( |
| 228 | + id TEXT PRIMARY KEY, |
| 229 | + template_id TEXT NOT NULL, |
| 230 | + status TEXT NOT NULL DEFAULT 'running' CHECK (status IN ('running','awaiting_module','completed','aborted')), |
| 231 | + current_step_index INTEGER NOT NULL DEFAULT 0, |
| 232 | + step_progress TEXT NOT NULL DEFAULT '{}', |
| 233 | + started_at TEXT NOT NULL, |
| 234 | + finished_at TEXT, |
| 235 | + FOREIGN KEY (template_id) REFERENCES sop_templates(id) ON DELETE CASCADE |
| 236 | +); |
| 237 | +CREATE TABLE IF NOT EXISTS inbox_items ( |
| 238 | + id TEXT PRIMARY KEY, |
| 239 | + source TEXT NOT NULL DEFAULT 'clipboard' CHECK (source IN ('clipboard','inspiration','import')), |
| 240 | + title TEXT NOT NULL DEFAULT '', |
| 241 | + content TEXT NOT NULL DEFAULT '', |
| 242 | + status TEXT NOT NULL DEFAULT 'new' CHECK (status IN ('new','settled','archived')), |
| 243 | + created_at TEXT NOT NULL |
| 244 | +); |
| 245 | +CREATE INDEX IF NOT EXISTS idx_sop_steps_template_order ON sop_steps(template_id,"order"); |
| 246 | +CREATE INDEX IF NOT EXISTS idx_sop_runs_status_started ON sop_runs(status,started_at); |
| 247 | +CREATE INDEX IF NOT EXISTS idx_inbox_items_status_created ON inbox_items(status,created_at DESC); |
| 248 | +-- v10:内测身份/激活码/邀请码表(临时收入方案) |
| 249 | +CREATE TABLE IF NOT EXISTS beta_profile ( |
| 250 | + id TEXT PRIMARY KEY, |
| 251 | + user_id TEXT NOT NULL, |
| 252 | + tier TEXT NOT NULL DEFAULT 'observer', |
| 253 | + cohort INTEGER NOT NULL DEFAULT 1, |
| 254 | + joined_at TEXT NOT NULL, |
| 255 | + lifetime_pro INTEGER NOT NULL DEFAULT 0, |
| 256 | + badges TEXT NOT NULL DEFAULT '[]', |
| 257 | + perks_config TEXT NOT NULL DEFAULT '{}', |
| 258 | + synced_at TEXT |
| 259 | +); |
| 260 | +CREATE TABLE IF NOT EXISTS licenses ( |
| 261 | + id TEXT PRIMARY KEY, |
| 262 | + code TEXT NOT NULL UNIQUE, |
| 263 | + type TEXT NOT NULL, |
| 264 | + tier TEXT NOT NULL, |
| 265 | + status TEXT NOT NULL DEFAULT 'active', |
| 266 | + machine_id TEXT, |
| 267 | + activated_at TEXT, |
| 268 | + expires_at TEXT, |
| 269 | + synced_at TEXT |
| 270 | +); |
| 271 | +CREATE TABLE IF NOT EXISTS invite_codes ( |
| 272 | + id TEXT PRIMARY KEY, |
| 273 | + code TEXT NOT NULL UNIQUE, |
| 274 | + issuer_user_id TEXT NOT NULL, |
| 275 | + status TEXT NOT NULL DEFAULT 'pending', |
| 276 | + used_by_user_id TEXT, |
| 277 | + used_at TEXT, |
| 278 | + created_at TEXT NOT NULL |
| 279 | +); |
| 280 | +CREATE INDEX IF NOT EXISTS idx_beta_profile_user_id ON beta_profile(user_id); |
| 281 | +CREATE INDEX IF NOT EXISTS idx_licenses_code ON licenses(code); |
| 282 | +CREATE INDEX IF NOT EXISTS idx_invite_codes_issuer ON invite_codes(issuer_user_id); |
207 | 283 | `; |
208 | 284 |
|
209 | 285 | /** v3 迁移 DDL:CRDT 同步引擎元数据表(条件执行) */ |
@@ -275,6 +351,9 @@ export function initializeSchema(db: Database.Database): void { |
275 | 351 | } |
276 | 352 | } |
277 | 353 |
|
| 354 | + // v9 迁移:SOP 模板/步骤/执行记录 + 统一收件箱(sop_templates/sop_steps/sop_runs/inbox_items) |
| 355 | + // 表 DDL 已包含在 SCHEMA_DDL 中(CREATE IF NOT EXISTS 幂等),此处无需额外操作 |
| 356 | + |
278 | 357 | db.pragma(`user_version = ${SCHEMA_VERSION}`); |
279 | 358 | } |
280 | 359 |
|
|
0 commit comments