Files

20 lines
2.0 KiB
JavaScript

import { randomUUID } from 'node:crypto';
import { createMongoStore } from './db.js';
import { loadConfig } from './config.js';
import { hashPassword, validEmail } from './security.js';
function argument(name) { const prefix = `--${name}=`; const item = process.argv.find((value) => value.startsWith(prefix)); return item ? item.slice(prefix.length) : ''; }
const config = await loadConfig();
const email = argument('email').trim().toLowerCase(); const password = argument('password') || config.qa.password || ''; const displayName = (argument('display-name') || 'QA Operator').trim(); const teamName = (argument('team-name') || 'QA Team').trim();
const dbName = argument('db') || config.qa.db; const uri = config.mongodb.uri;
if (!/^basket_utils_qa(?:_[A-Za-z0-9-]+)?$/.test(dbName)) throw new Error('QA seed는 basket_utils_qa 또는 basket_utils_qa_* 데이터베이스만 사용할 수 있습니다');
if (!validEmail(email) || password.length < 8 || !displayName || !teamName) throw new Error('사용법: npm run seed-qa -- --email=qa@example.com --password=긴비밀번호 [--db=basket_utils_qa]');
const store = await createMongoStore({ config, uri, dbName });
try {
const at = new Date(); let user = await store.users.findOne({ email });
if (user) { await store.users.updateOne({ id: user.id }, { $set: { displayName, passwordHash: await hashPassword(password), status: 'approved', isOperator: true, updatedAt: at } }); }
else { user = { id: randomUUID(), email, displayName }; await store.users.insertOne({ ...user, passwordHash: await hashPassword(password), status: 'approved', isOperator: true, createdAt: at, updatedAt: at }); }
const team = { id: randomUUID(), name: teamName, ownerUserId: user.id, createdAt: at, updatedAt: at }; await store.teams.insertOne(team); await store.teamMembers.insertOne({ teamId: team.id, userId: user.id, role: 'owner', createdAt: at });
console.log(JSON.stringify({ dbName, email, teamId: team.id, teamName }, null, 2));
} finally { await store.close(); }