This repository hosts an API that helps volunteer managers plan festival activities on a schedule, associate volunteers to time slots, and send SMS reminders during the event. Volunteer/slot data can also be bootstrapped from a Google Sheet import.
user (default) or super_admin. Only super_admin
can create/edit organizations and manage organization membership.org_admin — full control over the organization's projects and can
change member roles within their own organization.respo_benevole — manages volunteer allocation across the whole
project: slots, templates, volunteers, groups, and SMS.respo_commission — read access to the whole project plan; write
access limited to templates/slots belonging to the commission(s) they
are a member of. Cannot manage volunteers, groups, or SMS directly.name + phone_number) rather than stored as
free text — see SlotTemplate.responsible_override for the manual
exception case.For running the application
git clone ...
cd ...
python -m venv venv
venv/scripts/activate
poetry install
Note, be sure to use python3.11 with this application
init.sh
uvicorn app.main:app --reload
New databases start with no organizations and no super_admin. After
running migrations, promote the first user manually (there is currently
no API endpoint for this, by design — it's a one-time operational step):
UPDATE user_model
SET global_role = 'SUPER_ADMIN'
WHERE email = '<you>';
From there, that user can create organizations and add members via the
/organizations endpoints.
python -m app.debug
Run tests
pytest
pytest app\test\test_volunteer.py
Run coverage tests
coverage run -m pytest
coverage html
# create migration
alembic revision --autogenerate -m "migration_name"
# apply all migrations
alembic upgrade head
Autogenerated migrations are a starting point, not a final draft — review them by hand, especially for:
NOT NULL columns on tables that may already have data (add
nullable, backfill, then tighten in the same migration)create_table block
(need an explicit create_type=False + manual CREATE TYPE/DROP TYPE)ondelete behavior vs. the SQLAlchemy relationship's own cascade
config (see passive_deletes=True on Organization.projects — without
it, session.delete(org) tries to null out Project.organization_id
in Python before the DB's ON DELETE CASCADE ever runs, which fails
since that column is NOT NULL)poetry lock
poetry export -f requirements.txt --output requirements.txt --without-hashes
poetry export -f requirements.txt --output requirements-dev.txt --without-hashes --with dev
npm run update-schema
Regenerate after any backend route or schema change — see the frontend repo's README for details.
FastAPI project generated using https://github.com/rafsaf/minimal-fastapi-postgres-template