National Talent Portal
A multi-tenant job portal for Eastern Caribbean governments, connecting candidates, employers, and ministry staff from one shared codebase across web and native mobile.
Overview
National Talent Portal is a job-matching platform built for governments across the Eastern Caribbean, connecting three very different users — candidates, employers, and ministry staff — on one product, with each government running its own independently configured instance.
In development
Status
Web + iOS + Android
Platforms
Multi-tenant
Deployment
one instance per government
90+
Requirements Tracked
individually, against MVP/V1/V2 tiers
Problem
Public employment services in the Caribbean region typically run on a different system for each of the 7 member governments, none of which share users, data, or features. The brief was to build one flexible product: each government could run its own branded version, with its own roles and data, without copying the code every time a new country joins.
Technical Architecture
To make sure one government can never accidentally see another's data, multi-tenancy is
built into the database structure itself, not just enforced as an application rule that
could be bypassed. The backend runs NestJS on MongoDB, with a single Expo and React
Native codebase producing both the native mobile app and the web build. Every
collection carries a required, indexed tenantId, so a query that omits it simply has
no way to return another government's data.
@Schema({ collection: 'jobs', timestamps: true })
export class Job {
@Prop({ type: Types.ObjectId, required: true, index: true })
tenantId: Types.ObjectId
@Prop({ type: Types.ObjectId, required: true })
orgId: Types.ObjectId
@Prop({ required: true, enum: ['draft', 'pending_review', 'published', 'closed'] })
status: string
}Each tenant can also be configured for a shared or dedicated deployment, depending on a government's isolation requirements, without a different codebase.
Implementation

Candidates and Employers
Candidates browse and apply for jobs from the native app or the web build of the same Expo codebase. Employers post vacancies and review applications from a separate dashboard. Resume and company logo uploads go through S3 with CloudFront in front of them, rather than serving files directly from the API.
Shortly after that upload path shipped, deleting a resume or replacing a logo left the old file behind in S3 instead of being cleaned up. The fix was straightforward — delete the previous object as part of the same request that uploads the new one — but it's the kind of gap that only shows up once real files are actually being replaced, not during initial testing.
Access and Permissions
Getting into the system is locked down at every level, especially for government staff handling sensitive employment data. Authentication runs through Firebase for Google sign-in plus a signed access token (JWT) for the API itself. Staff accounts add TOTP-based multi-factor authentication — the same six-digit codes generated by an authenticator app — and repeated failed logins trigger a lockout rather than allowing unlimited attempts. Roles, organisation memberships, and a permission catalog sit behind every request, and each tenant can turn individual features on or off independently of the others.
Build Tradeoffs
Search runs directly against MongoDB rather than through a dedicated search engine. That's enough for the data volume a per-government job portal actually has; a dedicated search layer is the kind of thing to add once real usage shows it's needed, not before.
There's no background job queue yet, so work like outbound notification email currently happens inline rather than through a worker. It's on the list, and it moves up once traffic makes inline sending a problem.
Technical Challenges
Security hardening in the open. Session revocation, brute-force lockout, and password reset didn't all land at once — they were tracked as explicit gaps and closed one at a time as the product moved toward a pilot-ready state. For a platform handling government employment data, treating auth gaps as tracked work rather than assuming they're solved mattered more than shipping fast.
No CI test gate yet. There's no automated lint/test workflow running on every push. Deploy and mobile-build workflows exist, but not a verification gate. Instead, a pre-push hook runs the same checks locally before code leaves a developer's machine. It's a real gap, but it's tracked and sitting in the backlog, not something swept under the rug.
Outcome
The multi-tenant foundation, authentication, roles, and the core candidate and employer flows are built and working today. Requirements are tracked individually against MVP, V1, and V2 tiers, with foundational access and portal features complete and richer workflow features still being built out.