01 The problem
A travel-industry operations team planned shifts by hand in spreadsheets. Rules about rest periods, qualifications, holidays and fairness lived in people's heads, so every plan took hours and broke whenever someone was unavailable.
02 What it does
- Generates schedules automatically with Google OR-Tools CP-SAT, encoding hard rules and soft preferences as constraints.
- Admin web app for planners: staff, availability, rules, plan review and manual adjustments.
- Native Flutter app for employees to see their shifts and submit availability.
- Exports to XLSX, PDF and iCal; Czech public holidays handled automatically.
03 Architecture
- 01 MobileFlutter app with a generated Dart (dio) API client
- 02 AdminNext.js admin in a monorepo with a shared API client package
- 03 APIFastAPI, SQLAlchemy 2, Argon2 + Google sign-in
- 04 SolverOR-Tools CP-SAT model as an isolated, tested module
- 05 DataPostgreSQL with Alembic migrations
- 06 OpsDocker + Compose deployment, separate QA review image
04 Stack
FastAPIPython 3.12OR-Tools CP-SATPostgreSQLSQLAlchemyAlembicNext.jsFlutterDocker
05 How I worked with AI
The solver constraints were specified by hand first, as plain-language rules with examples, then implemented by agents one constraint at a time, each with its own test. The OpenAPI schema drives code generation for the Dart client, so frontend agents work against a contract instead of guessing.
06 What is verified
- CP-SAT solver implemented with a dedicated solver test suite.
- Backend: 23 pytest files; frontend monorepo: 29 test files.
- 12 Alembic migrations, Docker images and a Compose deployment.
07 Honest notes
- Built for a specific client; the name is withheld. No CI pipeline yet, tests run locally.