Glossar — breakout.now
Zurück zur MOC - Map of Content
Kernbegriffe
Session
Eine Live-Musik-Broadcast-Session, die ein Creator hostet. Sessions haben eine aktive Warteschlange (Queue) mit eingereichten Songs, Voting-Mechaniken und Payouts.
Technisch (sessions Table):
id: UUIDcreator_id: Foreign Key zucreatorsactive: Boolean (Session läuft gerade)queue_open: Boolean (neue Entries akzeptiert)started_at/ended_at: Timestampsstream_platform: Enum ='twitch' | 'youtube' | 'kick' | 'tiktok' | 'instagram' | 'other'min_entry_price_eur_cents: Integer (in EUR-Cents)min_skip_price_eur_cents: Integer (für höhere Position)min_increment_pct: Integer (z.B. 20 = +20% über aktuellen Top-Bid)free_entries_per_viewer: Integer (kostenlose Einreichungen)min_startup_entries: Integer (Minimum Songs zum Starten)
Siehe: Executive Summary für Session-Lifecycle
Entry / Einreichung
Ein Song, den ein Artist in eine Session einreicht. Jede Entry geht in die Queue und wird bei der Reihe abgespielt und bewertet.
Technisch (queue_entries Table):
id: UUIDsession_id: Foreign Keyparticipant_token: UUID (anonyme Viewer-ID)display_name: String (Artist-Anzeigename)track_title: String (Song-Titel)track_url: String | NULL (YouTube/Spotify Link)storage_path: String | NULL (Supabase Storage Path in "tracks" Bucket)entry_type: Enum ='standard' | 'priority'(standard = free, priority = paid)status: Enum ='waiting' | 'playing' | 'played' | 'removed'desired_position: Integer | NULL (höhere Position angefordert via Boost)queue_position: Integer | NULL (aktuelle Position in Queue)paid_amount_eur_cents: Integer (0 = kostenlos)payment_mode: Enum | NULL ='entry_fee' | 'buy_first' | 'skip_to_n'artist_id: UUID | NULL (Link zu Artists Profil wenn registriert)rating: Number | NULL (Durchschnittliche Bewertung)comment: String | NULL (Viewer-Kommentare)created_at/updated_at/edited_at: Timestamps
RLS: Viewer (via participant_token) können eigene Entries editieren
Queue / Warteschlange
Sortierte Liste aller 'waiting' Entries in einer Session. Die Sortierung bestimmt, welche Songs als nächstes gespielt werden.
Mechanik:
- Free Entries: Sortiert nach
created_at - Paid Entries: Nach
paid_amount_eur_centsDESC (höchstes Gebot zuerst) - Boosts: Erhöhen
queue_positionviadesired_position
Queue-Position ist relativ: Wenn Entry 1 → played, verschieben sich alle anderen up.
Queue-Boost / Positioni-Boost
Kostenpflichtige Upgrade, um eine Entry höher in der Queue zu positionieren.
Preis-Berechnung (lib/pricing.ts):
skip_to_position_N = max(
min_skip_price_eur_cents,
ceil(topBid_at_position_N × (1 + min_increment_pct / 100))
)
Beispiel: Session mit min_skip_price = 100 EUR-Cents, min_increment_pct = 20:
- Position 1 hat Bid = 500 Cents
- Zum Skip nach Position 1:
max(100, ceil(500 × 1.20)) = 600 Cents
Safety Cap: MAX_PRICE_CENTS = 1.000.000 (10.000 EUR)
Flow:
- Viewer klickt "Skip zu Position N"
createCheckoutSessionberechnet Preis- Stripe Checkout Session wird erstellt
- Nach Payment →
stripeWebhook→insert_paid_entry_atomicRPC - Entry wird in Queue verschoben
Breakout (Outcome-Type)
Der höchste Qualitäts-Status für einen Song in einer Session.
3 Outcome-Typen (via BreakoutOutcome Enum):
'breakout': Klarer Gewinner'upcoming': Top 3, aber kein klarer Gewinner'no_winner': <15 Community-Votes (ungültige Runde)
Breakout-Definition (aus computeBreakoutResults.mts):
- ≥15 Community-Votes in Production (≥1 in Dev)
- ≥10 Prozentpunkte Vorsprung auf Platz 2
Wichtig: Ein Artist, der 2× Upcoming in verschiedenen Sessions erreicht, steigt automatisch zum vollen Breakout-Status auf (geplantes Feature, noch nicht im Code).
Outcome für Artist-Profil:
'breakout'→ Sofort Badge + 1 Boost-Token verdient'upcoming'→ Badge; bei 2× automatisch →'breakout''no_winner'→ Keine Rewards
Upcoming (Zweit-Status)
Top 3 einer Session, aber nicht klarer Gewinner.
Mechanik:
- Wird automatisch vergeben wenn ≥15 Votes aber <10pp Vorsprung auf Platz 2
- 2× Upcoming in verschiedenen Sessions = zählt als 1× Breakout für Qualification
Boost-Tokens: 1× Upcoming → 0 Tokens; aber 2× Upcoming-Pair → 2 Tokens verdient
Breakout Phase (Session State)
Das Stadium eines Breakout-Votings innerhalb einer Session.
Enum (BreakoutPhase):
'inactive': Breakout-Runde nicht gestartet'community_voting': Zuschauer voten (live 2–3 Minuten)'creator_voting': Creator wählt Top 3 oder Favorit (1–2 Minuten)'completed': Ergebnisse berechnet, Outcomes vergeben
Ablauf:
- Session aktiv → Community-Voting startet automatisch
- Nach Timer → Phase wechselt zu
creator_voting - Creator trifft Entscheidung → RPC berechnet Finals
- Phase =
completed, Outcomes inbreakout_results
Entry Type
Kategorisierung einer Entry nach Bezahlstatus.
Enum (EntryType):
'standard': Kostenlose Einreichung (bisfree_entries_per_viewerLimit)'priority': Kostenpflichtige Einreichung (Queue-Boost)
Logik: submitEntry RPC setzt entry_type basierend auf Payment-Status
Entry Status
Lebenszyklus-State eines Songs in der Queue.
Enum (EntryStatus):
'waiting': In der Warteschlange, noch nicht gespielt'playing': Gerade jetzt abgespielt'played': Abspiel komplett, Voting finalisiert'removed': Manuell gelöscht von Creator oder Content-Moderation
State Diagram:
waiting → playing → played
↓
removed (jederzeit)
Payment Mode
Kategorisierung der Zahlungs-Quelle für eine Entry.
Enum (PaymentMode):
'entry_fee': Gebühr zum Einreichen (später)'buy_first': Bezahlte Position 1 (später)'skip_to_n': Bezahlter Skip zu Position N (AKTUELL IMPLEMENTIERT)
Aktuell: Nur skip_to_n ist live. Andere sind Placehodler für zukünftige Features.
Participant Token
Eindeutige anonyme ID für Viewer (nicht Creator/Artist).
Technisch:
- UUID generiert beim ersten Besuch
- Gespeichert in
localStorage['breakout_participant_token'] - Persistent über Browser-Sessions
- Wird benutzt für:
- Deduplizierung von Votes (max 1 Vote/Token)
- Kostenloses Einreichungs-Limit (
free_entries_per_viewer) - Anonyme Session-Teilnahme (kein Login nötig)
RLS: Supabase akzeptiert participant_token in Anon-Kontext
Stream Platform
Das Broadcast-Medium, das ein Creator nutzt.
Enum (StreamPlatform):
'twitch'— Twitch.tv'youtube'— YouTube Live'kick'— Kick.com'tiktok'— TikTok Live'instagram'— Instagram Live'other'— Custom Stream
Zweck: Linking zurück zu Creator's Main-Stream, Social Proof
Nutzergruppen
Creator
Streamer, der Live-Sessions hostet. Verdient durch Queue-Boosts und Benutzungs-Gebühren. Im Tournament können Top-Creator Jury-Mitglieder sein.
Technisch (creators Table + users Table):
id: UUID (Creator-spezifisch)user_id: Foreign Key zu Supabaseuserscreator_name: Unique handle (z.B. @musikzauberer)display_name: Public Namestripe_account_id: Stripe Connect Account (für Payouts)stripe_payouts_enabled: Booleandefault_min_entry_price: EUR-Cents Standarddefault_min_skip_price: EUR-Cents Standarddefault_min_increment_pct: Integer Standardcommission_override_bps: Integer | NULL (Basis-Punkte, z.B. 500 = 5%)stats_cache: JSON (Breakouts, Sessions, Earnings)
Auth: Creator Auth via Supabase (separate User-Pool von Artists)
Artist
Musiker, der Songs einreicht. Verdient indirekt durch Exposure und kann Breakout-Status erreichen.
Technisch (artists Table + users Table):
id: UUID (Artist-spezifisch)user_id: Foreign Key zu Supabaseusersartist_name: Unique handledisplay_name: Public Nameparticipant_token: UUID | NULL (verbunden mit anonyem Viewer-Account)song_library_links: Array von Spotify/Apple Music/SoundCloud Linkssocial_links: JSON (Instagram, TikTok, Twitter, YouTube, Website)music_links: JSON (Spotify, Apple Music, SoundCloud)stats_cache: JSON (Breakouts, Upcomings, Plays, Sessions)genre: String | NULL (Primary Genre)
Auth: Artist Auth via Supabase (separate von Creator)
Registrierung: Artists können anonym Entries einreichen, dann später ein Profil erstellen
Viewer / Zuschauer
Community-Mitglied, der an Sessions teilnimmt, für Songs votet und Musik entdeckt.
Identifikation:
- Keine Accounts nötig
- Identifiziert via
participant_token - Können kostenlosen Entries einreichen (bis Limit)
- Können voten in Breakout-Runden
RLS: Anon-User können lesen (active Sessions, öffentliche Queue), schreiben limitiert
A&R (Artist & Repertoire)
Vertreter von Labels/Publishern, der neue Talente scouted. Später kann breakout.now A&R-Dashboard mit Filtered Artist-Views anbieten.
Status: Geplant (Phase 4), noch nicht implementiert
Breakout Voting System
Community Voting Phase
Live-Abstimmung der Zuschauer über beste Songs.
Mechanik (castBreakoutVote.mts):
- Breakout-Runde startet → Phase =
community_voting - Jeder Viewer mit
participant_tokenkann 1× voten - Vote wird in
breakout_votesgespeichert (dedupliziert via(participant_token, round_id)) - Nach Timer (z.B. 2–3 Min) → Phase wechselt zu
creator_voting
Sicherheit: Advisory Locks verhindern doppelte Votes
Creator Voting Phase
Creator (Host) trifft final Entscheidung.
Mechanik (computeBreakoutResults.mts):
- Nach Community-Voting kann Creator:
- Top 1 Song als Favorit wählen, ODER
- Top 3 Songs wählen
- Creator-Wahl wird in
breakout_rounds.creator_pick_entry_idgespeichert - Entscheidungslogik:
- Wenn Creator Top 3 wählt → zusätzliche Qualifizierung
- Wenn Creator außerhalb Top 3 wählt → eigene Entscheidung steht
BreakoutOutcome
Final-Status einer Entry nach Voting.
Typen (Enum):
'breakout': Klarer Gewinner'upcoming': Top 3, kein klarer Gewinner'no_winner': <15 Votes
Berechnung:
if (community_votes >= 15) {
if (first_place_pct >= second_place_pct + 10pp) {
outcome = 'breakout'
} else {
outcome = 'upcoming'
}
} else {
outcome = 'no_winner'
}
Hard Gates (Qualification)
Mindestanforderungen für Artist-Tournament-Eingangsticket.
Regel (aus Qualification-Updated):
- UND: 1× Breakout ODER 2× Upcoming (verschiedene Sessions)
- UND: Mind. 3 bewertete Entries in verschiedenen Sessions
Effekt: Filtert vorbei-einsichtige "One-Hit-Wunder" Artists
Reward-Systeme
Boost Token
Kostenlose Gutschrift für höhere Queue-Position, verdient durch Quality-Achievements.
Technisch (breakout_boost_tokens Table):
id: UUIDartist_id: Foreign Keysource_type: Enum ='breakout' | 'upcoming_pair'source_achievement_id: UUID | NULL (Link zuartist_achievements)source_achievement_id_2: UUID | NULL (für Upcoming-Pair)earned_at: Timestampexpires_at: Timestamp (90 Tage)used_at: Timestamp | NULLused_for_entry_id: UUID | NULL (welche Entry den Token genutzt hat)
Verdienung:
- 1× Breakout → 1 Token
- 2× Upcoming in verschiedenen Sessions → 2 Tokens
Nutzung:
- Artist kann Token kostenlos anwenden via
freeBoost.mts - Setzt
desired_positionohne Kosten
Technische Infrastruktur
Supabase
Backend-as-a-Service mit PostgreSQL, Auth, Realtime, Storage.
Verwendung in breakout.now:
- Auth: Creator + Artist User-Pools
- Database: 14 Tables + Enums
- Realtime: Phoenix Channels für Live-Updates
- Storage: "tracks" Bucket (private, Audio-Files)
Client: @supabase/supabase-js in lib/supabase.ts
Netlify Functions
Serverless Functions für Critical Business Logic (atomare Payments, Votes).
13 Functions (alle in netlify/functions/):
| Funktion | Trigger | Zweck |
|---|---|---|
submitEntry.mts |
POST /api/submitEntry | Free Entry via insert_queue_entry_atomic RPC |
createCheckoutSession.mts |
POST /api/checkout | Stripe Session mit Idempotency-Key |
stripeWebhook.mts |
Stripe Event | Payment → Atomic Insert |
createConnectAccount.mts |
POST /api/connectAccount | Stripe Connect Onboarding |
stripeConnectWebhook.mts |
Stripe Connect Event | Account Refresh |
getSignedUrl.mts |
POST /api/signedUrl | Audio Playback URL (3600s Expiry) |
cleanupStorage.mts |
Cron (daily) | Delete Stale Audio (7+ days) |
castBreakoutVote.mts |
POST /api/vote | Vote Atomicity |
computeBreakoutResults.mts |
POST /api/computeResults | Final Rankings + Outcomes |
editEntry.mts |
POST /api/editEntry | Edit Queue Entry |
freeBoost.mts |
POST /api/freeBoost | Apply Boost Token |
processWeeklyPayouts.mts |
Cron (weekly) | Stripe → Creator Batch |
devSeed.mts |
POST /api/seed | Test-Daten (nur Dev) |
Pattern: Advisory Locks in RPCs für Atomarität, Service Role Key für RLS Bypass
Supabase RPC (Remote Procedure Calls)
PostgreSQL Functions aufgerufen vom Frontend/Functions via Supabase Client.
Kritische RPCs:
insert_queue_entry_atomic: Free Entry mit Lockinsert_paid_entry_atomic: Payment + Entry mit Lockcompute_breakout_results: Final Calculations
Stripe
Payment Processor für Queue-Boosts.
Flow:
createCheckoutSession→ Stripe Session ID- Frontend redirect zu Stripe Checkout
- User zahlt
- Stripe Event →
stripeWebhook→ RPC Insert - Entry moved in Queue
Payout: Stripe Connect für Creator Withdrawals
Stripe Connect
Marketplace-Payout System für Creators.
Flow:
- Creator autorisiert Stripe Connect Account
createConnectAccountgeneriert Link- Payouts werden weekly via
processWeeklyPayoutsverarbeitet - Plattformgebühr = abgezogen, Creator erhält Netto
Business-Konzepte
Revenue Split
Aufteilung des Transaktionsumsatzes.
Struktur (Beispiel: €100 Queue-Boost):
- Brutto: 100 EUR
- Stripe Fee: ~3 EUR
- Plattformgebühr (gestaffelt):
- 0–500€ Monat: 15% = 15 EUR
- 501–1.000€ Monat: 10% = 10 EUR
- Etc.
- Creator netto: 100 - 3 - Fee = z.B. 82 EUR
Rating Criteria / Bewertungskriterien
Custom-Bewertungsskala pro Creator.
Technisch (rating_criteria + entry_ratings Tables):
- Creator definiert
name+description(z.B. "Production Quality", "Originality") - Viewer geben Scores (z.B. 1–5)
entry_ratingsspeichert individual Scores- Durchschnitt wird in
queue_entries.ratingcached
Artist Achievements
Historisches Log von Breakout/Upcoming Ergebnissen.
Technisch (artist_achievements Table):
id: UUIDartist_id: Foreign Keybreakout_result_id: Link zu Resultoutcome: Enum ='breakout' | 'upcoming'achieved_at: Timestamp
Zweck: Tracking für Qualification (2× Upcoming = Breakout)
Glossar-Links
- Executive Summary — Tech Stack & Business-Overview
- Stakeholder Map — Wer braucht wen
- Siehe auch
apps/web/src/lib/types.tsfür vollständige Type Definitions
Letztes Update: 16.02.2026
Status: Aligned mit Codebase v42-migrations