- app_settings 表(key/value):MCP 开关与令牌存 DB,不属于任何用户、不参与同步协议 - 配置读取/写入收敛到 core/mcp.js(readMcpConfig/saveMcpToken/setMcpEnabled) - 状态语义:未配置→404(端点视为不存在);已配置关闭→503(可重新开启);令牌错→401 - env MCP_AUTH_TOKEN 仅首次种子(库里从没有过令牌时迁入 DB),不设也行;后台改动即时生效无需重启 - 管理 API(登录态):GET /api/mcp/status(掩码)、POST /api/mcp/token(生成/重置,明文仅一次)、GET /api/mcp/token(复制用)、POST /api/mcp/enabled - 设置页新增「AI 接入 (MCP)」卡片:开关 toggle、掩码展示、一键生成并复制(writeClipboard 兜底)、重置令牌;未登录徽章「本设备请先登录」 - 入口接线:node-server.js 与 worker.js 均挂 /mcp(seedToken 透传);sw.js 放行裸 /mcp(v2→v3) - 两个适配器补 getSetting/setSetting(node:sqlite 与 D1 同语义) - 测试:server/test/mcp.test.js 39 项(未配置关闭/鉴权/JSON-RPC 全链路/开关热切换/令牌轮换);npm test 全绿(107+72+39) - 线上 E2E:生产令牌 initialize/tools 7 个/2026-09 大盘(出勤11天/82h/挣得1599);公网 HTTPS 链路通;UI puppeteer 17/17(含关→503→开→200 热切换,全程无重启) - 文档:README + server/README(环境变量表/接口表/数据模型/MCP 章节)
86 lines
3.3 KiB
SQL
86 lines
3.3 KiB
SQL
-- 工时记账服务端 schema
|
||
-- 同时兼容 VPS 上的 node:sqlite 与 Cloudflare D1(都是 SQLite 方言)
|
||
-- 设计要点:
|
||
-- 1. users.rev 是该用户的单调递增版本号,任何写入都 +1,客户端靠它做增量拉取
|
||
-- 2. records / month_adjust 用 deleted 墓碑标记而非物理删除,否则增量同步无法传播「删除」
|
||
-- 3. 所有时间戳统一存 ISO 8601 字符串(UTC),避免 D1 与 SQLite 的时间函数差异
|
||
|
||
CREATE TABLE IF NOT EXISTS users (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
username TEXT NOT NULL UNIQUE,
|
||
pw_hash TEXT NOT NULL,
|
||
pw_salt TEXT NOT NULL,
|
||
pw_iter INTEGER NOT NULL,
|
||
rev INTEGER NOT NULL DEFAULT 0,
|
||
created_at TEXT NOT NULL
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS sessions (
|
||
token_hash TEXT PRIMARY KEY,
|
||
user_id INTEGER NOT NULL,
|
||
created_at TEXT NOT NULL,
|
||
expires_at TEXT NOT NULL
|
||
);
|
||
CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);
|
||
CREATE INDEX IF NOT EXISTS idx_sessions_exp ON sessions(expires_at);
|
||
|
||
-- 每日打卡:主键 (user_id, day),day 形如 2026-09-08
|
||
CREATE TABLE IF NOT EXISTS records (
|
||
user_id INTEGER NOT NULL,
|
||
day TEXT NOT NULL,
|
||
status TEXT,
|
||
shift_type TEXT,
|
||
hours REAL,
|
||
contraband_found INTEGER NOT NULL DEFAULT 0,
|
||
contraband_missed INTEGER NOT NULL DEFAULT 0,
|
||
other_penalty REAL,
|
||
penalty_reason TEXT,
|
||
deleted INTEGER NOT NULL DEFAULT 0,
|
||
rev INTEGER NOT NULL,
|
||
updated_at TEXT NOT NULL,
|
||
PRIMARY KEY (user_id, day)
|
||
);
|
||
CREATE INDEX IF NOT EXISTS idx_records_rev ON records(user_id, rev);
|
||
|
||
-- 月度奖惩终稿:主键 (user_id, month),month 形如 2026-09
|
||
-- status = draft(草稿,不计入金额) | final(组长审核定稿,计入金额)
|
||
CREATE TABLE IF NOT EXISTS month_adjust (
|
||
user_id INTEGER NOT NULL,
|
||
month TEXT NOT NULL,
|
||
status TEXT NOT NULL,
|
||
final_amount REAL,
|
||
note TEXT,
|
||
finalized_at TEXT,
|
||
deleted INTEGER NOT NULL DEFAULT 0,
|
||
rev INTEGER NOT NULL,
|
||
updated_at TEXT NOT NULL,
|
||
PRIMARY KEY (user_id, month)
|
||
);
|
||
CREATE INDEX IF NOT EXISTS idx_adjust_rev ON month_adjust(user_id, rev);
|
||
|
||
-- 设置整体存一份 JSON:字段会随功能迭代增减,拆列反而不好演进
|
||
CREATE TABLE IF NOT EXISTS settings (
|
||
user_id INTEGER PRIMARY KEY,
|
||
json TEXT NOT NULL,
|
||
rev INTEGER NOT NULL,
|
||
updated_at TEXT NOT NULL
|
||
);
|
||
|
||
-- App 级键值:服务自身的运行时配置(当前用于 MCP 接入开关与令牌)。
|
||
-- 刻意与 users/settings 分开:它不属于任何用户,不参与同步协议,
|
||
-- 客户端 push 碰不到它,增量拉取也不会把它带出去。
|
||
CREATE TABLE IF NOT EXISTS app_settings (
|
||
key TEXT PRIMARY KEY,
|
||
value TEXT NOT NULL,
|
||
updated_at TEXT NOT NULL
|
||
);
|
||
|
||
-- App 级键值:服务自身的运行时配置(当前用于 MCP 接入开关与令牌)。
|
||
-- 刻意与 users/settings 分开:它不属于任何用户,不参与同步协议,
|
||
-- 客户端 push 碰不到它,增量拉取也不会把它带出去。
|
||
CREATE TABLE IF NOT EXISTS app_settings (
|
||
key TEXT PRIMARY KEY,
|
||
value TEXT NOT NULL,
|
||
updated_at TEXT NOT NULL
|
||
);
|