architecture: 数据唯一权威迁至服务器——本地降级为实时缓存,写后即时推送+快照重建;账号登录转为云端原生(新增 /api/auth/password、/api/auth/delete、每日自动备份)

This commit is contained in:
root
2026-10-16 16:13:38 +08:00
parent 7517eb0ad9
commit e5f99d46d8
16 changed files with 641 additions and 478 deletions
+6 -6
View File
@@ -15,8 +15,8 @@ const store = new Map<string, string>()
setItem: (k: string, v: string) => { store.set(k, String(v)) },
removeItem: (k: string) => { store.delete(k) }
}
store.set('dsh_cloud_creds', JSON.stringify({ username: 'audit_a', password: 'aapass123' }))
store.set('dsh_session_user', JSON.stringify({ userId: 'local_rt', username: 'audit_a' }))
store.set('dsh_cloud_creds', JSON.stringify({ username: 'twodev', password: 'dev123456' }))
store.set('dsh_session_user', JSON.stringify({ userId: 'local_rt', username: 'twodev' }))
// Node 24 自带 EventSource;老环境则垫一个基于 fetch 流的最小实现
if (typeof (globalThis as any).EventSource === 'undefined') {
@@ -54,7 +54,7 @@ async function main() {
check('Node 有 EventSource(原生或垫片)', typeof (globalThis as any).EventSource !== 'undefined')
bindDatabase(new WorklogDB('rt_a'))
await repo.setSetting('sync_base_url', BASE) // 测试环境指向本机服务
store.set('dsh_sync_base', BASE) // 测试环境同步基址走本地覆盖
engine.enableRealtimeSync()
// ---- 场景1:本地写入 -> 防抖 3s -> 自动推送 ----
@@ -63,7 +63,7 @@ async function main() {
const login = await fetch(BASE + '/api/auth/login', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'audit_a', password: 'aapass123' })
body: JSON.stringify({ username: 'twodev', password: 'dev123456' })
})
const tok = (await login.json()).token as string
async function serverSnapshot(): Promise<Record<string, any>> {
@@ -101,10 +101,10 @@ async function main() {
// ---- 场景3:autoSyncNow 手动失败可见性(断開服务)----
engine.stopRealtime()
await repo.setSetting('sync_base_url', 'http://127.0.0.1:9') // 不可达端口
store.set('dsh_sync_base', 'http://127.0.0.1:9') // 服务不可达
await engine.autoSyncNow()
check('服务不可达时 syncLastError 被记录', engine.syncLastError.value !== '', engine.syncLastError.value)
await repo.setSetting('sync_base_url', BASE)
store.set('dsh_sync_base', BASE)
console.log('==== 实时链路审计: PASS ' + pass + ' / FAIL ' + fail + ' ====')
process.exit(fail > 0 ? 1 : 0)