seed-admin-user.js 2 KB
#!/usr/bin/env node
/**
 * seed-admin-user.js — 建出登录用的默认种子账号
 *
 * 依据: docs/todo/system-design/38-auth-multi-tenant-isolation.md §3.4 / Phase 0
 *
 * 账号: admin / hex1234(登录标识存在 users.email 列,不要求真实邮箱格式——
 * 直接走 userDb.createUser 建号,不经过 /api/auth/register 那道邮箱格式校验)。
 *
 * 幂等: admin 已存在就跳过,可重复执行。
 *
 * 用法:
 *   node scripts/seed-admin-user.js
 */

const path = require('path');
// bcryptjs 是 server/package.json 的依赖,只装在 server/node_modules 下(三个 workspace
// 各自独立 npm install,不是 pnpm 提升到根目录),scripts/ 在这层目录树里够不着它,
// 用 require.resolve 的 paths 选项显式指去 server/ 底下找。
const bcrypt = require(require.resolve('bcryptjs', { paths: [path.join(__dirname, '..', 'server')] }));
const userDb = require('../server/services/user-db');

const SEED_EMAIL = 'admin';
const SEED_PASSWORD = 'hex1234';
const SEED_DISPLAY_NAME = 'admin';
const SALT_ROUNDS = 10;

async function main() {
  const existing = userDb.findByEmail(SEED_EMAIL);
  if (existing) {
    console.log(`[seed-admin-user] 账号 "${SEED_EMAIL}" 已存在(id=${existing.id}),跳过`);
    return;
  }

  const passwordHash = await bcrypt.hash(SEED_PASSWORD, SALT_ROUNDS);
  const user = userDb.createUser({
    email: SEED_EMAIL,
    passwordHash,
    displayName: SEED_DISPLAY_NAME,
    provider: 'local',
  });

  // role 列默认是 'user'(user-db.js 建表语句),种子账号需要 admin 权限
  // 才能看到全部存量公司(38 号文档 §一.4 / §四 Phase 2)——createUser 不接收
  // role 参数,直接改这一行。
  userDb.getDb().prepare('UPDATE users SET role = ? WHERE id = ?').run('admin', user.id);

  console.log(`[seed-admin-user] 已创建账号 "${SEED_EMAIL}"(id=${user.id}, role=admin)`);
}

main().catch((err) => {
  console.error('[seed-admin-user] 失败:', err.message);
  process.exit(1);
});