Add comprehensive comments to all source files and expand documentation

This commit is contained in:
Troll (Hermes Agent) 2026-07-31 22:23:40 +00:00
parent 9e532a1920
commit b4f0222bd5
16 changed files with 1230 additions and 552 deletions

132
README.md
View file

@ -1,18 +1,54 @@
# Theme Song Booth
Prototype web app for a convention booth where attendees request custom AI-generated theme songs.
Custom theme-song request and delivery system for a convention booth. Customers fill out a form, the operator generates two AI-made song versions, the customer picks one, and the approved MP3 is delivered by email after payment is collected.
## Flow
## What this project does
1. Customer fills out the public request form at `/request`.
2. Operator generates a Suno Custom Mode prompt via Hermes and saves it in the admin detail page.
3. Operator generates two song versions in Suno and uploads the MP3s in admin.
4. Operator clicks **Send Preview Link**. Customer receives an email with a private player page.
5. Customer listens to Version A and Version B, then approves one/both or requests changes.
6. Operator sees the approval alert, collects payment via Square reader, then clicks **Mark Paid & Deliver**.
7. Customer receives the approved MP3(s) as email attachments.
- **Customer request page** (`/request`) — booth visitors enter their name, email, hobbies, notable facts, preferred genre, and extra requests. A branded banner image is shown.
- **Operator dashboard** (`/admin`) — queue of all requests with status filters, per-request detail page, and system reset.
- **Prompt generation** — the admin page builds a plain-text prompt for Hermes/AI, which returns a Title, Style, and Lyrics block. The operator pastes that response, clicks **Extract**, then uses Copy buttons to paste into Suno Custom Mode.
- **Song upload** — operator uploads Version A and Version B MP3s.
- **Customer player page** — a private `/play/<token>` page emails to the customer. They can listen to both versions, choose A/B/both, or request changes.
- **Payment and delivery** — operator enters a Square payment reference and clicks **Mark Paid & Deliver**. The approved MP3(s) are emailed as attachments.
- **System reset** — one button in the admin topbar clears all requests and files at the start of an event.
## Local Development
## Status flow
```
pending → prompt_ready → songs_uploaded → awaiting_payment → paid → delivered
```
| Status | Meaning |
|---|---|
| `pending` | Customer submitted request; no prompt yet. |
| `prompt_ready` | Operator saved Title/Style/Lyrics. |
| `songs_uploaded` | Both MP3s uploaded; preview link can be sent. |
| `awaiting_payment` | Customer approved a version. |
| `paid` | Payment reference recorded; delivery email sent. |
| `delivered` | MP3 attachments emailed. |
## File layout
| File | Purpose |
|---|---|
| `app.py` | Flask routes, helpers, and email logic. |
| `config.py` | Environment-variable based configuration. |
| `models.py` | SQLite schema and database helper functions. |
| `init_db.py` | Standalone script to create the database tables. |
| `templates/request.html` | Customer request form (with banner). |
| `templates/thanks.html` | Post-submission confirmation. |
| `templates/player.html` | Customer audio player and approval page. |
| `templates/admin/login.html` | Admin password login. |
| `templates/admin/dashboard.html` | Operator queue with filters and reset. |
| `templates/admin/request.html` | Single-request detail / prompt / upload / delivery. |
| `static/Trollgorithm_booth.jpg` | Banner image on the request page. |
| `Dockerfile` | Production container image. |
| `docker-compose.yml` | Portainer stack definition. |
| `requirements.txt` | Python dependencies. |
| `.env.example` | Template for environment variables. |
| `REVIEW.md` | Quick reference for returning to this project. |
## Local development
```bash
cd /home/jess/workspace/theme-song-booth
@ -24,42 +60,62 @@ cp .env.example .env
.venv/bin/python -m flask --app app run --host=0.0.0.0
```
Visit:
- Customer form: http://127.0.0.1:5000/request
- Admin login: http://127.0.0.1:5000/admin
## Deployment with Portainer
The repo includes a `docker-compose.yml` that builds directly from GitLab, so Portainer can pull and deploy it as a stack.
1. Log in to your Portainer instance.
1. Log in to Portainer.
2. Go to **Stacks****Add stack**.
3. Choose **Repository** and paste:
3. Choose **Repository**:
- URL: `https://gitlab.hallsworth.ca/yrtria/theme-song-booth.git`
- Branch: `main`
- Compose path: `docker-compose.yml`
4. Add environment variables directly in Portainer under **Environment variables**:
- `APP_SECRET_KEY` — long random string
- `ADMIN_PASSWORD` — password for `/admin`
- `SMTP_PASS``b3ZzD@eM!MkqVS8P`
- `PUBLIC_BASE_URL` — your HTTPS domain
- `HOST_PORT` — default `127.0.0.1:8000`
- `BOOTH_NAME` — optional
4. Add environment variables:
| Variable | Required | Purpose |
|---|---|---|
| `APP_SECRET_KEY` | Yes | Long random string for Flask sessions. Generate with `python3 -c "import secrets; print(secrets.token_hex(32))"`. |
| `ADMIN_PASSWORD` | Yes | Password for `/admin`. |
| `SMTP_PASS` | Yes | Password for `ai@hallsworth.ca`. |
| `PUBLIC_BASE_URL` | Yes | Public HTTPS URL, e.g. `https://booth.dionysismedia.ca`. |
| `HOST_PORT` | No | Host-side port mapping, default `127.0.0.1:8000`. |
| `INTERNAL_PORT` | No | Port gunicorn binds inside container, default `8000`. |
| `BOOTH_NAME` | No | Name used in emails, default `Trollgorithm Theme Songs`. |
| `PRICE_PER_VERSION` | No | Shown on receipt page, default `10.00`. |
| `CURRENCY` | No | Currency label, default `CAD`. |
5. Deploy the stack.
6. Open a console into the `booth` container and run once:
```bash
python init_db.py
```
7. Point your reverse proxy at the `HOST_PORT` you chose (e.g. `http://host-ip:8000`).
8. Print the booth QR code pointing to `https://your-domain/request`.
6. Open a console in the `booth` container and run once:
### Portainer Notes
```bash
python init_db.py
```
- The `docker-compose.yml` uses named volumes (`booth-data`, `booth-uploads`) so Portainer handles persistence automatically.
- For a pre-built image instead of repo build, replace the `build:` block with an `image:` line pointing to your registry.
- Update the stack after each push to redeploy the latest code.
7. Point your reverse proxy at the `HOST_PORT` you chose.
8. Print or display a QR code pointing to `https://your-domain/request`.
## Files
### Updating the deployment
- `app.py` — Flask application with public/admin routes and email logic.
- `models.py` — SQLite schema and helper functions.
- `config.py` — Configuration loaded from environment.
- `templates/` — Jinja2 HTML templates.
- `init_db.py` — Standalone script to create the SQLite database.
- `Dockerfile` / `docker-compose.yml` — Container packaging for Portainer.
After each push to GitLab, go to Portainer → **Stacks**`theme-song-booth`**Pull and redeploy** to rebuild from the repo.
## Important notes
- **No `.env` file in production.** `docker-compose.yml` passes variables directly from Portainer. This avoids Portainer's `env_file not found` error.
- **Payments are manual.** The app records a Square payment reference but does not integrate with Square's API. Use a Square Terminal/Reader at the booth.
- **Operator queue is the dashboard.** No operator email alerts are sent; approvals and revision notes appear as status changes in `/admin`.
- **Security:** the repo is public on GitLab. No secrets are committed. Admin password is plain text in the Portainer environment.
## Common troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| "Send Preview Link" does nothing | Form tags were unbalanced (now fixed). | Redeploy the latest commit. |
| Emails not arriving | SMTP_PASS wrong or messages in spam. | Verify SMTP credentials; check spam folder. |
| Can't reach app through domain | Reverse proxy points to wrong host port. | Match `HOST_PORT` to your proxy upstream. |
| Static banner not showing | Browser cached old image. | Hard-refresh or redeploy stack. |
## License / ownership
Built for Jess's Trollgorithm theme-song booth. All code and assets are private to that project.