Back to projects

CovalFlow

2026 · Designer and lead developer, built at CovalTech.

Volunteer scheduling for event organisers: profiles, e-signed contracts, automatic reminders, and a shift plan generated by a constraint solver in under 10 seconds.

What I delivered

  • A shift plan generated by a constraint solver (OR-Tools CP-SAT) in under 10 seconds
  • A self-service app where volunteers declare their own availability
  • Re-planning that keeps every assignment already locked in by hand
  • Contracts with a real e-signature (self-hosted Documenso), tracked and reminded automatically
  • PDF exports: one plan per event, one route sheet per volunteer
  • Volunteer profiles shared across organisations, each organisation's data kept isolated
  • Settlements: cash and wire amounts owed per volunteer, per event

In numbers

to plan 100 volunteers across 400 shifts
< 10 s
associations using it live
3
contracts signed from a phone by one association
68
automated tests on the solver
48
CovalFlow public homepage showing the events overview dashboard mockup
CovalFlow's public homepage: volunteer recruitment, automatic shift planning and contract signing in one workspace.

Context

Event organisers running on volunteers, mostly associations covering events of a few hundred to a few thousand attendees, were scheduling shifts by hand in a spreadsheet and chasing signatures over email and PDF attachments: availability, skills and rest rules tracked in separate documents that fell out of sync the moment someone changed their mind. I felt this problem directly, coordinating volunteers for a two-day event where a clock change in the middle of the night undid most of a finished plan. Moving one person off a shift meant moving several others around them, and the sheet had to be rebuilt, not patched.

The problem

A feasible schedule has to satisfy every volunteer's availability, skill and rest constraints at once, cover every role an event needs, and a spreadsheet cannot prove any of that. Past a few dozen volunteers, checking it by hand stops being reliable, and a single withdrawal the night before an event can force the whole plan to be rebuilt from nothing.

Constraints

Contracts needed a real signature, not an email attachment nobody chased. A plan already published, sometimes already partly signed, could not be silently overwritten the moment something changed: regenerating it had to keep every assignment already locked in by hand and only rework the rest. And the organisers running this are small associations, so the stack had to stay self-hosted and cheap to operate, not a SaaS bill per seat.

What I built, in detail

Volunteer profiles that follow a person across organisations, since the same volunteer often works with more than one association, behind an org switcher that keeps each organisation's data isolated from the others. Event roles (security, bar, reception) with remuneration set per assignment, a self-service app where volunteers declare their own availability, and a planning screen backed by a Python service (FastAPI, Google OR-Tools CP-SAT, covered by 48 tests) that turns availability, skill and rest rules into a feasible shift plan, with a tooltip explaining why any volunteer was left unassigned. A published plan survives a regeneration: assignments already locked in by hand stay locked in, only the rest gets recomputed, and the whole thing exports as a PDF, one view for the event and one route sheet per volunteer. Contracts, tied to an event or standalone, get a PDF and a real signature through a self-hosted Documenso instance, tracked from generated to sent to signed, with automatic reminders for the ones still waiting. A settlements module closes the loop: cash and wire amounts owed per volunteer, per event.

Decisions

A constraint solver instead of a rule engine
OR-Tools CP-SAT treats availability, skill and rest as hard constraints and proves a feasible plan exists, instead of a best-effort heuristic that can silently leave a shift uncovered.
Impact A plan for 100 volunteers and 400 shifts in under 10 seconds, with every constraint checked.
Multi-tenant from the first migration
Every table carries an organisation id, and a volunteer working with two associations switches between them without either one seeing the other's data. That mattered from the start: CovalFlow runs several associations on the same instance today.
Impact 3 associations run on the same instance, and none of them sees another's data.
Self-hosted e-signature
Documenso, self-hosted, gives every organisation a real signed contract without a recurring per-seat SaaS bill, which matters for a volunteer-run association.
Impact One association had 68 contracts signed from a phone, with no per-seat subscription.
AI-assisted solver, human-reviewed
Python is not a language I write daily. I designed the OR-Tools model and the module boundaries, then reviewed every line an AI agent wrote before it shipped.
Impact The solver shipped covered by 48 tests.

Result

The solver plans 100 volunteers across 400 shifts in under 10 seconds, and CovalFlow runs today for 3 associations. Two events into using it for real, one association had managed 80 volunteers and signed 68 contracts from a phone, without printing a single page. The surprise was not the time saved on the plan itself, it was not spending evenings chasing people for a signature anymore.

100 volunteers and 400 shifts planned in under 10 seconds, live for 3 associations.

Stack

  • React
  • TypeScript
  • Node.js
  • PostgreSQL
  • Python (OR-Tools CP-SAT)
  • FastAPI
  • Docker
Back to projects