3.8 KiB
3.8 KiB
REVIEW.md — Theme Song Booth
Quick reference for future work on this project.
One-sentence summary
Flask app that lets convention attendees request custom AI-generated theme songs, lets an operator manage the queue, and emails MP3s after payment.
Stack
- Python 3.12 + Flask
- SQLite (file-based, request-scoped connection via
g) - Gunicorn in Docker
- Portainer stack deployed from GitLab repo
- SMTP (SSL port 465) for customer emails
- Square Terminal/Reader for manual payment
mutagenfor MP3 metadata taggingflask-limiterfor public form rate limitingcryptographyto encrypt the stored SMTP password
Repository
- GitLab:
https://gitlab.hallsworth.ca/yrtria/theme-song-booth(public) - Deployed at:
https://booth.dionysismedia.ca
Key files and what they hold
| File | Notes |
|---|---|
app.py |
All routes, helpers, email function, status labels, runtime settings, MP3 tagging, rate limiting, DB health. |
config.py |
Env vars. ADMIN_PASSWORD is plain text. |
models.py |
SQLite schema + CRUD. player_token is a secret URL-safe token. |
init_db.py |
Run once after deploy: python init_db.py. |
templates/admin/request.html |
Biggest template; prompt copy helpers and JS live here. Customer email and operator notes are editable here. |
templates/admin/dashboard.html |
Queue table + filters + auto-refresh + topbar Reset System button. |
templates/admin/settings.html |
SMTP config, MP3 metadata defaults, DB backup/restore, health check, reset. |
templates/faq.html |
Customer FAQ page. |
templates/status.html |
Customer order status lookup. |
templates/closed.html |
Message shown on /request when the booth is marked closed. |
docker-compose.yml |
No env_file; variables come from Portainer. |
Status meanings
pending → prompt_ready → songs_uploaded → awaiting_payment → paid → delivered
revisions_requested is a branch used when the customer asks for changes.
Operator workflow
- Customer fills
/request. - Open
/admin, click request row (or filter by status). - On
/admin/request/<id>, fix the customer's email if needed, then click Copy customer info for Hermes, paste result to Hermes. - Paste Hermes response (Title/Style/Lyrics format) into the fields and click Save Prompt.
- Copy Style/Lyrics into Suno Custom Mode, generate two versions.
- Upload Version A and B MP3s.
- Click Send Preview Link.
- Customer receives email, visits player, picks version.
- Operator collects Square payment, enters reference, clicks Mark Paid & Deliver.
- Customer receives MP3 attachment(s) by email.
Environment variables that matter
APP_SECRET_KEY
ADMIN_PASSWORD
SMTP_PASS
PUBLIC_BASE_URL
BOOTH_NAME
HOST_PORT
INTERNAL_PORT
MAX_REVISIONS
Most can be overridden at runtime from /admin/settings and stored in booth_settings.json.
Gotchas
- Multiple forms on
admin/request.htmlmust stay properly closed; nested forms break buttons. upload_songsform needsenctype="multipart/form-data"and a matching</form>.- The dashboard uses
basename()as a function, not a Jinja filter. - Reset System deletes DB rows and all files under
UPLOAD_FOLDER, then resetssqlite_sequence. - Runtime settings are stored in the persistent uploads volume (
booth_settings.json). - The
booth_opensetting controls whether/requestshows the form or the closed banner. - Container cannot read host paths; all static assets used at runtime (logo, banner, favicons, closed banner) must be in the repo or a mounted volume.
How to redeploy
- Push changes to GitLab
main. - In Portainer: Stacks →
theme-song-booth→ Pull and redeploy. - If schema changed, open container console and run
python init_db.py, or use/admin/settings→ Fix Missing Columns.