There is a moment when a process outgrows the tools it started in. The shared sheet nobody dares reorder. The inbox that is really a work queue. The report somebody rebuilds by hand every Monday morning. A portal is what you build at that moment: a real system, with accounts, permissions, a history and an API. We build those.
Built in your accounts. Handed over with the keys and the runbook.
Almost every internal system we are asked for is some combination of these four. Naming them early is what stops a build from turning into a wishlist.
Work arrives, someone owns it, it moves through defined states, and it cannot skip one by accident. Most "we need a portal" conversations are this, described in other words.
Who changed what, when, and what it was before. Retrofitting an audit trail after an incident is one of the more expensive things a business can be asked to do.
A dashboard that answers a question a person actually has. If nobody would open it unprompted, it is a report, and a report is cheaper than a portal.
The portal that only has a UI becomes the bottleneck the spreadsheet used to be. Every portal we build is usable by software from day one.
These are the items that decide whether a portal is still trusted in year three. They are also the items most commonly discovered after go-live, when they are far more expensive.
We are not attached to a stack, and we will not sell you a rewrite into whatever we most recently enjoyed. This is what we have shipped and currently support. If your team already runs something else well, that is usually the right answer.
| Layer | What we run in production |
|---|---|
| Application | Laravel / PHP, Django / Python, NestJS / TypeScript |
| Interface | Server-rendered templates where that is enough; React and React Native Web where a shared component library earns its keep |
| Data | MySQL and PostgreSQL, with migrations that are reviewed like code |
| Identity | SAML 2.0 and OIDC against your provider; token auth for machine callers |
| Infrastructure | AWS, in your accounts: object storage, queues with a failover path, and provisioning scripts committed alongside the application |
| Observability | Grafana dashboards, Prometheus metrics endpoints, alerting on state transitions |
The question behind most portal procurement is never asked out loud: what happens when these people are gone? It is a fair question and it deserves an artefact rather than a promise.
Deleting our local configuration is not the same as closing a route. Only removing the authorised key on your side does that. We tell you what to remove, and you confirm it is gone.
Deploy paths, environments, which routes reach which environment, and what a given document is deliberately not about. Written for a reader who had no part in how the engagement ended.
Not a description of how it was set up. You get the numbered scripts that set it up, committed with the code. The estate can be rebuilt rather than archaeologically reconstructed.
If a previous supplier left badly, this is a fixed-price engagement in its own right. It is also the cheapest way to see how we work before you commit to anything larger.
Tell us what the work is and where it currently lives. The screens fall out of that conversation. Sometimes the honest answer is that you need a report, not a portal.
We reply within one business day.
The portals described on this page are systems TechJoy built and operates. No client is named. We do not publish improvement percentages we have not measured, and every capability listed here is one you can ask us to show you.