CRI Hub — microservices business platform with SSO
Seven .NET services, an offline-capable React PWA and ESP32 access control.
- .NET 8
- PostgreSQL
- React PWA
- TypeScript
- API Gateway
- Docker
- GitHub Actions
- ESP32
The problem
A volunteer organisation was running shifts, vehicles, member records and communications on spreadsheets and messaging groups. It needed a single system, with one shared identity across several applications, usable from a phone in the middle of a callout — which means usable offline.
Outcome
Seven services running behind a gateway, two distinct frontends (operators and administrators) sharing one design system, centralised authentication and automated deployment on every push.
The architecture
The system is split by responsibility, not by development convenience:
| Service | Role |
|---|---|
sso |
Single identity: registration, login, token issuance and renewal |
api-gateway |
One entry point: routing, rate limiting, request logging |
cri-hub-be |
Application domain: shifts, vehicles, member records, permissions |
notification-be |
Push notifications and outbound communication |
cri-fe |
React PWA for operators |
admin-cri |
Administration panel |
cri-ui |
Design system shared by both frontends |
Services talk to each other over Docker’s internal network; only the gateway is exposed. That is a security decision before it is an architectural one: a service with no public address has no public attack surface.
The decisions that mattered
Real Single Sign-On, not duplicated login. Authentication lives in a separate service that issues signed tokens; every other service verifies them without ever seeing a password. Adding an application to the system means teaching it to verify a token, not to manage users.
Offline as a requirement, not a finishing touch. The frontend is a Progressive Web App: the people using it are usually moving, with patchy connectivity. It installs on the phone, keeps working without a network, and syncs when one comes back.
Push notifications instead of group chats. An alert that arrives as a system notification gets read; a message in a group chat gets lost.
A shared design system. Both frontends consume the same component library, so the admin panel and the operator app do not drift apart — there is no second copy of the buttons to forget.
ESP32 access control
The project includes a hardware module built on an ESP32 that unlocks physical access by validating the same identities as the web system. The interesting part is not the microcontroller: it is that the door and the web application share a single source of truth about who is allowed in.
Deployment
Each repository has its own GitHub Actions pipeline on a self-hosted runner. A push to main rebuilds
that image and restarts only the affected service. Nginx sits in front of everything, with Let’s
Encrypt certificates and automatic renewal.