(Feat): Initial Commit

This commit is contained in:
2025-11-27 22:50:08 +00:00
commit 00f9ed128b
79 changed files with 17413 additions and 0 deletions

View File

@@ -0,0 +1,240 @@
import bcrypt from 'bcryptjs';
import mysql from 'mysql2/promise';
import dotenv from 'dotenv';
dotenv.config();
async function seedDatabase() {
let connection;
try {
// Connect to database with retry logic
console.log('🔌 Connecting to database...');
let retries = 5;
while (retries > 0) {
try {
connection = await mysql.createConnection({
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || 'admin123',
database: process.env.DB_NAME || 'work_allocation',
port: process.env.DB_PORT || 3306,
connectTimeout: 10000,
enableKeepAlive: true,
keepAliveInitialDelay: 0
});
break;
} catch (err) {
retries--;
if (retries === 0) throw err;
console.log(` ⏳ Retrying connection... (${5 - retries}/5)`);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
console.log('✅ Connected to database');
console.log('');
// 1. Seed Departments
console.log('📁 Seeding departments...');
const [existingDepts] = await connection.query('SELECT COUNT(*) as count FROM departments');
if (existingDepts[0].count === 0) {
await connection.query(`
INSERT INTO departments (name) VALUES
('Tudki'),
('Dana'),
('Groundnut')
`);
console.log(' ✅ Departments created');
} else {
console.log(' Departments already exist');
}
// 2. Seed Sub-departments for Groundnut
console.log('📂 Seeding sub-departments...');
const [groundnutDept] = await connection.query('SELECT id FROM departments WHERE name = ?', ['Groundnut']);
let groundnutId = null;
if (groundnutDept.length > 0) {
groundnutId = groundnutDept[0].id;
const [existingSubDepts] = await connection.query('SELECT COUNT(*) as count FROM sub_departments WHERE department_id = ?', [groundnutId]);
if (existingSubDepts[0].count === 0) {
await connection.query(`
INSERT INTO sub_departments (department_id, name, primary_activity) VALUES
(?, 'Mufali Aavak Katai', 'Loading/Unloading'),
(?, 'Mufali Aavak Dhang', 'Loading/Unloading'),
(?, 'Dhang Se Katai', 'Loading/Unloading'),
(?, 'Guthli Bori Silai Dhang', 'Loading/Unloading'),
(?, 'Guthali dada Pala Tulai Silai Dhang', 'Loading/Unloading'),
(?, 'Mufali Patthar Bori silai dhang', 'Loading/Unloading'),
(?, 'Mufali Patthar Bori Utrai', 'Loading/Unloading'),
(?, 'Bardana Bandal Loading Unloading', 'Loading/Unloading'),
(?, 'Bardana Gatthi Loading', 'Loading/Unloading'),
(?, 'Black Dana Loading/Unloading', 'Loading/Unloading'),
(?, 'Pre Cleaning', 'Pre Cleaning'),
(?, 'Destoner', 'Destoner'),
(?, 'Water', 'Water'),
(?, 'Decordicater', 'Decordicater & Cleaning'),
(?, 'Round Chalna', 'Round Chalna & Cleaning'),
(?, 'Cleaning', 'Decordicater & Cleaning'),
(?, 'Round Chalna No.1', 'Round Chalna No.1')
`, Array(17).fill(groundnutId));
console.log(' ✅ Sub-departments created');
} else {
console.log(' Sub-departments already exist');
}
}
// 3. Seed SuperAdmin
console.log('👤 Seeding SuperAdmin user...');
const [existingAdmin] = await connection.query('SELECT id FROM users WHERE username = ?', ['admin']);
const adminPassword = await bcrypt.hash('admin123', 10);
if (existingAdmin.length > 0) {
await connection.query(
'UPDATE users SET password = ?, is_active = TRUE WHERE username = ?',
[adminPassword, 'admin']
);
console.log(' ✅ SuperAdmin password updated');
} else {
await connection.query(
'INSERT INTO users (username, name, email, password, role, is_active) VALUES (?, ?, ?, ?, ?, ?)',
['admin', 'Super Admin', 'admin@workallocate.com', adminPassword, 'SuperAdmin', true]
);
console.log(' ✅ SuperAdmin created');
}
// 4. Seed Sample Supervisors
console.log('👥 Seeding sample supervisors...');
const [tudkiDept] = await connection.query('SELECT id FROM departments WHERE name = ?', ['Tudki']);
const [danaDept] = await connection.query('SELECT id FROM departments WHERE name = ?', ['Dana']);
const supervisorPassword = await bcrypt.hash('supervisor123', 10);
const supervisors = [
{ username: 'supervisor_tudki', name: 'Tudki Supervisor', email: 'supervisor.tudki@workallocate.com', deptId: tudkiDept[0]?.id },
{ username: 'supervisor_dana', name: 'Dana Supervisor', email: 'supervisor.dana@workallocate.com', deptId: danaDept[0]?.id },
{ username: 'supervisor_groundnut', name: 'Groundnut Supervisor', email: 'supervisor.groundnut@workallocate.com', deptId: groundnutId }
];
for (const sup of supervisors) {
if (sup.deptId) {
const [existing] = await connection.query('SELECT id FROM users WHERE username = ?', [sup.username]);
if (existing.length === 0) {
await connection.query(
'INSERT INTO users (username, name, email, password, role, department_id, is_active) VALUES (?, ?, ?, ?, ?, ?, ?)',
[sup.username, sup.name, sup.email, supervisorPassword, 'Supervisor', sup.deptId, true]
);
console.log(`${sup.name} created`);
} else {
console.log(` ${sup.name} already exists`);
}
}
}
// 5. Seed Sample Contractors
console.log('🏗️ Seeding sample contractors...');
const contractorPassword = await bcrypt.hash('contractor123', 10);
const contractors = [
{ username: 'contractor1', name: 'Contractor One', email: 'contractor1@workallocate.com', deptId: groundnutId },
{ username: 'contractor2', name: 'Contractor Two', email: 'contractor2@workallocate.com', deptId: groundnutId }
];
for (const con of contractors) {
const [existing] = await connection.query('SELECT id FROM users WHERE username = ?', [con.username]);
if (existing.length === 0) {
await connection.query(
'INSERT INTO users (username, name, email, password, role, department_id, is_active) VALUES (?, ?, ?, ?, ?, ?, ?)',
[con.username, con.name, con.email, contractorPassword, 'Contractor', con.deptId, true]
);
console.log(`${con.name} created`);
} else {
console.log(` ${con.name} already exists`);
}
}
// 6. Seed Sample Employees
console.log('👷 Seeding sample employees...');
const [contractor1] = await connection.query('SELECT id FROM users WHERE username = ?', ['contractor1']);
const employeePassword = await bcrypt.hash('employee123', 10);
if (contractor1.length > 0) {
const employees = [
{ username: 'employee1', name: 'Employee One', email: 'employee1@workallocate.com' },
{ username: 'employee2', name: 'Employee Two', email: 'employee2@workallocate.com' },
{ username: 'employee3', name: 'Employee Three', email: 'employee3@workallocate.com' }
];
for (const emp of employees) {
const [existing] = await connection.query('SELECT id FROM users WHERE username = ?', [emp.username]);
if (existing.length === 0) {
await connection.query(
'INSERT INTO users (username, name, email, password, role, department_id, contractor_id, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
[emp.username, emp.name, emp.email, employeePassword, 'Employee', groundnutId, contractor1[0].id, true]
);
console.log(`${emp.name} created`);
} else {
console.log(` ${emp.name} already exists`);
}
}
}
// 7. Seed Contractor Rates
console.log('💰 Seeding contractor rates...');
if (contractor1.length > 0) {
const [existingRate] = await connection.query(
'SELECT id FROM contractor_rates WHERE contractor_id = ?',
[contractor1[0].id]
);
if (existingRate.length === 0) {
await connection.query(
'INSERT INTO contractor_rates (contractor_id, rate, effective_date) VALUES (?, ?, CURDATE())',
[contractor1[0].id, 500.00]
);
console.log(' ✅ Contractor rates created');
} else {
console.log(' Contractor rates already exist');
}
}
console.log('');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('✅ Database seeding completed successfully!');
console.log('');
console.log('🔑 Default Login Credentials:');
console.log('');
console.log(' SuperAdmin:');
console.log(' Username: admin');
console.log(' Password: admin123');
console.log('');
console.log(' Supervisor (Groundnut):');
console.log(' Username: supervisor_groundnut');
console.log(' Password: supervisor123');
console.log('');
console.log(' Contractor:');
console.log(' Username: contractor1');
console.log(' Password: contractor123');
console.log('');
console.log(' Employee:');
console.log(' Username: employee1');
console.log(' Password: employee123');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('');
} catch (error) {
console.error('❌ Error seeding database:', error.message);
process.exit(1);
} finally {
if (connection) {
await connection.end();
}
}
}
seedDatabase();

View File

@@ -0,0 +1,135 @@
-- Work Allocation System Database Schema
-- This version is for Docker init (database already created by environment variables)
-- Departments table
CREATE TABLE IF NOT EXISTS departments (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Sub-departments table (for Groundnut department)
CREATE TABLE IF NOT EXISTS sub_departments (
id INT PRIMARY KEY AUTO_INCREMENT,
department_id INT NOT NULL,
name VARCHAR(200) NOT NULL,
primary_activity VARCHAR(200) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE CASCADE
);
-- Users table (for all roles: SuperAdmin, Supervisor, Contractor, Employee)
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) NOT NULL UNIQUE,
name VARCHAR(200) NOT NULL,
email VARCHAR(200) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role ENUM('SuperAdmin', 'Supervisor', 'Contractor', 'Employee') NOT NULL,
department_id INT,
contractor_id INT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE SET NULL,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE SET NULL
);
-- Contractor rates table (rates per contractor + sub-department combination)
CREATE TABLE IF NOT EXISTS contractor_rates (
id INT PRIMARY KEY AUTO_INCREMENT,
contractor_id INT NOT NULL,
sub_department_id INT,
activity VARCHAR(200),
rate DECIMAL(10, 2) NOT NULL,
effective_date DATE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE SET NULL
);
-- Work allocations table
CREATE TABLE IF NOT EXISTS work_allocations (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT NOT NULL,
supervisor_id INT NOT NULL,
contractor_id INT NOT NULL,
sub_department_id INT,
activity VARCHAR(100),
description TEXT,
assigned_date DATE NOT NULL,
status ENUM('Pending', 'InProgress', 'Completed', 'Cancelled') DEFAULT 'Pending',
completion_date DATE,
rate DECIMAL(10, 2),
units DECIMAL(10, 2),
total_amount DECIMAL(10, 2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (employee_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (supervisor_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE SET NULL
);
-- Attendance table
CREATE TABLE IF NOT EXISTS attendance (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT NOT NULL,
supervisor_id INT NOT NULL,
check_in_time DATETIME NOT NULL,
check_out_time DATETIME,
work_date DATE NOT NULL,
status ENUM('CheckedIn', 'CheckedOut') DEFAULT 'CheckedIn',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (employee_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (supervisor_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Insert default departments
INSERT IGNORE INTO departments (name) VALUES
('Tudki'),
('Dana'),
('Groundnut');
-- Insert Groundnut sub-departments
INSERT IGNORE INTO sub_departments (department_id, name, primary_activity)
SELECT id, 'Mufali Aavak Katai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Aavak Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Dhang Se Katai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Guthli Bori Silai Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Guthali dada Pala Tulai Silai Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Patthar Bori silai dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Patthar Bori Utrai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Bardana Bandal Loading Unloading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Bardana Gatthi Loading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Black Dana Loading/Unloading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Pre Cleaning', 'Pre Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Destoner', 'Destoner' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Water', 'Water' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Decordicater', 'Decordicater & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Round Chalna', 'Round Chalna & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Cleaning', 'Decordicater & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Round Chalna No.1', 'Round Chalna No.1' FROM departments WHERE name = 'Groundnut';
-- Note: Admin user will be created by running: npm run seed
-- This ensures the password is properly hashed with bcrypt

View File

@@ -0,0 +1,11 @@
-- Migration: Add activity, units, and total_amount columns to work_allocations table
-- Run this if you have an existing database without these columns
ALTER TABLE work_allocations
ADD COLUMN IF NOT EXISTS activity VARCHAR(100) AFTER sub_department_id;
ALTER TABLE work_allocations
ADD COLUMN IF NOT EXISTS units DECIMAL(10, 2) AFTER rate;
ALTER TABLE work_allocations
ADD COLUMN IF NOT EXISTS total_amount DECIMAL(10, 2) AFTER units;

View File

@@ -0,0 +1,13 @@
-- Migration: Add sub_department_id and activity columns to contractor_rates table
-- Run this if you have an existing database
-- Add sub_department_id column if it doesn't exist
ALTER TABLE contractor_rates
ADD COLUMN IF NOT EXISTS sub_department_id INT NULL,
ADD COLUMN IF NOT EXISTS activity VARCHAR(200) NULL;
-- Add foreign key constraint for sub_department_id
-- Note: This may fail if the constraint already exists
ALTER TABLE contractor_rates
ADD CONSTRAINT fk_contractor_rates_sub_department
FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE SET NULL;

134
backend/database/schema.sql Normal file
View File

@@ -0,0 +1,134 @@
-- Work Allocation System Database Schema
-- Create database
CREATE DATABASE IF NOT EXISTS work_allocation;
USE work_allocation;
-- Departments table
CREATE TABLE departments (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Sub-departments table (for Groundnut department)
CREATE TABLE sub_departments (
id INT PRIMARY KEY AUTO_INCREMENT,
department_id INT NOT NULL,
name VARCHAR(200) NOT NULL,
primary_activity VARCHAR(200) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE CASCADE
);
-- Users table (for all roles: SuperAdmin, Supervisor, Contractor, Employee)
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) NOT NULL UNIQUE,
name VARCHAR(200) NOT NULL,
email VARCHAR(200) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role ENUM('SuperAdmin', 'Supervisor', 'Contractor', 'Employee') NOT NULL,
department_id INT,
contractor_id INT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE SET NULL,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE SET NULL
);
-- Contractor rates table
CREATE TABLE contractor_rates (
id INT PRIMARY KEY AUTO_INCREMENT,
contractor_id INT NOT NULL,
rate DECIMAL(10, 2) NOT NULL,
effective_date DATE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Work allocations table
CREATE TABLE work_allocations (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT NOT NULL,
supervisor_id INT NOT NULL,
contractor_id INT NOT NULL,
sub_department_id INT,
description TEXT,
assigned_date DATE NOT NULL,
status ENUM('Pending', 'InProgress', 'Completed', 'Cancelled') DEFAULT 'Pending',
completion_date DATE,
rate DECIMAL(10, 2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (employee_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (supervisor_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (contractor_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (sub_department_id) REFERENCES sub_departments(id) ON DELETE SET NULL
);
-- Attendance table
CREATE TABLE attendance (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_id INT NOT NULL,
supervisor_id INT NOT NULL,
check_in_time DATETIME NOT NULL,
check_out_time DATETIME,
work_date DATE NOT NULL,
status ENUM('CheckedIn', 'CheckedOut') DEFAULT 'CheckedIn',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (employee_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (supervisor_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Insert default departments
INSERT INTO departments (name) VALUES
('Tudki'),
('Dana'),
('Groundnut');
-- Insert Groundnut sub-departments
INSERT INTO sub_departments (department_id, name, primary_activity)
SELECT id, 'Mufali Aavak Katai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Aavak Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Dhang Se Katai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Guthli Bori Silai Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Guthali dada Pala Tulai Silai Dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Patthar Bori silai dhang', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Mufali Patthar Bori Utrai', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Bardana Bandal Loading Unloading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Bardana Gatthi Loading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Black Dana Loading/Unloading', 'Loading/Unloading' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Pre Cleaning', 'Pre Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Destoner', 'Destoner' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Water', 'Water' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Decordicater', 'Decordicater & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Round Chalna', 'Round Chalna & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Cleaning', 'Decordicater & Cleaning' FROM departments WHERE name = 'Groundnut'
UNION ALL
SELECT id, 'Round Chalna No.1', 'Round Chalna No.1' FROM departments WHERE name = 'Groundnut';
-- Insert default SuperAdmin (password: admin123)
-- Password is hashed using bcrypt: $2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
INSERT INTO users (username, name, email, password, role) VALUES
('admin', 'Super Admin', 'admin@workallocate.com', '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'SuperAdmin');

View File

@@ -0,0 +1,72 @@
import bcrypt from 'bcryptjs';
import mysql from 'mysql2/promise';
import dotenv from 'dotenv';
dotenv.config();
async function seedAdmin() {
let connection;
try {
// Connect to database (use root for seeding)
connection = await mysql.createConnection({
host: process.env.DB_HOST || 'localhost',
user: 'root',
password: 'rootpassword',
database: process.env.DB_NAME || 'work_allocation',
port: process.env.DB_PORT || 3306
});
console.log('✅ Connected to database');
// Check if admin already exists
const [existingUsers] = await connection.query(
'SELECT id FROM users WHERE username = ?',
['admin']
);
if (existingUsers.length > 0) {
console.log(' Admin user already exists, updating password...');
// Generate new password hash
const passwordHash = await bcrypt.hash('admin123', 10);
// Update existing admin user
await connection.query(
'UPDATE users SET password = ? WHERE username = ?',
[passwordHash, 'admin']
);
console.log('✅ Admin password updated successfully');
} else {
console.log('📝 Creating admin user...');
// Generate password hash
const passwordHash = await bcrypt.hash('admin123', 10);
// Insert admin user
await connection.query(
'INSERT INTO users (username, name, email, password, role) VALUES (?, ?, ?, ?, ?)',
['admin', 'Super Admin', 'admin@workallocate.com', passwordHash, 'SuperAdmin']
);
console.log('✅ Admin user created successfully');
}
console.log('');
console.log('🔑 Default Login Credentials:');
console.log(' Username: admin');
console.log(' Password: admin123');
console.log('');
} catch (error) {
console.error('❌ Error seeding admin user:', error.message);
process.exit(1);
} finally {
if (connection) {
await connection.end();
}
}
}
seedAdmin();