-- ═══ CYPHER-HR Database Schema ═══ -- Run: psql -U KENCYPHER -d "cypher-hr" -f schema.sql CREATE TABLE IF NOT EXISTS company_profile ( id SERIAL PRIMARY KEY, company_name VARCHAR(255) NOT NULL, address TEXT, phone VARCHAR(30), email VARCHAR(255), website VARCHAR(255), industry VARCHAR(100), established_date DATE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, role VARCHAR(20) NOT NULL DEFAULT 'employee', department VARCHAR(100), position VARCHAR(100), phone VARCHAR(30), avatar_color VARCHAR(10) DEFAULT '#6366f1', is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS leave_policies ( id SERIAL PRIMARY KEY, leave_type VARCHAR(60) NOT NULL UNIQUE, monthly_limit INTEGER NOT NULL DEFAULT 1, is_enabled BOOLEAN DEFAULT true, description TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS leave_balances ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, leave_policy_id INTEGER NOT NULL REFERENCES leave_policies(id) ON DELETE CASCADE, balance INTEGER NOT NULL DEFAULT 0, month INTEGER NOT NULL, year INTEGER NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), UNIQUE(user_id, leave_policy_id, month, year) ); CREATE TABLE IF NOT EXISTS leave_requests ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, leave_policy_id INTEGER NOT NULL REFERENCES leave_policies(id) ON DELETE CASCADE, start_date DATE NOT NULL, end_date DATE NOT NULL, reason TEXT, status VARCHAR(20) NOT NULL DEFAULT 'pending', admin_remarks TEXT, approved_by INTEGER REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_leave_balances_user ON leave_balances(user_id); CREATE INDEX IF NOT EXISTS idx_leave_balances_period ON leave_balances(month, year); CREATE INDEX IF NOT EXISTS idx_leave_requests_user ON leave_requests(user_id); CREATE INDEX IF NOT EXISTS idx_leave_requests_status ON leave_requests(status); CREATE INDEX IF NOT EXISTS idx_users_role ON users(role); CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);