feat: Hermes prompt callback endpoint + API key management
- Add /api/prompt/<rid> callback endpoint with dual auth: per-request signed URL token + Bearer API key. - Add HERMES_API_KEY config and runtime key helpers in app.py. - Update admin request page to copy request details + callback URL. - Add API key management to admin settings: regenerate, mask, show-once. - Update .env.example, docker-compose.yml, README, REVIEW docs.
This commit is contained in:
parent
e46893e0b4
commit
6a60aa686c
8 changed files with 242 additions and 35 deletions
37
README.md
37
README.md
|
|
@ -21,6 +21,8 @@ A Flask web app for a convention booth where visitors request a custom AI-genera
|
|||
- **Dashboard queue** (`/admin`) — filter by status (All, Pending, Needs Upload, Awaiting Payment, Delivered) and auto-refresh at a configurable interval.
|
||||
- **Per-request detail page** (`/admin/request/<id>`):
|
||||
- Generate and save a Suno prompt from customer info.
|
||||
- One-click copy of request details + a signed callback URL for Hermes.
|
||||
- Hermes POSTs back the generated Title/Style/Lyrics; status becomes **Prompt Ready** automatically.
|
||||
- Edit the customer's email address if they mistyped it.
|
||||
- Upload Version A and Version B MP3s (with automatic ID3 metadata tagging).
|
||||
- Send a preview email with a private player link.
|
||||
|
|
@ -32,6 +34,7 @@ A Flask web app for a convention booth where visitors request a custom AI-genera
|
|||
- Configure dashboard auto-refresh interval.
|
||||
- Configure SMTP host/port/user/from; store the SMTP password encrypted.
|
||||
- Configure default MP3 metadata tags (artist, album, year, comment).
|
||||
- Generate/regenerate the Hermes API key used by the prompt callback endpoint (shown once, otherwise masked).
|
||||
- Send a test email.
|
||||
- Download or restore the SQLite database backup.
|
||||
- Reset the entire system for a new event.
|
||||
|
|
@ -46,7 +49,7 @@ pending → prompt_ready → songs_uploaded → awaiting_payment → paid → de
|
|||
| Status | Meaning |
|
||||
|---|---|
|
||||
| `pending` | Customer submitted a request; operator has not saved a prompt yet. |
|
||||
| `prompt_ready` | Operator saved Title/Style/Lyrics. |
|
||||
| `prompt_ready` | Hermes POSTed back the generated Suno prompt, or the operator saved it manually. |
|
||||
| `songs_uploaded` | Both MP3s uploaded; preview link can be sent. Dashboard filter label: **Needs Upload** (shown for this state when filtering). |
|
||||
| `revisions_requested` | Customer asked for changes; current files were archived. |
|
||||
| `awaiting_payment` | Customer approved a version; waiting for operator to collect payment and deliver. |
|
||||
|
|
@ -57,13 +60,13 @@ pending → prompt_ready → songs_uploaded → awaiting_payment → paid → de
|
|||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `app.py` | Flask routes, helpers, email layer, runtime settings, MP3 tagging, rate limiting, and DB maintenance helpers. |
|
||||
| `config.py` | Environment-variable based configuration; defines defaults for DB, uploads, SMTP, and secrets. |
|
||||
| `models.py` | SQLite schema and CRUD helpers. |
|
||||
| `init_db.py` | Standalone script to create the database tables. |
|
||||
| `templates/closed.html` | Message shown on `/request` when the booth is marked closed. |
|
||||
| `templates/request.html` | Customer request form. |
|
||||
| `templates/thanks.html` | Post-submission confirmation. |
|
||||
| `app.py` | Flask routes, helpers, email layer, runtime settings, MP3 tagging, rate limiting, DB maintenance, and Hermes callback endpoint. |
|
||||
| `config.py` | Environment-variable based configuration; defines defaults for DB, uploads, SMTP, secrets, and `HERMES_API_KEY`. |
|
||||
| `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` | Maintenance, settings, backup/restore, reset, and Hermes API key management. |
|
||||
| `templates/status.html` | Customer order status lookup. |
|
||||
| `templates/faq.html` | Customer FAQ page. |
|
||||
| `templates/player.html` | Customer audio player, approval, and revision form. |
|
||||
|
|
@ -114,10 +117,11 @@ Visit:
|
|||
| `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 to the operator/customer, default `10.00`. |
|
||||
| `CURRENCY` | No | Currency label, default `CAD`. |
|
||||
| `MAX_REVISIONS` | No | Default customer revision limit if not changed in settings, default `2`. |
|
||||
|| `BOOTH_NAME` | No | Name used in emails, default `Trollgorithm Theme Songs`. |
|
||||
|| `PRICE_PER_VERSION` | No | Shown to the operator/customer, default `10.00`. |
|
||||
|| `CURRENCY` | No | Currency label, default `CAD`. |
|
||||
|| `MAX_REVISIONS` | No | Default customer revision limit if not changed in settings, default `2`. |
|
||||
|| `HERMES_API_KEY` | No | API key for the `/api/prompt` callback. If omitted, generate one from `/admin/settings`. |
|
||||
|
||||
5. Deploy the stack.
|
||||
6. Open a console in the `theme-song-booth` container and run once:
|
||||
|
|
@ -127,7 +131,9 @@ python init_db.py
|
|||
```
|
||||
|
||||
7. Point your reverse proxy at the `HOST_PORT` you chose.
|
||||
8. Print or display a QR code pointing to `https://your-domain/request`.
|
||||
8. Visit `/admin/settings` and click **Regenerate API Key** to create the Hermes callback key.
|
||||
9. Update your Hermes skill or config with the new key and the booth public URL.
|
||||
10. Print or display a QR code pointing to `https://your-domain/request`.
|
||||
|
||||
### Updating the deployment
|
||||
|
||||
|
|
@ -136,13 +142,14 @@ After each push to GitLab, go to Portainer → **Stacks** → `theme-song-booth`
|
|||
## Important notes
|
||||
|
||||
- **No `.env` file in production.** `docker-compose.yml` passes variables directly from Portainer. This avoids Portainer's `env_file not found` error.
|
||||
- **Runtime settings persist.** SMTP config, revision limit, auto-refresh interval, booth open/closed state, and MP3 metadata defaults are stored in `booth_settings.json` inside the persistent uploads volume. They survive redeploys.
|
||||
- **Runtime settings persist.** SMTP config, revision limit, auto-refresh interval, booth open/closed state, Hermes API key, and MP3 metadata defaults are stored in `booth_settings.json` inside the persistent uploads volume. They survive redeploys.
|
||||
- **Booth open/closed switch.** Operators can flip the booth status from `/admin/settings`. When closed, `/request` shows a closed banner and message instead of the form.
|
||||
- **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`.
|
||||
- **Hermes callback workflow.** Operators copy request details + a signed callback URL from `/admin/request/<id>`. Hermes POSTs back Title/Style/Lyrics; the record becomes `prompt_ready`.
|
||||
- **MP3 metadata.** Uploaded files are tagged with title (from the saved prompt), plus configured artist/album/year/comment values.
|
||||
- **Email logo.** `static/DM-Logo_email.png` is attached inline to all customer emails as the Dionysis Media signature.
|
||||
- **Security:** the repo is public on GitLab. No secrets are committed. Admin password is plain text in the Portainer environment.
|
||||
- **Security:** the repo is public on GitLab. No secrets are committed. Admin password is plain text in the Portainer environment. The Hermes API key is stored encrypted in `booth_settings.json` and masked in the admin UI.
|
||||
|
||||
## Common troubleshooting
|
||||
|
||||
|
|
|
|||
Reference in a new issue