All Projects

Live

API

Kwara State Polytechnic Staff API

A comprehensive backend API for managing staff profiles, institutional hierarchy, appointments, and internal communications for Kwara State Polytechnic.

Role: Backend Lead


Node.jsMongoDBExpress.jsJWTRBACAgenda (cron)CloudinaryInstitutional
Problem Statement

The institution needed a centralized, secure, and structured system to manage a complex hierarchy of academic and non-academic staff, institutes, and departments, while securely handling administrative appointments, portal news, and internal events.

Target users: Polytechnic administrators, institute directors, heads of departments, and general staff members.

Project Walkthrough

When building the Kwara State Polytechnic Staff API, the primary challenge was digitizing a highly complex institutional hierarchy. The polytechnic needed a robust, centralized backend to manage thousands of staff members across various institutes, departments, and administrative roles. I designed a layered Node.js/Express architecture, focusing heavily on strict data modeling with Mongoose to accurately represent the intricate web of academic designations—from Chief Lecturers to Institute Directors and HODs.

One of the most critical engineering decisions I made was how to handle role-specific data. Rather than polluting the core Staff model with fields only relevant to specific leadership roles, I created dedicated models (like Director and Hod) that are dynamically referenced based on a staff member's current appointment. This kept the database normalized and the business logic incredibly clean. I also implemented a robust JWT-based authentication system with refresh token rotation, alongside custom Express middlewares that strictly enforce role-based access control down to specific appointment types.

Beyond core CRUD functionality, the system needed to be resilient and efficient at scale. I integrated Agenda for MongoDB-backed cron jobs to handle automated state changes, built a custom response utility middleware to ensure API responses were 100% consistent, and engineered a batch-processing bulk onboarding script capable of safely migrating large JSON datasets into the database.


Tech Stack

Languages

JavaScript (Node.js)

Frameworks

Express.js

Databases

MongoDB (Mongoose)

Cloud & Infrastructure

Vercel (Frontend portals)MongoDB Atlas

Dev Tools

NodemonESLintPrettierMorganSentry (Error tracking)Agenda (cron jobs)

Authentication

JWT (JSON Web Tokens) with refresh token rotation, bcrypt for password hashing, and role/appointment-based access control.

Third-Party APIs & Integrations

Cloudinary (image/avatar storage)

Paystack (payment initialization and account resolution)

Google APIs (SMTP/Email services)


System Architecture

Architecture Pattern

MVC-inspired layered architecture (Routes -> Middlewares -> Controllers -> Services -> Models).

Request Data Flow

Client Request → Helmet/CORS Security → Route Definitions → Joi Payload Validation → Auth/RBAC Middleware → Controller Logic → Mongoose Models → Unified Custom Response Utility.

Key Engineering Decisions

1. Extracted all response formatting into a custom `responseUtilities` middleware for strict API shape consistency. 2. Used `express-async-errors` to completely eliminate repetitive try/catch blocks in controllers. 3. Abstracted all errors into custom Error classes mapped to a centralized HTTP Error Codes dictionary. 4. Utilized `agenda` and `agendash` for robust, database-backed background job scheduling.

Database Design

Highly relational schema design over MongoDB. The core `Staff` collection utilizes strict enums for designations (e.g., 'Chief Lecturer', 'Technologist II') and departments. Role-specific metadata is normalized into separate collections (`Director`, `Hod`) that are referenced by the `Staff` document to prevent schema pollution. Other key collections include `Admin`, `NewsEvents`, `Gallery`, and `Job`.

Module Structure

api/v1/routes (API endpoint definitions)api/v1/controllers (Core business logic)api/v1/models (Mongoose schemas)api/v1/services (External integrations like Paystack and Cloudinary)api/v1/validators (Joi schema validations)api/shared/middlewares (Auth, Error handling, and Response Utilities)jobs (Agenda cron configurations)

Key Features & Implementation

Hierarchical Authentication & Authorization

Role-based access control that distinguishes between general Staff and Admins, with deeper checks for specific institutional appointments.

How it was built

Implemented via custom middlewares and JWT. Beyond standard token validation, controllers actively check `req.loggedInAccount.appointment` to restrict actions. For example, only a staff member with the 'Head of Department' enum can update HOD-specific data.

Bulk Staff Onboarding

Allows administrators to quickly import large batches of staff members from JSON data exports.

How it was built

Engineered a memory-efficient batch processing script in the auth controller. It reads data, slices it into chunks of 50, strictly validates/formats inputs, skips existing emails/IDs, and uses `Staff.insertMany` to write to the DB. It returns a detailed report of created vs. skipped users.

Institutional Role Management

Manages complex relationships between Staff, Directors, and HODs based on their current academic or administrative appointment.

How it was built

Used Mongoose references. When a staff member is assigned a Director or HOD role, dedicated records are created in those respective collections and their ObjectIDs are attached to the core `Staff` document. This keeps role-specific data (like 'welcomeAddress' or 'vision') separate from standard staff data.

Automated Background Jobs

Automatically expires old jobs or appointments without manual administrative intervention.

How it was built

Integrated `agenda` to run MongoDB-backed cron tasks. The `activate-cron.js` script queries for active jobs with a `completedDate` in the past, updates their status to 'expired', and saves them.


Challenges & Engineering Decisions

Designing the `Staff` schema was a significant challenge due to the complex institutional hierarchy. Kwara State Polytechnic has dozens of designations (from Chief Lecturer to Assistant Lecturer), diverse departments, institutes, and specific administrative appointments (Rector, Registrar, HOD, Director). I solved this by using strict Mongoose enums and referencing separate `Director` and `Hod` models for appointment-specific metadata rather than polluting the core `Staff` schema.

Handling bulk staff onboarding was another technical hurdle. Reading and writing thousands of records at once risked memory bloat and database timeouts. I implemented a `formStaffRegisterBulk` function that processes large JSON arrays in batches (e.g., 50 at a time) using `Staff.insertMany`, gracefully skipping existing records or invalid entries.

To maintain code cleanliness across a large controller footprint, I integrated `express-async-errors` and a centralized error handling middleware. This allowed me to throw custom error classes directly from business logic without writing a single try-catch block in the controllers.


API Documentation

API Route Namespaces

/api/v1/auth/api/v1/admins/api/v1/staffs/api/v1/resumes/api/v1/gallery/api/v1/appointment/api/v1/department/api/v1/institute/api/v1/notifications/api/v1/newsevents