- Database: Add Loan, LoanInstallment, PurchaseRequest, LeaveEntitlement, EmployeeContract models - Database: Extend Attendance with ZK Tico fields (sourceDeviceId, externalId, rawData) - Database: Add Employee.attendancePin for device mapping - Backend: HR admin - Loans, Purchase Requests, Leave entitlements, Employee contracts CRUD - Backend: Leave reject, bulk attendance sync (ZK Tico ready) - Backend: Employee Portal API - scoped by employeeId (loans, leaves, purchase-requests, attendance, salaries) - Frontend: Employee Portal - dashboard, loans, leave, purchase-requests, attendance, salaries - Frontend: HR Admin - new tabs for Leaves, Loans, Purchase Requests, Contracts (approve/reject) - Dashboard: Add My Portal link - No destructive schema changes; additive migrations only Made-with: Cursor
132 lines
5.4 KiB
SQL
132 lines
5.4 KiB
SQL
-- AlterTable: Add attendancePin to employees
|
|
ALTER TABLE "employees" ADD COLUMN IF NOT EXISTS "attendancePin" TEXT;
|
|
|
|
-- CreateIndex (unique) on attendancePin - only if column added
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "employees_attendancePin_key" ON "employees"("attendancePin");
|
|
|
|
-- AlterTable: Add ZK Tico fields to attendances
|
|
ALTER TABLE "attendances" ADD COLUMN IF NOT EXISTS "sourceDeviceId" TEXT;
|
|
ALTER TABLE "attendances" ADD COLUMN IF NOT EXISTS "externalId" TEXT;
|
|
ALTER TABLE "attendances" ADD COLUMN IF NOT EXISTS "rawData" JSONB;
|
|
|
|
-- CreateIndex on sourceDeviceId
|
|
CREATE INDEX IF NOT EXISTS "attendances_sourceDeviceId_idx" ON "attendances"("sourceDeviceId");
|
|
|
|
-- CreateTable: loans
|
|
CREATE TABLE "loans" (
|
|
"id" TEXT NOT NULL,
|
|
"employeeId" TEXT NOT NULL,
|
|
"loanNumber" TEXT NOT NULL,
|
|
"type" TEXT NOT NULL,
|
|
"amount" DECIMAL(12,2) NOT NULL,
|
|
"currency" TEXT NOT NULL DEFAULT 'SAR',
|
|
"installments" INTEGER NOT NULL DEFAULT 1,
|
|
"monthlyAmount" DECIMAL(12,2),
|
|
"reason" TEXT,
|
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
|
"approvedBy" TEXT,
|
|
"approvedAt" TIMESTAMP(3),
|
|
"rejectedReason" TEXT,
|
|
"startDate" DATE,
|
|
"endDate" DATE,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "loans_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable: loan_installments
|
|
CREATE TABLE "loan_installments" (
|
|
"id" TEXT NOT NULL,
|
|
"loanId" TEXT NOT NULL,
|
|
"installmentNumber" INTEGER NOT NULL,
|
|
"dueDate" DATE NOT NULL,
|
|
"amount" DECIMAL(12,2) NOT NULL,
|
|
"paidDate" DATE,
|
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "loan_installments_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable: purchase_requests
|
|
CREATE TABLE "purchase_requests" (
|
|
"id" TEXT NOT NULL,
|
|
"requestNumber" TEXT NOT NULL,
|
|
"employeeId" TEXT NOT NULL,
|
|
"items" JSONB NOT NULL,
|
|
"totalAmount" DECIMAL(12,2),
|
|
"reason" TEXT,
|
|
"priority" TEXT NOT NULL DEFAULT 'NORMAL',
|
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
|
"approvedBy" TEXT,
|
|
"approvedAt" TIMESTAMP(3),
|
|
"rejectedReason" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "purchase_requests_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable: leave_entitlements
|
|
CREATE TABLE "leave_entitlements" (
|
|
"id" TEXT NOT NULL,
|
|
"employeeId" TEXT NOT NULL,
|
|
"year" INTEGER NOT NULL,
|
|
"leaveType" TEXT NOT NULL,
|
|
"totalDays" INTEGER NOT NULL DEFAULT 0,
|
|
"usedDays" INTEGER NOT NULL DEFAULT 0,
|
|
"carriedOver" INTEGER NOT NULL DEFAULT 0,
|
|
"notes" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "leave_entitlements_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable: employee_contracts
|
|
CREATE TABLE "employee_contracts" (
|
|
"id" TEXT NOT NULL,
|
|
"employeeId" TEXT NOT NULL,
|
|
"contractNumber" TEXT NOT NULL,
|
|
"type" TEXT NOT NULL,
|
|
"startDate" DATE NOT NULL,
|
|
"endDate" DATE,
|
|
"salary" DECIMAL(12,2) NOT NULL,
|
|
"currency" TEXT NOT NULL DEFAULT 'SAR',
|
|
"documentUrl" TEXT,
|
|
"status" TEXT NOT NULL DEFAULT 'ACTIVE',
|
|
"notes" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "employee_contracts_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "loans_loanNumber_key" ON "loans"("loanNumber");
|
|
CREATE INDEX "loans_employeeId_idx" ON "loans"("employeeId");
|
|
CREATE INDEX "loans_status_idx" ON "loans"("status");
|
|
|
|
CREATE UNIQUE INDEX "loan_installments_loanId_installmentNumber_key" ON "loan_installments"("loanId", "installmentNumber");
|
|
CREATE INDEX "loan_installments_loanId_idx" ON "loan_installments"("loanId");
|
|
|
|
CREATE UNIQUE INDEX "purchase_requests_requestNumber_key" ON "purchase_requests"("requestNumber");
|
|
CREATE INDEX "purchase_requests_employeeId_idx" ON "purchase_requests"("employeeId");
|
|
CREATE INDEX "purchase_requests_status_idx" ON "purchase_requests"("status");
|
|
|
|
CREATE UNIQUE INDEX "leave_entitlements_employeeId_year_leaveType_key" ON "leave_entitlements"("employeeId", "year", "leaveType");
|
|
CREATE INDEX "leave_entitlements_employeeId_idx" ON "leave_entitlements"("employeeId");
|
|
|
|
CREATE UNIQUE INDEX "employee_contracts_contractNumber_key" ON "employee_contracts"("contractNumber");
|
|
CREATE INDEX "employee_contracts_employeeId_idx" ON "employee_contracts"("employeeId");
|
|
CREATE INDEX "employee_contracts_status_idx" ON "employee_contracts"("status");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "loans" ADD CONSTRAINT "loans_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
ALTER TABLE "loan_installments" ADD CONSTRAINT "loan_installments_loanId_fkey" FOREIGN KEY ("loanId") REFERENCES "loans"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
ALTER TABLE "purchase_requests" ADD CONSTRAINT "purchase_requests_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
ALTER TABLE "leave_entitlements" ADD CONSTRAINT "leave_entitlements_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
ALTER TABLE "employee_contracts" ADD CONSTRAINT "employee_contracts_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|