OPSY, security operations in real time

About the project
OPSY replaces scattered check-ins and paper logs with one dashboard: where every guard is, what shift they are on, and what just happened in the field, updated as it happens.
It sells as a white-label product, so a security company puts its own name, colours and domain on the app its guards use.
We built five pieces that shipped together: the guard mobile app, the supervisor dashboard, the backend behind both, the marketing site and the content platform.
Services
Tech stack
The guard app runs Angular and Ionic over Capacitor for iOS and Android, with NGXS for state. The supervisor dashboard is React on Vite with Tailwind CSS and an Apollo client for live updates.
Underneath: NestJS with PostgreSQL and TypeORM behind a GraphQL API, Redis with BullMQ for background jobs, AWS S3 and SES, Firebase Cloud Messaging for push and Stripe for billing, all in Docker. The marketing site is Next.js, with content on Ghost.
The next version of the guard app moves to React Native and Expo.
How the work went
Five pieces that had to launch as one product, not as five releases.
Scoping the operation, not the screens
We started from a shift: who is on it, where they have to be, what happens when something goes wrong and who needs to know within a minute. That set the data model and the order of the build.
A multi-tenant backend first
NestJS, PostgreSQL and TypeORM behind a GraphQL API, with tenants separated from the first migration. White-label only works if a new client is configuration rather than a fork, so the hard part was decided before any screen existed.
The guard app
Angular and Ionic over Capacitor, with check-ins and emergency alerts kept to a couple of taps. Field staff do not sit through training, so the app had to be obvious at install and usable with one hand free.
The supervisor dashboard
React on Vite with an Apollo client, built around a live view of the shift: positions, patrol progress and incidents as they arrive, with the reports an audit asks for afterwards.
Billing, alerts and go-live
Stripe for the trial-to-paid flow, SES for compliance and incident mail, Firebase Cloud Messaging for push and Docker for deployment: the pieces that let a new branded client go live on the platform.
The parts that decided the platform
Security companies running on spreadsheets and radio calls lose sight of the work the moment a guard leaves the office. The platform had to close that gap without asking anyone to adopt a new brand.
Problem
Showing supervisors what is happening right now
Solution
A dashboard that refreshes when asked is not much better than a phone call. Apollo GraphQL subscriptions push guard location, shift state and incidents from the NestJS backend to the dashboard as they happen, so the screen is the operation rather than a report about it.
Problem
A guard working from the first shift
Solution
The guard app keeps check-ins and emergency alerts to a couple of taps, with state handled by NGXS so the screen is right even on a slow phone. The path from install to first shift is a walkthrough, not a course.
Problem
Incidents that survive a bad signal
Solution
Reports are filed from parking lots and stairwells, not from offices. Incident data and photos queue on the device and upload through BullMQ jobs on Redis once the signal returns, landing in S3 without the guard retrying anything.
Problem
A new branded client as configuration, not a project
Solution
Logo, colours, domain and login belong to the client; the platform underneath does not change. A multi-tenant backend deployed through Docker turns a new security company into a configuration task instead of a fork.
Problem
Billing and alerts without extra headcount
Solution
Stripe runs the self-serve trial-to-paid flow, SES carries compliance and incident mail, and Firebase Cloud Messaging puts time-sensitive alerts on a guard's phone. Nobody has to chase any of it by hand.
What the platform does
The feature set behind a shift: planning it, watching it happen and proving afterwards that it did.
Workforce management
Guards, supervisors and dispatchers in one place, with profiles and certifications.
Patrol management
Rounds, checkpoints and route progress, digitised instead of written on paper.
Live monitoring
Active shifts, guard positions and patrol state on one screen as they change.
GPS verification
Attendance and checkpoints confirmed by location, not by someone's word.
Shift handoff
Early-exit requests and handovers with a full audit trail, so coverage never drops.
Incident reporting
Reports from the field with photos, notes, category and timestamp.
Automated reports
PDF and Excel summaries of incidents, patrols and shifts, generated rather than typed.
Alerts
Missed patrols, early endings and new incidents pushed to whoever has to act.
Multi-site
Several clients, properties and locations run from a single dashboard.
Analytics
Workforce performance, patrol compliance and incident trends over time.
White-label
The client's logo, colours, domain and login on the app their guards use.
Mobile tools
Shifts, patrols and reports on iOS and Android, usable where the signal is not.
Where it landed
The dashboard, the guard app and the backend shipped as one product, which is the only way a live operations tool is any use: a shift either shows up on the screen while it happens, or the screen is just another report.
Each new security company runs on the same platform under its own brand, so a launch is configuration rather than a new build.
Building something in this shape? Tell us about it, see how we build SaaS products, or get a range in two minutes.
Questions about this build
Who built OPSY?
2muchcoffee built OPSY, a white-label operations platform for security companies: the guard mobile app, the live supervisor dashboard, the multi-tenant backend, the marketing site and the content platform.
What is OPSY built with?
The guard app is Angular and Ionic over Capacitor for iOS and Android. The supervisor dashboard is React on Vite with Apollo GraphQL subscriptions for live updates. The backend is NestJS with PostgreSQL, TypeORM, Redis and BullMQ, deployed in Docker, with Stripe for billing and Firebase Cloud Messaging for push.


