The admin was a set of env credentials on its own loopback listener. That bought network isolation, and charged a second port to tunnel and proxy and a second credential in the password manager. It also sat outside the SameSite protection the member cookie already had, and left every ban and password reset with no actor to log. is_admin on users reuses what was already there: the session, the login rate limiter, ban-drops-sessions, CSRF. /admin is now a route on the member mux. A member without the flag gets 404 rather than 403 — the pages are none of their business, and "forbidden" confirms there is something to be forbidden from. Registration needs an invite and invites come from /admin, so an empty database cannot grow its first user. seedAdmin breaks that circle exactly once, from ADMIN_EMAIL and ADMIN_PASSWORD, and does nothing against a database that already has users. An admin cannot ban themselves: banning drops the target's sessions, and nothing would be left that could undo it. This reverses decision 8, which is rewritten rather than deleted, along with the admin entry in the CONTEXT.md vocabulary.
78 lines
3.3 KiB
Markdown
78 lines
3.3 KiB
Markdown
# Levyraati
|
||
|
||
A private music review club for about ten friends. Members submit songs and review each other's
|
||
picks; other people's opinions of a song stay hidden until you've written your own.
|
||
|
||
Identifiers, schema, and routes are English. Rendered text is Finnish only. Each term below carries
|
||
both, so the UI uses one word per concept everywhere.
|
||
|
||
## Language
|
||
|
||
**Member** — _jäsen_:
|
||
A person with an account. Every account is a member; there is no other kind.
|
||
_Avoid_: user, käyttäjä, account
|
||
|
||
**Admin** — _ylläpitäjä_:
|
||
A member who also operates the installation. The same account, the same session, one extra flag —
|
||
so an admin submits and reviews like anyone else and does appear in lists of people.
|
||
_Avoid_: superuser, role, admin account (there is no separate account)
|
||
|
||
**Invite** — _kutsu_ / **invite code** — _kutsukoodi_:
|
||
A one-time code that permits one registration. Spent only by a registration that succeeds.
|
||
|
||
**Song** — _kappale_:
|
||
A published piece of music with its converted audio, submitted by a member. A row in `songs` is a
|
||
real song with no qualifier.
|
||
_Avoid_: track, biisi, levy (that's a record, the wrong unit)
|
||
|
||
**Submission** — _(no Finnish noun; the member sees only the verb_ lähettää _and a status)_:
|
||
A song in flight — uploaded or downloaded, converting, not yet published. It becomes a Song at
|
||
Publish and ceases to exist as a Submission.
|
||
|
||
**Publish** — _julkaise_:
|
||
The submitter's explicit act of turning a converted Submission into a Song. Never automatic.
|
||
|
||
**Review** — _arvostelu_:
|
||
One member's score and written verdict on one song. At most one per member per song, and never on
|
||
your own song.
|
||
|
||
**Reviewer** — _arvostelija_:
|
||
The member who wrote a review. Reviews are never anonymous.
|
||
|
||
**Score** — _pisteet_:
|
||
An integer 1–100 given in a review.
|
||
_Avoid_: rating, arvosana
|
||
|
||
**Reveal**:
|
||
Gaining access to other members' opinions of a song by having written your own review of it — or by
|
||
being its submitter. Covers the reviews and the song's average score, on every surface that names a
|
||
song. Enforced in the query, never in the rendering.
|
||
|
||
Per-song opinion is gated; whole-history aggregate is public. A member's profile shows counts and
|
||
averages over everything they have done, never how they reviewed any particular song.
|
||
|
||
**Edit window**:
|
||
The 30 minutes after a review's last change, during which its author may edit or delete it. Then the
|
||
review is on the record permanently.
|
||
|
||
**Locked** (of a song):
|
||
Having at least one review, which freezes its title, artist, and description and prevents the
|
||
submitter deleting it. A live state, not a one-way door: if the last review is deleted, the song is
|
||
editable again.
|
||
|
||
**Report** — _palaute_:
|
||
A member's free-text note about something broken or annoying, carrying the page they were on. Open
|
||
until the admin resolves it. Deliberately has no category, priority, or severity.
|
||
_Avoid_: ticket, issue, bug, vikailmoitus
|
||
|
||
**Genre** — _genre_:
|
||
One value from a fixed list, chosen by the submitter.
|
||
_Avoid_: tyylilaji, tag, category
|
||
|
||
**Ban** — _estä_:
|
||
Ending a member's participation: login refused and live sessions dropped. Their songs and reviews
|
||
remain and continue to count. Reversible.
|
||
|
||
**Stats** — _tilastot_:
|
||
The always-public leaderboards. The only place aggregate opinion is visible without having reviewed.
|