- scripts/backfill-users.ts: 扫 PG users 表,对每人幂等调 orchestrator POST /users - orchestrator/package.json: 加 postgres 依赖 - .memory/project.md: Phase 3/4 完成状态,Phase 5 上线 checklist Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
#!/usr/bin/env bun
|
|
/**
|
|
* 给存量 LobeChat 用户补建沙箱容器(幂等,已存在就跳过)。
|
|
*
|
|
* 用法(在 VPS 上跑):
|
|
* export DATABASE_URL=postgresql://...
|
|
* export SANDBOX_BACKEND_URL=http://127.0.0.1:8700
|
|
* export SANDBOX_BACKEND_SECRET=<same as orchestrator>
|
|
* bun run scripts/backfill-users.ts
|
|
*/
|
|
import postgres from 'postgres';
|
|
|
|
const DATABASE_URL = process.env.DATABASE_URL;
|
|
const BACKEND_URL = process.env.SANDBOX_BACKEND_URL ?? 'http://127.0.0.1:8700';
|
|
const SECRET = process.env.SANDBOX_BACKEND_SECRET;
|
|
|
|
if (!DATABASE_URL) throw new Error('DATABASE_URL required');
|
|
if (!SECRET) throw new Error('SANDBOX_BACKEND_SECRET required');
|
|
|
|
const sql = postgres(DATABASE_URL, { max: 1 });
|
|
|
|
const users: { id: string; email: string | null }[] = await sql`
|
|
SELECT id, email FROM users ORDER BY created_at ASC
|
|
`;
|
|
|
|
console.log(`[backfill] ${users.length} users to check`);
|
|
|
|
let ok = 0,
|
|
skip = 0,
|
|
fail = 0;
|
|
|
|
for (const u of users) {
|
|
try {
|
|
const res = await fetch(`${BACKEND_URL}/api/v1/users`, {
|
|
body: JSON.stringify({ userId: u.id }),
|
|
headers: { 'Content-Type': 'application/json', 'X-Sandbox-Secret': SECRET },
|
|
method: 'POST',
|
|
});
|
|
const text = await res.text();
|
|
if (res.ok) {
|
|
if (text.includes('"success":true')) {
|
|
ok++;
|
|
console.log(`[backfill] ✓ ${u.id} (${u.email ?? '-'})`);
|
|
} else {
|
|
skip++;
|
|
console.log(`[backfill] ~ ${u.id}: ${text.slice(0, 100)}`);
|
|
}
|
|
} else {
|
|
fail++;
|
|
console.error(`[backfill] ✗ ${u.id}: HTTP ${res.status} ${text.slice(0, 100)}`);
|
|
}
|
|
} catch (e) {
|
|
fail++;
|
|
console.error(`[backfill] ✗ ${u.id}:`, (e as Error).message);
|
|
}
|
|
}
|
|
|
|
console.log(`[backfill] done: ok=${ok} skip=${skip} fail=${fail}`);
|
|
await sql.end();
|