3.5 KiB
3.5 KiB
AGENTS.md
Mission
Maintain a deliberately small, self-hosted rota application for a non-profit bar/club. Prefer clarity and operational simplicity over enterprise HR features.
Domain invariants
- Assignments are the source of truth. Recurrence/rotation rules only create assignments that do not already exist.
- There are three seeded schedules:
night: fixed/manual, every day of the month.saturday-lunch: rotating, Saturdays only.sunday-lunch: rotating, Sundays only.
- Saturday and Sunday rotations are independent.
- Never silently rewrite an existing assignment when rotation membership/order changes.
- A swap/change request only applies if the requester still owns the assignment when it is accepted/approved.
emailandphoneare optional.username/passwordare optional as a pair: a person either signs in or is rota-only. Ausername, when set, is unique.- Email failure must never roll back or block a rota change. Log failures in
notification_logs. - Past assignments cannot be offered for change through the member UI.
Stack
- Python 3.12+
- FastAPI + server-rendered Jinja2
- SQLAlchemy 2.x
- SQLite by default
- No frontend build step or JavaScript framework
- Docker Compose for self-hosting
Important files
app/models.py— database schema.app/scheduling.py— recurrence and assignment generation. Treat changes here as high-risk.app/web.py— HTTP routes and workflows.app/notifications.py— SMTP delivery; should fail soft.app/bootstrap.py— initial admin + three default schedules.app/cli.py— database/demo/reminder commands.docs/DOMAIN.md— expected business behavior.
Working rules for agents
- Read
docs/DOMAIN.mdbefore changing scheduling behavior. - Add/update tests for every scheduling or swap-state change.
- Keep existing generated/published assignments stable unless an admin explicitly edits them.
- Do not add payroll, time clocks, attendance, leave management, or HR modules unless requested.
- Keep phone as data-only until SMS/WhatsApp is explicitly implemented.
- Do not commit
.env, database files, credentials, or real member data. - Do not introduce a frontend package manager unless the UI requirements truly need it.
- Prefer migrations before making schema changes in a deployed installation. This MVP currently uses
create_all; adding Alembic is a roadmap item.
Validation before handoff
Run:
python -m compileall -q app
pytest -q
For route/UI changes also start the app and verify /health, /login, the rota, admin month editor, and swap workflow.
Security notes
- Passwords use PBKDF2-SHA256 from Python stdlib.
- State-changing forms use a session CSRF token.
- Admin routes must call
_require_admin. - Treat names, email addresses, phone numbers and schedules as private member data.
- Change the default
SECRET_KEYand initial admin password before deployment.
Branding and UI
- The CRR logo is the user-supplied asset at
app/static/logo-crr.png. Keep its aspect ratio and do not redraw, recolor, crop, or replace it unless explicitly requested. - CRR brand red is
#ED1C24and is exposed as--brandinapp/static/app.css. - For controls with white text, use the darker accessible red
--brand-deep(#C81018), not the exact brand red. The exact brand red is used for borders, focus states, highlights, and other identity accents. - Keep branding usable on mobile and preserve visible keyboard focus states.
- Default application name is
CRR Bar Rota; deployments can still override it withAPP_NAME.