/projects/ulbra-admin
← All projectsUlbra Admin
The numbers the board runs the university on.
Head of Technology — design & implementation · Aug 2026 – Current
Overview
The dashboards the presidency and the board use to check the university’s numbers. A .NET 10 API and a React 19 front end that read two systems neither of them owns: prospect data from the CRM, and confirmed enrollment from the legacy Oracle platform through a typed HTTP client rather than a database connection.
What I did
I built it end to end — the API, the integrations, the front end and the deployment.
- The read-only integration with the CRM’s datastore.
- The typed client that fronts the legacy enrollment system.
- The dashboards themselves and the React front end.
- Authentication and the Swarm deployment.
The problem
The people accountable for the university’s numbers could not see them without asking. Enrollment lived in a legacy platform, prospects lived in the CRM, and reconciling the two meant a request to IT and a spreadsheet that was stale by the time it arrived. The question being asked was not complicated; the answer was just never at hand.
Architecture
Two sources, neither of them owned by this system, behind one API.
- CRM storeProspect and pipeline data, read-only.
- Enrollment APIA typed HTTP client over the legacy platform — never the database directly.
- Admin APIJoins the two and serves the dashboards.
- DashboardsWhat the board actually looks at.
What it does
- Prospect and enrollment figures side by side, from the two systems that own them.
- Reads the CRM’s datastore strictly read-only — the dashboards can never corrupt the system of record.
- Single sign-on, so access follows the accounts the university already manages.
- The same design tokens as the service desk, so six systems read as one platform.
Engineering decisions
Deliberately the simplest architecture in the group
Single project, no modules, no DDD — written into the codebase as a rule, in a house whose service desk is a modular monolith. This system owns almost no domain: it reads two other systems and draws charts. Giving it aggregates and bounded contexts would be ceremony around a query. The architecture is chosen per problem, and the honest answer here was "less".
Never query the legacy database directly
Enrollment could have been read straight from the legacy platform’s database, and it would have been faster to write. It goes through a typed API instead, so the definition of "an enrolled student" lives in one place rather than being reimplemented in a SQL query — and so the day the legacy platform is replaced, one client changes rather than every consumer of it.
Read-only by construction
The connection to the CRM’s datastore is read-only, not by convention but by the credentials it holds. A reporting system that can write to the system of record is one bug away from corrupting the numbers it exists to report.