Planvera — Workforce Scheduling & Operations Platform
A full-stack operations platform for building and managing complex monthly workforce schedules — initially designed, built, and deployed for a senior security services firm, and architected to be shaped and adapted to any project-driven business.
Scheduling complex teams is harder than it looks
Managing large security teams across dynamic, shift-based projects doesn't fit neatly into any off-the-shelf tool. Generic scheduling software assumes fixed roles and predictable patterns — neither of which match the reality of a senior security project manager juggling multi-site deployments, rotating rosters, and monthly planning cycles.
Planvera was built to close that gap. The spec came directly from live operational pain points, making it a tool shaped by real constraints rather than assumptions.
Risk-based, not coverage-based
Testing is my primary discipline, so on Planvera I treated it as a budgeting problem before a coverage one: every test carries a maintenance cost, and the question is which tests buy the most risk reduction per unit of effort. Investment went heavy on the schedule engine — a greedy assignment algorithm where one off-by-one strands a worker mid-shift — the JWT auth flow, and the Google Calendar sync contract. Pytest + httpx exercise the FastAPI endpoints against a real Postgres fixture rather than mocks, because the bugs that actually cost money in scheduling are the ones a mocked test passes and a live publish fails.
The highest-ROI surface is the schedule-publish path: one user action touches the database, queues emails, fires background tasks, and writes to external calendars. Everything that flows through it is covered end-to-end. In a team setting, visual regression and exhaustive role-permission sweeps are the right work to hand to a junior tester with a structured checklist while I keep the engine, data, and integration layers — and UAT was delegated by design, with the senior operations manager running live trial shifts and surfacing edge cases no spec could have predicted.
Architecture choices made deliberately small
Planvera serves a single security operations team — under a thousand active users — so the architecture was sized to that reality rather than to a hypothetical scale. A single AWS EC2 instance running Docker Compose hosts the full stack: FastAPI behind Gunicorn, the Vite build served by Nginx as a static site, and PostgreSQL co-located on the same box. ECS, ALB, CloudFront, and S3 were all considered and rejected as premature for the load profile.
Async work — schedule-publish emails, Google Calendar sync, invoice delivery — runs through
FastAPI’s built-in BackgroundTasks instead of Celery. No Redis broker, no
worker fleet to operate. PDF generation uses WeasyPrint server-side so invoice layouts stay
identical regardless of the client’s browser. FullCalendar was chosen over a hand-rolled
grid because the schedule view is the product, and a battle-tested scheduler with native
Google Calendar bindings was worth more than the flexibility of building from scratch.
State management splits cleanly: TanStack Query owns server data and cache invalidation, Zustand holds the small set of truly-client concerns (active user, current role, UI flags). Pydantic schemas on the FastAPI side and Zod schemas on the React side describe the same contracts in both languages, so a backend change surfaces as a type error on the frontend rather than as a runtime bug in production.
What the platform does
Monthly Schedule Builder
Create and manage complex shift patterns across dynamic project timelines.
Worker Management
Track roles, certifications, availability, and assignment history per employee.
Project & Site Management
Scope and manage multi-site, multi-role projects with live status tracking.
Reporting & Exports
Export clean schedule summaries and operational reports from within the platform.
Multi-Business Ready
Designed to be adapted and white-labeled for different businesses and industries.
Secure Admin System
Role-based access and secure admin controls built for operational environments.
See it in action
Platform views
How it’s built
A typed full stack from database to UI — React on the front, FastAPI on the back, PostgreSQL underneath, all on a single AWS EC2 host orchestrated with Docker Compose.
What I worked around
No co-engineer, no dedicated QA, and a live operations team using earlier builds in real shifts — which meant every release had to land cleanly the first time, because a broken schedule view on a Sunday night isn’t a bug report, it’s a missed deployment of security personnel. The spec also kept moving: real edge cases (overnight shifts crossing billing periods, partial-day re-assignments, last-minute substitutions) surfaced from the floor faster than they could be designed for on paper.
Infrastructure was deliberately constrained — a single EC2 host instead of a managed container platform — which kept costs flat and the system understandable end to end, but meant zero-downtime deploys, backups, and SSL renewal all had to be solved with simple tools rather than relied on as managed services.
How I built it
Planvera is a solo project in every sense — I designed the system architecture, built the full stack, planned the feature set, and managed deployment to AWS. The feedback loop came directly from the end user: a senior security firm project manager running live trial operations, surfacing real edge cases and workflow gaps in real time.
Sole engineer, designer & planner. Spec-to-deployment ownership, with live trial runs inside a real security operations team. Designed with adaptation in mind — the same core platform can be configured and deployed for different businesses and industries.
What I’d do differently
I’d treat the schedule engine as its own deliberately-bounded service from day one rather than letting it grow inside the FastAPI app. The greedy scheduler is the part of the system most likely to need real iteration — new constraints, fairness rules, re-assignment heuristics — and isolating it behind a stable interface would have made rewrites cheaper. I’d also wire a small synthetic-monitoring layer earlier; running on a single EC2 means an unhealthy container is a real outage, and a one-minute check pinging the schedule API would have caught a couple of issues before users did.