Muscat University E-Procurement Platform
A bilingual, multi-tenant e-procurement platform built as a pitch demo for Muscat University, covering the full tender-to-payment lifecycle from sealed bidding through contracts, claims, and budget tracking.
Overview
This is a bilingual (Arabic RTL and English LTR), multi-tenant procurement platform built with Next.js 15 (App Router), Prisma 5, Postgres, and Auth.js v5. The repository's own README frames it explicitly as a pitch demo prepared for Muscat University, architected as a multi-tenant platform for every ministry, university, and large enterprise.
Problem
Public-sector and university procurement (tenders, supplier qualification, contract award, milestone billing, budget control) typically lives across disconnected paper processes or siloed legacy systems, with no single audit trail from requisition to payment and no easy way to onboard additional buyer organizations without new code.
Approach
The build models every buyer as an Organization in a shared multi-tenant schema, with suppliers kept platform-wide so they can bid across multiple tenant organizations. The domain is broken into clear stages: internal purchase requisitions consolidate into sealed-bid tenders, tenders resolve into awards, awards generate contracts with milestones, milestones trigger financial claims, and claims route through an approval chain to payment orders. A polymorphic AuditLog model and a generic Approval model are shared across contracts and claims rather than duplicated per workflow. The UI ships in Arabic (default, RTL) and English (LTR) via next-intl, with RTL-aware Tailwind utilities.
Architecture
- Next.js 15 App Router with
(public),(auth), and(dashboard)route groups separating marketing/tender-browsing pages, login/register, and the buyer/supplier/admin workspaces. - Prisma schema modeling Organization, Department, User, Supplier, PurchaseRequisition, Tender, Bid, Award, Contract, Milestone, Amendment, FinancialClaim, PaymentOrder, BudgetLine, BudgetTransfer, Approval, AuditLog, and Notification, roughly 20 models covering the full procurement lifecycle.
- Role-based access via a
UserRoleenum (Super Admin, Entity Admin, Procurement Director/Officer, Department Head, Requester, Evaluation Committee, Finance Officer, Approver, Auditor, Executive, Supplier Admin/User). - Auth.js v5 with a JWT session strategy; the implemented provider is credentials-based (email/password with bcrypt), with session and JWT callbacks carrying role, org, supplier, and locale onto the session object.
- A
GET /api/healthendpoint that reports app and DB liveness separately, returning a 200 with a "degraded" status on DB outage so a health probe can distinguish "app up, DB down" from a full outage. - Server actions per domain under
src/server/rather than a separate API layer for most data access. - A seed script that provisions a Muscat University tenant, departments, suppliers, and demo accounts across every role.
Tech stack
- Next.js 15 (App Router, Server Components, Server Actions), React 19, TypeScript (strict)
- Prisma 5 ORM against Postgres 16
- Auth.js v5 (NextAuth), bcryptjs for password hashing, Zod for input validation
- Tailwind CSS 3.4 with shadcn/ui (Radix UI) primitives, RTL-aware utility classes
- next-intl for Arabic/English i18n
- React Hook Form, Recharts for analytics charts, Sonner for toasts
- Deployment target: Railway (Nixpacks/
railway.json), with a multi-stage Dockerfile as an alternative container path
Engineering highlights
- Designed a single relational schema that supports adding a new buyer organization as a config and seed exercise rather than a code change, per the README's stated multi-tenant goal.
- Modeled the sealed-bid tender lifecycle explicitly in the schema (financial amount held encrypted until a reveal timestamp), separating technical and financial evaluation scoring per criterion.
- Built a generic, reusable
Approvalmodel shared by both contracts and financial claims instead of one-off approval tables per workflow. - Wrote a health-check endpoint that differentiates "degraded" (DB down, app up) from a hard failure, specifically to support platform-level uptime probes.
- Iterated through a deployment hardening pass visible in the commit history: moved schema push from build time to runtime for Docker safety, adjusted the install flow for the Docker build, and bumped Next.js to address a critical CVE.
- Delivered full bilingual coverage (Arabic RTL default locale, English LTR) across the entire app, including auth, dashboards, and marketing pages, via next-intl routing and middleware.
Want to dig deeper?
Ask my AI agent anything about how this was built, what tradeoffs I made, or how it could fit your team.
Ask my AI →// related projects
University Super App
Multi-tenant Flutter + Firebase platform for students, teachers, parents, and staff with role-based dashboards, offline support, and configurable per-university branding.
AI SEO Collection Optimizer
Autonomous SEO content engine that captures Lebanese organic search demand by generating high-confidence collection landing pages on a parallel VPS layer, grounded in Search Console signals, Shopify orders, and live catalog data, with a self-improving GSC measurement loop.
Marketing Intelligence Dashboard
Enterprise marketing operations platform (16 modules) covering campaigns, approvals, creative intake, compliance, and analytics, with an OpenAI-powered AI assistant via the Vercel AI SDK and one-click PPTX stakeholder reporting.