162 lines
11 KiB
TypeScript
162 lines
11 KiB
TypeScript
import { db } from './connection';
|
|
import { branches, employees, candidates, settings, voteRecords } from './schema';
|
|
import { eq } from 'drizzle-orm';
|
|
import crypto from 'crypto';
|
|
|
|
// Simple hash function for PIN
|
|
function hashPin(pin: string): string {
|
|
return crypto.createHash('sha256').update(pin).digest('hex');
|
|
}
|
|
|
|
function generateId(): string {
|
|
return crypto.randomUUID();
|
|
}
|
|
|
|
async function seed() {
|
|
console.log('ðą Seeding database...');
|
|
|
|
// Check if already seeded
|
|
const existingBranches = await db.select().from(branches).limit(1);
|
|
if (existingBranches.length > 0) {
|
|
console.log('âïļ Database already seeded, skipping...');
|
|
return;
|
|
}
|
|
|
|
// ===== BRANCHES =====
|
|
const branchData = [
|
|
{ id: generateId(), name: 'āļŠāļģāļāļąāļāļāļēāļāđāļŦāļāđ (āļāļĨāļēāļ)', code: 'HQ' },
|
|
{ id: generateId(), name: 'āļŠāļēāļāļēāđāļāļĩāļĒāļāđāļŦāļĄāđ', code: 'CNX' },
|
|
{ id: generateId(), name: 'āļŠāļēāļāļēāļāļāļāđāļāđāļ', code: 'KKC' },
|
|
{ id: generateId(), name: 'āļŠāļēāļāļēāļ āļđāđāļāđāļ', code: 'PKT' },
|
|
{ id: generateId(), name: 'āļŠāļēāļāļēāļāļāļāļāļļāļĢāļĩ', code: 'NBI' },
|
|
{ id: generateId(), name: 'āļŠāļēāļāļēāļāļĨāļāļļāļĢāļĩ', code: 'CBI' },
|
|
];
|
|
|
|
for (const branch of branchData) {
|
|
await db.insert(branches).values(branch);
|
|
}
|
|
console.log(`â
Created ${branchData.length} branches`);
|
|
|
|
// ===== EMPLOYEES =====
|
|
const hqBranch = branchData[0];
|
|
const cnxBranch = branchData[1];
|
|
const kkcBranch = branchData[2];
|
|
const pktBranch = branchData[3];
|
|
const nbiBranch = branchData[4];
|
|
const cbiBranch = branchData[5];
|
|
|
|
const employeeData = [
|
|
// Admin
|
|
{ id: generateId(), employeeId: 'ADMIN001', name: 'āļāļđāđāļāļđāđāļĨāļĢāļ°āļāļ', branchId: hqBranch.id, isAdmin: true, pin: hashPin('1234'), isActive: true },
|
|
|
|
// HQ employees
|
|
{ id: generateId(), employeeId: 'EMP001', name: 'āļŠāļĄāļāļēāļĒ āđāļāļāļĩ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP002', name: 'āļŠāļĄāļŦāļāļīāļ āļĢāļąāļāđāļĢāļĩāļĒāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP003', name: 'āļ§āļīāļāļąāļĒ āļĄāļļāđāļāļĄāļąāđāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP004', name: 'āļāļĢāļāļīāļāļĒāđ āļŠāļ§āđāļēāļāļāļīāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP005', name: 'āļāļāļāļĢ āđāļāļĢāļīāļāļŠāļļāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP006', name: 'āļĢāļąāļāļāļē āļāļāļļāļāļĻāļĢāļĩ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP007', name: 'āļāļīāļāļāļīāļāļāļĐāđ āļ§āļāļĻāđāļāļāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP008', name: 'āļāļ āļąāļŠāļŠāļĢ āļĻāļĢāļĩāļŠāļļāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP009', name: 'āļāļĢāļ°āđāļŠāļĢāļīāļ āļāļīāļāļŠāļļāļ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP010', name: 'āļāļĢāļļāļāļĩ āđāļŠāļāļāļąāļāļāļĢāđ', branchId: hqBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
|
|
// Chiang Mai employees
|
|
{ id: generateId(), employeeId: 'EMP011', name: 'āđāļāļĢāļĩāļĒāļāļĻāļąāļāļāļīāđ āļāļāļĐāđāļāļĢāļ°āđāļŠāļĢāļīāļ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP012', name: 'āļĻāļīāļĢāļīāļĨāļąāļāļĐāļāđ āļāļāļāđāļĄāđ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP013', name: 'āļ āļēāļāļļāļāļāļĻāđ āļāļāļĢ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP014', name: 'āļāļīāļĢāļēāļ āļĢāļāđ āļĻāļĢāļĩāļŠāļĄāļāļđāļĢāļāđ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP015', name: 'āļāļāļīāļĻāļĢ āļ āļđāļĄāļīāļāļąāļāļāđ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP016', name: 'āļ§āļīāļ āļēāļāļē āđāļĢāļ·āļāļāļĻāļĢāļĩ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP017', name: 'āļāļēāļāļĢāļĩ āđāļŠāļāļŠāļļāļ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP018', name: 'āļāļīāļĄāļāđāđāļ āļĢāļļāđāļāđāļĢāļ·āļāļ', branchId: cnxBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
|
|
// Khon Kaen employees
|
|
{ id: generateId(), employeeId: 'EMP019', name: 'āļŠāļļāļĢāļāļąāļĒ āļāļĨāđāļĄāļ·āļāļ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP020', name: 'āļ§āļĢāļĢāļāļē āļŠāļīāļāļāļīāļāļĨ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP021', name: 'āļāļĩāļĢāļāļāļĐāđ āļāļąāļāļāļĢāđāđāļāđāļ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP022', name: 'āļĨāļĨāļīāļāļē āļŠāļļāļāļŠāļąāļāļāđ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP023', name: 'āļāļļāļāļĄāļĩ āļĻāļĢāļĩāđāļĄāļ·āļāļ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP024', name: 'āļāļīāļāļĢāļē āļāļāļāļāļĩ', branchId: kkcBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
|
|
// Phuket employees
|
|
{ id: generateId(), employeeId: 'EMP025', name: 'āļ§āļīāļāļąāļĒ āļāļ°āđāļĨāđāļŠ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP026', name: 'āļŠāļĄāļĻāļĢāļĩ āļŦāļēāļāļāļāļ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP027', name: 'āļāļĢāļ°āļ āļēāļŠ āđāļāđāļ§āļĄāļļāļ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP028', name: 'āļāļīāļāļĒāļē āļŠāļĄāļļāļāļĢ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP029', name: 'āļāļĄāļĨāļāļāļ āļ§āļīāđāļĨāļĨāļąāļāļĐāļāđ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP030', name: 'āļāļĩāļĢāļāļāļĻāđ āļāļĨāļāļĩ', branchId: pktBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
|
|
// Nonthaburi employees
|
|
{ id: generateId(), employeeId: 'EMP031', name: 'āļāļāļ§āļąāļāļāđ āļāļļāļāđāļĢāļ·āļāļ', branchId: nbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP032', name: 'āļŠāļļāļāļĩāļĒāđ āļĢāļļāđāļāļāļĢāļļāļ', branchId: nbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP033', name: 'āļāļąāļĒāļ§āļąāļāļāđ āļāļĢāļ°āļŠāļīāļāļāļīāđ', branchId: nbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP034', name: 'āļ§āļīāļĄāļĨ āļāļąāļāļāļĢāđāđāļāđāļ§', branchId: nbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP035', name: 'āļŠāļĄāļāļąāļāļī āļāļāļāļāļģ', branchId: nbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
|
|
// Chonburi employees
|
|
{ id: generateId(), employeeId: 'EMP036', name: 'āļ§āļĩāļĢāļāļąāļĒ āļĻāļĢāļĩāļŠāļĄāļļāļāļĢ', branchId: cbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP037', name: 'āļāļąāļāļāļĢāđāđāļāđāļ āđāļŠāļāļāļāļ', branchId: cbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP038', name: 'āļāļāļąāļāļāđ āļāļąāļĒāļāļāļ°', branchId: cbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP039', name: 'āļŠāļēāļĒāļāļ āļāļĢāļĄāđāļĒāđāļ', branchId: cbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
{ id: generateId(), employeeId: 'EMP040', name: 'āļāļđāļĻāļĢāļĩ āļāļļāļāļĄāļēāļ', branchId: cbiBranch.id, isAdmin: false, pin: hashPin('1234'), isActive: true },
|
|
];
|
|
|
|
for (const emp of employeeData) {
|
|
await db.insert(employees).values(emp);
|
|
}
|
|
console.log(`â
Created ${employeeData.length} employees`);
|
|
|
|
// ===== CANDIDATES (some sample ones) =====
|
|
// Use existing employees as candidates
|
|
const candidateEmployees = employeeData.filter(e => !e.isAdmin && [
|
|
'EMP001', 'EMP003', 'EMP005', 'EMP007', 'EMP009', // HQ
|
|
'EMP011', 'EMP013', 'EMP015', 'EMP017', // CNX
|
|
'EMP019', 'EMP021', 'EMP023', // KKC
|
|
'EMP025', 'EMP027', 'EMP029', // PKT
|
|
'EMP031', 'EMP033', // NBI
|
|
'EMP036', 'EMP038', // CBI
|
|
].includes(e.employeeId));
|
|
|
|
const candidateData = candidateEmployees.map(emp => ({
|
|
id: generateId(),
|
|
employeeId: emp.id,
|
|
branchId: emp.branchId,
|
|
position: 'āļāļāļąāļāļāļēāļ',
|
|
statement: `āļāļĢāđāļāļĄāļāļĩāđāļāļ°āđāļāđāļāļāļąāļ§āđāļāļāļāļāļąāļāļāļēāļ āđāļāļ·āđāļāļŠāđāļāđāļŠāļĢāļīāļĄāļŠāļīāļāļāļīāđāļĨāļ°āļāļļāļāļ āļēāļāļāļĩāļ§āļīāļāđāļāļāļēāļĢāļāļģāļāļēāļ`,
|
|
isApproved: true,
|
|
}));
|
|
|
|
for (const cand of candidateData) {
|
|
await db.insert(candidates).values(cand);
|
|
}
|
|
console.log(`â
Created ${candidateData.length} candidates`);
|
|
|
|
// ===== SETTINGS =====
|
|
const now = new Date();
|
|
const votingStart = new Date(now.getTime() - 1 * 24 * 60 * 60 * 1000); // 1 day ago (voting is open)
|
|
const votingEnd = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); // 7 days from now
|
|
|
|
const settingsData = [
|
|
{ id: generateId(), key: 'maxVotesPerPerson', value: '5' },
|
|
{ id: generateId(), key: 'votingStartDate', value: votingStart.toISOString() },
|
|
{ id: generateId(), key: 'votingEndDate', value: votingEnd.toISOString() },
|
|
{ id: generateId(), key: 'votingEnabled', value: 'true' },
|
|
{ id: generateId(), key: 'resultsVisible', value: 'false' }, // Only show results after voting ends (admin can toggle)
|
|
{ id: generateId(), key: 'systemName', value: 'āļĢāļ°āļāļāđāļĨāļ·āļāļāļāļąāđāļāļāļąāļ§āđāļāļāļāļāļąāļāļāļēāļ' },
|
|
];
|
|
|
|
for (const setting of settingsData) {
|
|
await db.insert(settings).values(setting);
|
|
}
|
|
console.log(`â
Created ${settingsData.length} settings`);
|
|
|
|
console.log('ð Seeding complete!');
|
|
console.log('');
|
|
console.log('ð Login credentials:');
|
|
console.log(' Admin: ADMIN001 / 1234');
|
|
console.log(' Employee: EMP001-EMP040 / 1234');
|
|
}
|
|
|
|
seed().catch(console.error);
|