Solver-backed scheduling for clinic operations.

A working system for generating weekly technician schedules across clinics, reviewing draft runs, filling gaps, and keeping an audit trail of schedule decisions.

The problem was operational, not just mathematical.

The hard part was not drawing a calendar. The system had to encode rules, constraints, approvals, disruptions, and handoffs in a way clinic staff could trust and inspect.

Weekly schedules pair technicians with clients across several clinics, and every clinic has its own operating hours. A solver can produce a valid week in seconds. What it cannot do is tell a manager why a particular technician ended up with a particular client at 2pm on Thursday, or let them change it without breaking the rest of the week. That gap between a correct schedule and a trusted one is where the work went.

Domain
Clinic operations and technician scheduling
Core
OR-Tools CP-SAT, rule registry, draft/review workflow
Stack
Flask, SQLAlchemy, Postgres, React, Vite

A scheduling workflow with review built in.

01

Generate draft schedules.

A manager picks the week, slot length, day horizon and lunch window, then generates. The solver produces a draft run and changes nothing that is already live. Progress streams back while it works, so a long solve looks like progress rather than a hung page.

02

Review before approval.

The draft shows proposed sessions, unfilled hours per client, and how long the solver took. Individual rows can be rejected or the whole run approved. Solver output is a proposal, never the schedule.

03

Fill gaps without collateral damage.

A second pass fills unfilled hours in the current week while pinning everything already approved. Managers can top up a partial week without the solver quietly rearranging work that people have already been told about.

04

Edit the live day directly.

Per-day drag-and-drop calendars by technician and by client, for the changes that never fit a rule: someone swaps a shift, a client cancels, a manager simply knows better.

05

Share, export, and account for it.

Read-only share links for a week or a run, CSV export of approved sessions, role-based access across admin, scheduler and read-only, and an audit log of every mutating call, so a schedule change can be explained after the fact.

Hard rules are law. Soft rules are priced.

Every constraint lives in a registry that can be toggled and tuned from the interface, and the split between the two kinds is the whole design.

Hard rules cannot be broken at any price: no double booking, stated availability windows, only technicians approved for that client, clinic operating hours, daily hour caps, and per-client limits on how short or long a block may be. A schedule violating any of these is not a worse schedule, it is an invalid one.

Soft rules carry weights, which is where a clinic's actual priorities get written down. Meeting each client's required hours is weighted roughly three hundred times more heavily than placing a tidy lunch break. Continuity — limiting how often a client's technician changes during a day — outranks technician preference. Travel gaps between clinics and avoiding isolated one-off sessions are worth something, but they lose to almost everything else.

Those weights are saved and reused on every run, so tuning them is a policy decision the clinic makes once rather than an argument relitigated every week. It also makes the trade-offs explicit: when a manager disagrees with the schedule, the conversation is about a number they can change, not about the solver being wrong.

Trust is a feature, and it has to be built.

01

Optimal is not the same as acceptable.

A mathematically optimal week that surprises staff will be overridden by hand, and once that starts the system is dead. Draft-and-approve exists so the solver never gets the last word.

02

Real weeks get disrupted.

Technicians call out mid-week. Recovering from that had to be a first-class flow — report the absence, generate cover, approve it — rather than a full regeneration that discards a week of settled decisions.

03

Every change needs an owner.

In clinic operations, "who moved this and when" is a question that gets asked. Role-based access and an audit trail over every mutating call were requirements, not hardening added later.

The useful lesson: optimization has to land inside a real workflow.

This is the kind of build Seam is good at: make the rules explicit, automate the repetitive decision, and leave a system that people can inspect, override, and run without calling the builder every week. The solver was the easy half. The half that mattered was giving people a place to disagree with it.