← Selected Work

IR Connect — International Relations MIS

A system built around the role — not around the data.

Role
Sole developer and admin — database, backend, frontend, auth, deployment
Timeline
~12 weeks, shipped Q3 2025
Stack
React 18 / TypeScript · Node.js / Express / Prisma · PostgreSQL · Google OAuth · Windows Server + IIS + Cloudflare Tunnel
01

The problem

The International Relations team at The Next manages relationships with 100+ universities across 8+ countries — contracts, MoUs, commission schedules, territory assignments, partnership stages, document trails. Before IR Connect, all of it ran on shared spreadsheets and email threads.

It worked while the rows were short. Once the data grew, the spreadsheet stopped being a system and started being a liability. Columns drifted. Colour codes lost their meaning. Every new officer inherited the sheet with no context for what anything meant. Documents lived in individual inboxes and personal desktops.

The real cost wasn't the messiness. It was that contract expiries slipped. With 100+ contracts in flight, a spreadsheet is a passive thing. It doesn't tell you something needs attention. You have to remember to go look — and when something gets overlooked, suddenly a renewal is overdue and the team is scrambling to save a partnership the week before it lapses.

02

The insight

I spent time with the IR team before writing anything. The thing I kept hearing — without anyone saying it directly — is that IR officers don't think in database tables. They think in tasks.

“Which contracts are expiring this quarter?” “Which Sri Lankan universities haven't been contacted in three months?” “Where's the latest MoU for Coventry?” Every question starts from what the person is trying to do, not from where the data lives.

“Design the interface around the day, not the data model. One tab per task, not one tab per table.”

That reframe changed everything downstream. The data model could stay clean — twelve normalised relational tables, foreign keys, proper constraints. But the UI sitting on top of it would ignore that structure entirely and organise itself around the seven things IR officers actually do each day.

03

The approach

A seven-tab tablet-first workspace. Twelve relational tables underneath. About fifty React components on top. Every tab is a task, not a table.

IR ConnectDashboardUniversitiesPortalContractsFollow-upsContactsSettingsActive contracts124 total · 8 countries33 contracts need attention this weekKingston (expires in 6 days) · Coventry (no contact 90d) · Monash (MoU pending)Review →University of LeedsUKExpires2026-09-14ActiveOpen →Coventry UniversityUKExpires2026-07-02ActiveOpen →Monash UniversityAustraliaExpires2026-12-01PendingOpen →University of WaikatoNew ZealandExpires2027-03-22ActiveOpen →Humber CollegeCanadaExpires2026-06-10ExpiresOpen →Asia Pacific UniversityMalaysiaExpires2027-01-05ActiveOpen →
Seven tabs. One per task. A small compass in the corner keeps an eye on what needs attention.

Dashboard opens on what needs attention — this week's expiring contracts, overdue follow-ups, new enquiries. Universities is the partnership encyclopedia — country, programs, contacts, tier. Portal handles student-facing submissions and the IR side of applications. Contracts is the document-and-lifecycle tab — every MoU, commission schedule, and renewal timeline lives here. Follow-ups is a task queue. Contacts is the university-side people directory. Settings is where roles, territories, and reminder cadences get configured.

Tablet-first because IR officers don't live at a desk. They're in partnership meetings, at recruitment fairs, in video calls with university counterparts — and they need to pull up a contract or log a conversation without opening a laptop. Layout breakpoints start at tablet widths and scale up gracefully on desktop.

Contract expiry tracking runs on a cron that checks daily. Contracts at 90 / 60 / 30 days from expiry surface in the Dashboard's attention banner and generate in-app notifications. Territory tagging lets officers filter by region with one tap. Three-tier RBAC separates admin, officer, and viewer. Google OAuth because the team was already on Workspace.

NSWE

And a small compass in the corner

With 100+ contracts in motion, the system has more to notice than any one person can keep track of. IR Connect has a small compass mascot that lives in the corner of every tab. It reacts to what's happening — happy when everything's on track, concerned when contracts need attention, celebratory when a big save goes through. It has expressions, it tracks the cursor, it speaks up when something's overdue.

It started as a joke. It's the thing people comment on first.

Built in pure SVG + CSS animations. Five mood states, cursor-tracking pupils and needle, time-of-day accessories, idle behaviour, and proactive tips about items that need attention.

04

What it changed

The headline result: nothing gets overlooked anymore. The attention-banner system means contracts that need action surface days before they're urgent — not the week they're about to lapse. The week-before-expiry scramble is gone. Officers notice things in order of importance instead of in order of who shouted last.

New officers onboard in hours, not weeks. The UI teaches them what IR work actually consists of — seven task shapes — rather than dropping them into a blank spreadsheet and hoping they figure out which column means what.

The whole history of every partnership — contracts, contacts, conversations, documents — lives in one place and can be pulled up on a tablet during a meeting. The IR team stopped being the custodians of a fragile spreadsheet and started being the owners of a system they trust.

100+
active contracts managed in one system
8+
countries, one tablet-friendly workspace
0
last-minute expiry scrambles since launch
05

Under the hood

Frontend
React 18 + TypeScript + Vite. About 50 components organised by tab. Tailwind for utility styling. Tablet-first breakpoints. Client-side state with React Context.
Backend
Node.js + Express, REST API. Prisma ORM against PostgreSQL. Twelve relational tables with proper foreign-key constraints, cascading rules, and timestamptz columns for timezone-safe expiry logic.
Auth & RBAC
Google OAuth 2.0 (team was already on Workspace). Three-tier access: admin manages the system, officers work in their assigned territories, viewers get read-only dashboards.
Notifications
Cron job runs daily, checks contracts at 90 / 60 / 30 day expiry thresholds, surfaces them in the Dashboard attention banner and in per-user notification lists. Configurable cadence per role.
Compass mascot
Pure SVG + CSS animations. Mood state machine with five expressions, cursor-tracked pupils and needle via rAF, time-of-day accessories, speech bubbles, and idle tips that surface real data (expiring contracts, items needing attention). Built to be loved, not tolerated.
Deployment
Windows Server 2019. IIS reverse-proxy fronting a Node process managed by PM2. Cloudflare Tunnel for public egress. Coexists on the same server as Student Analytics and Lead Dashboard.
What I'd do differently
The attention banner started as one banner showing top three alerts. It should have been a feed from day one — users asked for one within a week. Ship the feed first next time.