Add comprehensive comments to all source files and expand documentation
This commit is contained in:
parent
9e532a1920
commit
b4f0222bd5
16 changed files with 1230 additions and 552 deletions
132
README.md
132
README.md
|
|
@ -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.
|
||||
|
|
|
|||
Reference in a new issue