Production-ready REST API backend for LIMA (Ligue d'Improvisation du Maine-et-Loire), an improv theater association managing 60+ members, show seasons, event scheduling, and cast assignments.
- π JWT Authentication β Secure login, account activation via email, password reset
- π₯ Member Management β Full CRUD, HelloAsso CSV import, role management, commission assignment
- π Season & Event Management β Season lifecycle, event scheduling, Excel calendar import
- π Show Alignments β Cast assignment grid (players, MJ, MC, DJ, Coach, Referee per show)
- πͺ Show Plans β Flexible show configuration with JSON metadata
- π Activity Tracking β Per-user request logging, admin analytics dashboard (DAU, top pages, errors)
- π§ Email Service β Async SMTP (aiosmtplib), activation, password reset, and 24h reminder emails
- π‘οΈ Rate Limiting β slowapi on all auth endpoints
- π Admin Stats API β Recent activity, login stats, daily active users
React Frontend (limaimpro.duckdns.org)
β
βΌ
FastAPI (Railway) βββ PostgreSQL 16 (Railway)
β
βββ /auth JWT auth, activation, password reset
βββ /members Member CRUD, CSV import
βββ /seasons Season management
βββ /events Event scheduling, Excel import, cast
βββ /alignments Show casting grid
βββ /show-plans Show configuration
βββ /commissions Commission management
βββ /settings Association settings (DB-persisted)
βββ /admin Activity tracking, analytics
- Python 3.12+
- PostgreSQL 16 (or SQLite for dev)
# Clone
git clone https://github.com/versila22/lima-backend.git
cd lima-backend
# Setup venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Environment
cp .env.example .env
# Edit .env: DATABASE_URL, JWT_SECRET, SMTP settings
# Run migrations
alembic upgrade head
# Start
uvicorn app.main:app --reload --port 8001API available at http://localhost:8001 Β· Docs at http://localhost:8001/docs
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/login |
Login β JWT token |
| POST | /auth/activate |
Activate account with token + password |
| POST | /auth/forgot-password |
Request password reset |
| POST | /auth/reset-password |
Reset with token + new password |
| GET | /auth/me |
Current user profile |
| Method | Endpoint | Description |
|---|---|---|
| GET | /members |
List members (filterable by season) |
| POST | /members |
Create member (admin) |
| POST | /members/import |
Import from HelloAsso CSV |
| PUT | /members/{id}/role |
Update member role (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /events |
List events |
| POST | /events |
Create event (admin) |
| GET | /events/{id}/cast |
Get show cast assignments |
| POST | /events/import-calendar |
Import Excel calendar |
| GET | /alignments |
List casting grids |
| POST | /alignments/{id}/assign |
Assign player to event role |
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/activity/recent |
Recent activity logs |
| GET | /admin/activity/stats |
DAU, top pages, errors, avg response time |
| GET | /admin/activity/logins |
Login attempts (success/failure) |
- JWT β HS256, configurable expiry, startup validation (rejects insecure defaults in production)
- Passwords β pbkdf2_sha256 (passlib) β bcrypt-compatible, Python 3.13 safe
- Rate Limiting β slowapi: 5 req/min on
/auth/login, 3 req/min on/auth/forgot-password - CORS β Explicit allowed origins (no wildcard in production)
- Activity Logging β Every request logged with user, path, status, response time
JWT_SECRET=test-secret python -m pytest tests/ -v95 tests covering:
- Auth flows (login, activation, password reset, token expiry)
- Members, seasons, events, venues, alignments, commissions, show plans
- Admin activity endpoints
- Rate limiting, 401/403/404 handling, IDOR protection
# Required env vars on Railway
JWT_SECRET=<strong-random-secret>
DATABASE_URL=postgresql://...
SMTP_HOST=smtp.example.com
SMTP_USER=noreply@lima.asso.fr
SMTP_PASSWORD=...
FRONTEND_URL=https://limaimpro.duckdns.orgRailway auto-deploys on push to main. Migration runs automatically at startup (alembic upgrade head).
A daily script sends reminder emails to members assigned to published events happening in the next 24 hours.
cd /data/.openclaw/workspace/lima/backend
python scripts/send_reminders.pyRecommended setup:
- run it once per day via cron or Railway scheduled job
- keep
SMTP_*variables configured so emails are actually delivered - keep
FRONTEND_URLpointing to the public members app so the email CTA opens/mon-planning
Example cron (every day at 09:00):
0 9 * * * cd /data/.openclaw/workspace/lima/backend && /usr/bin/python3 scripts/send_reminders.py >> /var/log/lima-reminders.log 2>&1| Tool | Purpose | Version |
|---|---|---|
| FastAPI | Web framework | 0.111 |
| SQLAlchemy | ORM (async) | 2.0 |
| Alembic | DB migrations | latest |
| PostgreSQL | Database | 16 |
| asyncpg | Async PG driver | 0.29 |
| passlib | Password hashing | 1.7 |
| python-jose | JWT | 3.3 |
| slowapi | Rate limiting | 0.1 |
| aiosmtplib | Async SMTP | latest |
| pytest + pytest-asyncio | Testing | latest |
- WebSocket for real-time alignment updates
- Google Calendar integration
- Push notifications (email/Telegram)
- Availability management for players
- AI-powered show plan generation (Gemini)
- HelloAsso webhook auto-import
PRs welcome! Especially interested in:
- Gemini integration for automated show plan suggestions
- HelloAsso webhook for real-time member sync
- i18n (currently French-only)
MIT β See LICENSE
Built with β€οΈ for the LIMA improv community in Angers, France.