
Healthcare · Healthcare Ireland Group
Problem
A major Irish healthcare group needed a unified platform to run patient management, scheduling, clinical notes, billing, and analytics across multiple branches and departments - with real-time data synchronization and AI-assisted clinical documentation. Existing tools were fragmented, slow, and forced clinicians to context-switch between disconnected systems.
Your scope
I architected the frontend end to end - composition, state, routing, real-time integration, data-table system, and the shared design language - and contributed key modules on the NestJS backend including the AI agent service for SOAP-note generation. Honest framing: this was a team build; my slice was the frontend architecture plus the AI module.
System architecture
Client-server with persistent WebSocket channels for real-time sync. The frontend (Vite 7, React 19, TanStack Router) communicates with a NestJS 11 backend through REST endpoints and Socket.io. The backend implements a three-tier multi-tenant hierarchy (Organization → Branch → Department) with tenant-scoped data isolation enforced at the Prisma layer. Background processing runs through BullMQ; file storage uses MinIO (S3-compatible).
Key decisions
- Tenant isolation in Prisma middleware, not application code. Considered enforcing tenant scope per-query in service code; rejected - too easy to miss one branch and leak data across organizations. Centralised in middleware so isolation can't be forgotten.
- Socket.io rooms mapped 1:1 to tenant hierarchy. Considered a broadcast-and-filter approach; rejected - too noisy for clinicians with hundreds of concurrent connections. Room-based broadcasting puts the filter at the source.
- TanStack Table with server-side sorting/filtering/pagination, not client-side. Patient rosters routinely run into tens of thousands of rows; client-side filtering melts laptops. Server-side keeps the UI responsive at any scale.
Engineering challenges
- Multi-tenant isolation at the ORM layer without sacrificing query performance.
- Real-time synchronization for clinical data where consistency matters and stale UI is unacceptable.
- Encapsulating LLM calls (SOAP-note generation from audio) inside the NestJS module system with structured output validation and audit logging.
Solutions
- Tenant-scoped Prisma middleware injects
organizationId/branchIdcontext into every query - invisible to service code, impossible to miss. - Socket.io room-based architecture mapped to tenant hierarchy for targeted real-time broadcasts.
- NestJS agent module that encapsulates LLM calls with Zod-validated structured output and full audit logging - type-safe AI inside a typed backend.
- Comprehensive Winston logging with daily rotation for regulatory compliance.
What I'd change
Stack
- Frontend - React 19, Vite 7, TanStack Router/Query/Table/Form, Zustand, Socket.io client
- Backend - NestJS 11, Prisma 6, PostgreSQL, BullMQ, Winston, Swagger
- Infra & AI - MinIO (S3-compatible), Passport.js/JWT, Zod-validated structured LLM output
Links
- Client: healthcareirelandgroup.com