Add the submission pipeline and the review loop
Steps 3 and 4 of the build order. A member can now upload a song, watch it convert, publish it, and review what everyone else has published. Pipeline: - ffprobe reads tags synchronously at submit so prefill never races typing; ffmpeg converts to Opus in the background, two at a time - ffmpeg succeeding is the validation — no container sniffing - publish moves the file inside the transaction, so a song row and its .ogg appear together or neither does - five submissions per rolling 24h, failures excluded Reviews and the reveal rule: - the queue is unreviewed songs only, oldest first, never your own - other people's reviews and the average are withheld in the query, not the template — a hidden average is never sent - 30 minutes to edit or delete your own review, enforced in the WHERE clause - deleting the last review unlocks the song for its submitter again The waiting page has one button: the metadata form autosaves after a pause in typing, and Julkaise submits it and publishes in the same request, so nothing is lost without JS. Genres store an English code and render a Finnish label.
This commit is contained in:
+25
-7
@@ -96,10 +96,20 @@ zero reviews, it is editable again.
|
||||
|
||||
### 2.2 Genres
|
||||
|
||||
Fixed list, `text` column, validated app-side:
|
||||
Fixed list, `text` column, validated app-side. The **stored value is the English code** and the
|
||||
Finnish label is display only — the same split the statuses use, so rewording a genre never touches
|
||||
a song row:
|
||||
|
||||
Rock, Metal, Punk, Blues, Jazz, Electronic, Hip Hop, Pop, Folk / Country, Classical, Soundtrack,
|
||||
Experimental, Finnish, Just Plain Weird, Other
|
||||
| Code | Label | | Code | Label |
|
||||
|---|---|---|---|---|
|
||||
| Rock | Rock | | Soundtrack | Elokuvamusiikki |
|
||||
| Metal | Metal | | Experimental | Kokeellinen |
|
||||
| Punk | Punk | | Classical | Klassinen |
|
||||
| Blues | Blues | | Electronic | Elektroninen |
|
||||
| Jazz | Jazz | | Hip Hop | Hip hop |
|
||||
| Pop | Pop | | Finnish | Kotimainen |
|
||||
| Folk / Country | Folk / Country | | Just Plain Weird | Ihan outoa |
|
||||
| | | | Other | Muu |
|
||||
|
||||
---
|
||||
|
||||
@@ -201,9 +211,17 @@ States: `queued` → (`downloading`, URL only) → `converting` → `ready` | `f
|
||||
Submitter-only. Live status plus the editable metadata form, so the wait is spent writing the
|
||||
introduction rather than watching a spinner.
|
||||
|
||||
The button reads *Muunnetaan…* and is disabled until `status = 'ready'`, when it becomes
|
||||
**Julkaise**. Publishing is always an explicit click — firing it automatically would race the
|
||||
submitter mid-sentence.
|
||||
**One button, at the bottom of the form: Julkaise**, disabled until `status = 'ready'`. Publishing
|
||||
is always an explicit click — firing it automatically would race the submitter mid-sentence.
|
||||
|
||||
There is no separate save button: two buttons made it unclear which one committed the text.
|
||||
|
||||
- The metadata form **autosaves** — `hx-post` on `input changed delay:1.2s` and on `change`,
|
||||
answering with a quiet "Tallennettu 21.37" line and nothing else.
|
||||
- Julkaise lives outside the form and is bound to it with the HTML `form=` attribute, so pressing
|
||||
it submits the metadata *and* publishes in one request. The last keystrokes therefore arrive with
|
||||
the click even if the autosave never fired — which is also what makes the page work with no JS at
|
||||
all.
|
||||
|
||||
The live part is HTMX polling a fragment:
|
||||
|
||||
@@ -211,7 +229,7 @@ The live part is HTMX polling a fragment:
|
||||
<!-- {{define "submission-status"}} — included by the page, returned alone by the poll -->
|
||||
<div hx-get="/submit/{{.ID}}/status" hx-trigger="every 2s" hx-swap="outerHTML">
|
||||
<p>{{.Label}}</p>
|
||||
<button {{if not .Ready}}disabled{{end}}>Julkaise</button>
|
||||
<button type="submit" form="meta" {{if not .Ready}}disabled{{end}}>Julkaise</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user