Skip to main content
Petanque Life
← Back to all features
15

Mobile & Fan Experience

133 features · 12 subsystems

Mobile applications, spectator/fan features, gamification, and community engagement tools.

Mobile Application

F15.01
Shipped
How it works
  • F15.01.01 Shipped

    Cross-platform app (iOS, Android, Web) (React Native/Expo)

    ✅ PL-F1501a
  • F15.01.02 Shipped

    Player mobile app (profile, competitions, results, rankings)

    ✅ PL-F1501a
  • F15.01.03 Shipped

    Official mobile app (match management, score entry)

    ✅ PL-F1501a
  • F15.01.04 Shipped

    Club admin mobile app (member management, communication)

    ✅ PL-F1501a
  • F15.01.05 Shipped

    Spectator mobile app (live scores, schedule, venue info)

    ✅ PL-F1501a
  • F15.01.06 Shipped

    Offline mode (score entry without connectivity, sync later)

    ✅ PL-F1501b
  • F15.01.07 Shipped

    Push notifications

    ✅ PL-F1501b
  • F15.01.08 Shipped

    QR code scanner (license verification, check-in)

    ✅ PL-F1501b
  • F15.01.09 Shipped

    GPS-based nearby venue/competition finder

    ✅ PL-F1501b
  • F15.01.10 Shipped

    Dark mode and accessibility settings

    ✅ PL-F1501b

Live Match Experience

F15.02
Planned
How it works
  • F15.02.01 Shipped

    Real-time live scores across all courts

    ✅ PL-F1502a
  • F15.02.02 Shipped

    Match timeline (point-by-point history)

    ✅ PL-F1502a
  • F15.02.03 Shipped

    Court view (visual representation of ongoing matches)

    ✅ PL-F1502a
  • F15.02.04 Shipped

    Follow specific player/team (personalized updates)

    ✅ PL-F1502a
  • F15.02.05 Shipped

    Live commentary feed

    ✅ PL-F1502b
  • F15.02.06 Shipped

    Score alerts and notifications

    ✅ PL-F1502b
  • F15.02.07 Shipped

    Multi-match view (watch multiple courts)

    ✅ PL-F1502b
  • F15.02.30 Shipped

    Adaptive bitrate stream profile (HLS/DASH renditions, server-managed)

    ✅ PL-T219
  • F15.02.31 Shipped

    Picture-in-picture support flag per stream profile

    ✅ PL-T219
  • F15.02.32 Shipped

    Commentary language toggle (Accept-Language sortering, default-track)

    ✅ PL-T219
  • F15.02.33 Shipped

    Stream geo-block policy (ISO-3166-1 alpha-2, expiry, requires_auth)

    ✅ PL-T219

Community Features

F15.03
Planned
How it works
  • F15.03.01 Shipped

    Player profile pages (public)

    ✅ PL-F1503a
  • F15.03.02 Shipped

    Club profile pages (public)

    ✅ PL-F1503a
  • F15.03.03 Shipped

    Follow players and clubs

    ✅ PL-F1503a
  • F15.03.04 Shipped

    Activity feed (followed players' results, upcoming matches)

    ✅ PL-F1503a
  • F15.03.05 Shipped

    Find-a-player (looking for team members)

    ✅ PL-F1503b
  • F15.03.06 Shipped

    Find-a-club (new player looking for local club)

    ✅ PL-F1503b
  • F15.03.07 Shipped

    Forums / discussion boards per club, region, topic

    ✅ PL-F1503b
  • F15.03.08 Shipped

    Event reviews and photos sharing

    ✅ PL-F1503b
  • F15.03.20 Shipped

    Multilingual forums (locale-default + i18n_strings, BCP-47-validering)

    ✅ PL-T219
  • F15.03.21 Shipped

    Cross-locale forum discovery (locale=* aggregerar alla språk)

    ✅ PL-T219
  • F15.03.22 Shipped

    Forum auto-moderation (regel-baserad: profanity-regex, link-spam, all-caps, spam-score)

    ✅ PL-T219
  • F15.03.23 Shipped

    Forum mentions + reactions (@user → push-pipeline, emoji-toggle på posts)

    ✅ PL-T219

Gamification

F15.04
Planned
How it works
  • F15.04.01 Shipped

    Achievement badges (first competition, 100 matches, etc.) — PL-F1504a

    ✅ PL-F1504a
  • F15.04.02 Shipped

    Milestone tracking and celebrations — PL-F1504a

    ✅ PL-F1504a
  • F15.04.03 Shipped

    Prediction game (predict competition outcomes) — PL-F1504a

    ✅ PL-F1504a
  • F15.04.04 Shipped

    Fantasy petanque (build dream team, earn points) — PL-F1504a

    ✅ PL-F1504a
  • F15.04.05 Shipped

    Leaderboards (most active player, most competitions, etc.) — PL-F1504a

    ✅ PL-F1504a
  • F15.04.06 Shipped

    Challenge system (challenge another player to a match) — PL-F1504b

    ✅ PL-F1504b
  • F15.04.07 Shipped

    Streak tracking (consecutive wins, active weeks) — PL-F1504b

    ✅ PL-F1504b
  • F15.04.08 Shipped

    Daily/weekly challenges (community-wide skill challenges) — PL-F1504b

    ✅ PL-F1504b
  • F15.04.09 Shipped

    Club challenges (club vs club in weekly mini-competitions) — PL-F1504b

    ✅ PL-F1504b
  • F15.04.10 Shipped

    Seasonal quests (play X matches, visit Y venues, enter Z tournaments) — PL-F1504b

    ✅ PL-F1504b
  • F15.04.11 Shipped

    XP and level system (based on activity, not just wins)

    ✅ PL-F1504c
  • F15.04.12 Shipped

    Personal bests tracking (best ELO, best tournament result, longest streak)

    ✅ PL-F1504c
  • F15.04.13 Shipped

    Fan predictions for live matches (predict score, earn points)

    ✅ PL-F1504c
  • F15.04.14 Shipped

    Pick'em brackets (predict entire tournament outcomes)

    ✅ PL-F1504c
  • F15.04.15 Shipped

    Celebration UX motor — proportional confetti / banner / badge primitives, registry-governed events, max-1-major-per-session rate limit, audit gate

    ✅ PL-T163
  • F15.04.16 Shipped

    Reduced-motion + background-safe celebration playback (web prefers-reduced-motion + native AppState)

    ✅ PL-T163
  • F15.04.17 Shipped

    Personal-best comparison primitive with stagger animation

    ✅ PL-T163

Accessibility & Inclusion

F15.05
Planned
How it works
  • F15.05.01 Shipped

    Multi-language interface (French, English, Spanish, + federation languages)

    ✅ PL-F1505a
  • F15.05.02 Shipped

    Screen reader compatibility (WCAG 2.1 AA)

    ✅ PL-F1505a
  • F15.05.03 Shipped

    High contrast mode

    ✅ PL-F1505a
  • F15.05.04 Shipped

    Font size adjustment

    ✅ PL-F1505a
  • F15.05.05 Shipped

    Simplified interface mode (for non-technical users)

    ✅ PL-F1505b
  • F15.05.06 Shipped

    Age-appropriate interfaces (youth vs. adult)

    ✅ PL-F1505b
  • F15.05.07 Shipped

    Right-to-left language support

    ✅ PL-F1505b

Onboarding & Discovery

F15.06
Planned
How it works
  • F15.06.01 Shipped

    New player onboarding wizard — PL-F1506a

    ✅ PL-F1506a, ✅ PL-T308 (premium editorial multi-step flow: animerad welcome-sekvens, swipe-stack mobil + split-screen desktop med crossfade <StepIllustration>, persistent draft i AsyncStorage, tenant-aware licens-katalog, konfetti-celebration via shared useCelebrate('onboarding.complete') med reduced-motion-glow, ProgressDots med accessibilityRole="progressbar", focus-shift per steg-shift, skip-affordance på notifikations- och preferenssteg)
  • F15.06.02 Shipped

    "Getting started with petanque" content — PL-F1506a

    ✅ PL-F1506a
  • F15.06.03 Shipped

    Find your nearest club (location-based) — PL-F1506a

    ✅ PL-F1506a
  • F15.06.04 Shipped

    Try petanque events listing (beginner-friendly) — PL-F1506a

    ✅ PL-F1506a
  • F15.06.05 Shipped

    Rules overview for newcomers — PL-F1506b

    ✅ PL-F1506b
  • F15.06.06 Shipped

    Equipment guide for beginners — PL-F1506b

    ✅ PL-F1506b
  • F15.06.07 Shipped

    Sport ambassador program — PL-F1506b

    ✅ PL-F1506b
  • F15.06.10 Shipped

    Public club discovery map (PublicClubProfile + 2dsphere, bbox-search, antimeridian-split)

    ✅ PL-T219
  • F15.06.11 Shipped

    Pickup-game schedule per club (PickupSlot + DateOverride, klubblokal-tid)

    ✅ PL-T219
  • F15.06.12 Shipped

    Visitor-friendly club flag (filter på publik karta + i app)

    ✅ PL-T219
  • F15.06.20 Shipped

    Viewer preference center (ViewerPreference: follow + push + digest, get-or-default)

    ✅ PL-T219
  • F15.06.21 Shipped

    Per-player follow + match alerts (cap 200 / 100 / 50, score-tröskel)

    ✅ PL-T219
  • F15.06.22 Shipped

    Per-club follow + news feed (digest-källa)

    ✅ PL-T219
  • F15.06.23 Shipped

    Personalised digest (DigestBuilderService: daily/weekly, idempotent dispatch-log)

    ✅ PL-T219
  • F15.06.24 Shipped

    Quiet hours + push-cadence grouping (IANA-tz, batched_5min/15min/60min)

    ✅ PL-T219

My Equipment

F15.07
Planned

Inspired by golf (club fitting) and bowling (ball specs) — track your boules and equipment.

How it works
  • F15.07.01 Shipped

    Boule inventory (brand, model, weight, diameter, hardness, striation pattern) — PL-F1507a

    ✅ PL-F1507a
  • F15.07.02 Shipped

    Boule serial number tracking (for homologation verification) — PL-F1507a

    ✅ PL-F1507a
  • F15.07.03 Shipped

    Equipment photo gallery — PL-F1507a

    ✅ PL-F1507a
  • F15.07.04 Shipped

    Performance notes per boule set (which set for which conditions) — PL-F1507a

    ✅ PL-F1507a
  • F15.07.05 Shipped

    Equipment wear tracking (usage log, matches played, surface type, total matches counter) — PL-F1507b

    ✅ PL-F1507b
  • F15.07.06 Shipped

    Equipment wishlist and comparison (wishlist CRUD, compare 2–5 sets side-by-side) — PL-F1507b

    ✅ PL-F1507b
  • F15.07.07 Shipped

    "What boules do the pros use" — equipment profiles of top players (search, filter, verified badge) — PL-F1507b

    ✅ PL-F1507b

Weather & Conditions

F15.08
Planned

Inspired by golf and sailing — outdoor sport conditions matter.

How it works
  • F15.08.01 Shipped

    Weather forecast for upcoming competitions (integrated from weather API) — PL-F1508

    ✅ PL-F1508
  • F15.08.02 Shipped

    Weather conditions at venue (temperature, wind, humidity, rain risk) — PL-F1508

    ✅ PL-F1508
  • F15.08.03 Shipped

    Terrain condition reporting by venue (crowdsourced: type, condition, hardness, wind, notes, photo) — PL-F1508

    ✅ PL-F1508
  • F15.08.04 Shipped

    "Best time to play" suggestions (playability score 0-100, recommended hours per day) — PL-F1508

    ✅ PL-F1508
  • F15.08.05 Shipped

    Weather-related tips (condition-triggered: surface, wind, temperature, rain matching engine) — PL-F1508

    ✅ PL-F1508
  • F15.08.06 Shipped

    Historical weather data linked to venue analysis (aggregate statistics per club) — PL-F1508

    ✅ PL-F1508

Social & Community Engagement

F15.09

Inspired by Strava, fitness apps, and social sport platforms.

How it works
  • F15.09.01 Shipped

    PL-F1509a

    ✅ PL-F1509a
  • F15.09.02 Shipped

    PL-F1509a

    ✅ PL-F1509a
  • F15.09.03 Shipped

    PL-F1509a

    ✅ PL-F1509a
  • F15.09.04 Shipped

    PL-F1509a

    ✅ PL-F1509a
  • F15.09.05 Shipped

    PL-F1509b

    ✅ PL-F1509b
  • F15.09.06 Shipped

    PL-F1509b

    ✅ PL-F1509b
  • F15.09.07 Shipped

    PL-F1509b

    ✅ PL-F1509b
  • F15.09.08 Shipped

    PL-F1509b

    ✅ PL-F1509b
  • F15.09.09 Shipped

    PL-T098

    Group membership (auto-provision per klubb, opt-in distrikt/federation)
  • F15.09.10 Shipped

    PL-T098

    Nested comments (max djup 2) med @-mentions och reaktioner
  • F15.09.11 Shipped

    PL-T098

    Moderator-roller + ban + promote/demote med admin-only guards
  • F15.09.12 Shipped

    PL-T098

    Join request-flöde för distrikt/federation-grupper
  • F15.09.13 Shipped

    PL-T098

    Content report + moderator-resolve (actioned/dismissed)
  • F15.09.14 Shipped

    PL-T098

    Per-grupp settings (visibility, who-can-post, profanity-flag)
  • F15.09.15 Shipped

    PL-T098

    Push fan-out policy (members/mentions-only/off) — dispatcher log-only, FCM deferred
  • F15.09.16 Shipped

    PL-T098

    GDPR-anonymisering av användarens inlägg + kommentarer
  • F15.09.17 Shipped

    PL-T286

    ✅ PL-T286
  • F15.09.18 Shipped

    PL-T286

    ✅ PL-T286

Augmented Reality & Camera Features

F15.10

AR-powered tools for measuring, learning, detecting, and replaying petanque action on mobile.

How it works
  • F15.10.01 Shipped

    PL-F1510

    ✅ PL-F1510
  • F15.10.02 Shipped

    PL-F1510

    ✅ PL-F1510
  • F15.10.03 Shipped

    PL-F1510

    ✅ PL-F1510
  • F15.10.04 Shipped

    PL-F1510

    ✅ PL-F1510
  • F15.10.05 Shipped

    PL-F1510

    ✅ PL-F1510

Premium Mobile-First UX

F15.11
Planned

Mobile-first redesign av spelar-appen: dual-mode shell (bottom-tab på mobil, sidebar på desktop), hero-baserade startvyer, offline-first licenskort och tenant-branded theming.

How it works
  • F15.11.01 Shipped

    Dual-mode app shell — useDeviceClass({ cutoff: 640 }) växlar mellan mobile bottom-tab-nav (5 slottar: Hemma / Matcher / Ranking / Licens / Mer) och desktop sidebar (260 px) + centrerat innehåll (max 1024 px) utan route-byte eller data-remount. app/src/components/navigation/AppShell.tsx, BottomTabNav.tsx, SidebarNav.tsx.

    ✅ PL-T157
  • F15.11.02 Shipped

    Hero-baserad startsida — nästa match som full-bredd-hero med LinearGradient (primary→secondary), Fraunces display-titel, countdown, CalendarClock/MapPin-meta och sticky CTA. Två-up MiniCards (Licens + Ranking) + senaste resultat + discover-getting-started. Pull-to-refresh. app/src/components/home/PlayerHome.tsx.

    ✅ PL-T157
  • F15.11.03 Shipped

    Fullscreen licenskort — hologram-gradient-ring (primary→secondary→accent), Fraunces display-titel, 220 px QrPlaceholder, valid-until + status-pin, offline-verification-banner. Läser från verifyLicense() som faller tillbaka på signerad JWT-bundle från cache när offline. app/app/(tabs)/license.tsx, app/src/components/license/QrPlaceholder.tsx.

    ✅ PL-T157
  • F15.11.04 Shipped

    Rankings med "Du är #N"-highlight + sparklines — highlight Card ovanför leaderboard med aktuell position + Movement + mini-sparkline; varje RankingRow har position, namn, klubb, Movement-indikator (ArrowUp/Down/Minus) och 56×18 SVG-sparkline. Current-user row har primary-tint-bakgrund + border. app/app/(tabs)/rankings.tsx.

    ✅ PL-T157
  • F15.11.05 Shipped

    Matcher-lista med status-badges — MatchRow med Round-badge (eller LIVE-pin för live-matcher), W/L-badge för finished, CalendarClock+MapPin-meta, score + chevron-CTA. Separata sektioner "Upcoming" och "Recent". app/app/(tabs)/matches.tsx.

    ✅ PL-T157
  • F15.11.06 Shipped

    "Mer"-fliken — overflow-meny för sekundära sektioner (Profile, Equipment, Discover, Search, Community, Weather, Settings). Logged-in identity-card med avatar + tenant-badges, sign-in-CTA för gäster, grupperade rows med ikon-bubbla + description. Logout-knapp längst ned. app/app/(tabs)/more.tsx.

    ✅ PL-T157
  • F15.11.07 Shipped

    Offline-banner på root-nivå — prominent <Banner variant="offline"> med WifiOff-ikon, "senast synkad HH:MM"-text och optional "Sync now"-CTA när pendingCount > 0. Separat från det tunna OfflineIndicator sync-strippen. app/src/components/OfflineBanner.tsx.

    ✅ PL-T157
  • F15.11.08 Shipped

    Tenant-branded ThemeProvider — useTenantBranding()-hook hämtar /me/tenant-profile vid activeTenantId-byte och applicerar theme-objektet via applyTenantTheme(). Caching per tenantId via lastAppliedRef — best-effort, inga fel bubblar upp. app/src/hooks/useTenantBranding.ts.

    ✅ PL-T157
  • F15.11.09 Shipped

    Banner-primitiv — ny <Banner>-komponent med variants info/success/warning/error/offline, optional icon (lucide), title, message, action-button och dismiss. Matchar admin-appens Banner-API men med offline-variant (warning-palett) unikt för app-paradigmet. app/src/components/ui/Banner.tsx.

    ✅ PL-T157
  • F15.11.10 Shipped

    Haptic-feedback-gating per interaktion — useHaptics().fire('selection') på alla bottom-tab-trycky, match-row-trycky, more-entry-trycky; fire('warning') på logout. Respekterar både accessibility-toggle och OS reduce-motion. app/src/hooks/useHaptics.ts.

    ✅ PL-T157
  • F15.11.11 Shipped

    QrPlaceholder — deterministisk 25×25 SVG-bitmap från licens-payload, tre klassiska QR-finder-patterns + FNV-1a-hash-seedad LCG. Dokumenterat ej scanbar; federationens skannare läser license-number från visibel text. Swappbar mot riktig QR-komponent utan ändring av omgivande layout. app/src/components/license/QrPlaceholder.tsx.

    ✅ PL-T157
  • F15.11.12 Shipped

    Pull-to-refresh på alla primärvyer — RefreshControl på Home, Matches, Rankings, License. Tint = colors.primary. Samma callback som initial load() — enhetligt refresh-beteende.

    ✅ PL-T157

Digital scoreboard / live-display (D-SCORE)

F15.12
Planned

> Initiativ **D-SCORE** (`docs/product/scoreboard-analysis.md`), milstolpar `0ad09f7c.m-1` (t-1 backend,

  • F15.12.01 Planned

    Display-datamodell — rena tenant-skopade tabeller display/display_court/display_pairing/display_event (migration 00074_display_core.sql). Enum-CHECKs för status/mode/theme/distance_profile; mjuka event_id/court_ref-referenser (ingen hård FK över domängräns); ingen sponsor/rental-modell i m-1.

    0ad09f7c.m-1.t-1
  • F15.12.02 Planned

    Display-administration (/v1/displays…) — skapa (idempotent, med initial pairing-kod) / lista / hämta / PATCH (If-Match, optimistisk lås → 409) / soft-delete (retired) / PUT …/courts / POST …/pairing / GET …/events. Capability-gated display:manage/display:view; tenant-isolering (404 för främmande tenant).

    0ad09f7c.m-1.t-1
  • F15.12.03 Planned

    Pairing & klient-bootstrap — POST /v1/display-pairings/{code}/claim (oautentiserad device → claim_token + config, engångs, hashad hemlighet), GET …/config (claim_token/display:view), POST …/heartbeat (idempotent, online/offline härlett ur last_seen_at).

    0ad09f7c.m-1.t-1
  • F15.12.04 Planned

    Sys tvärs-tenant flottöversikt — GET /v1/sys/displays (operatör-scope, läs-only): aggregerade antal online/offline/unpaired/retired + rad per display i alla tenants.

    0ad09f7c.m-1.t-1
  • F15.12.05 Planned

    AuthZ-capabilities display:manage/display:view i katalogen, seedade på clubadmin/federation_admin. OpenAPI-först + genererad TS-klient i synk (packages/shared).

    0ad09f7c.m-1.t-1
  • F15.12.06 Shipped

    admin Displayer-sektion (admin/app/displayer) — lista med status-badge färg+ikon+text (online/offline/unpaired/retired) + filter, skapa/para-stepper (namn → org-nod → banor → visningsläge → tema/distans → generera & visa pairing-kod med regenerera), redigera-konfig (PATCH med If-Match) och händelse-tidslinje. Verklig data via den genererade klienten (displaysOps); inga stubbar. Sponsor-steg (m-4) och renderad live-vy (m-2) är medvetet inte med.

    0ad09f7c.m-1.t-2
  • F15.12.07 Shipped

    sys tvärs-tenant flottöversikt (sys/app/flotta) — operatör-scope, läs-only, ingen branding: aggregerade antal + tabell över alla tenants displayer ur GET /v1/sys/displays via genererad klient. Ingen beslutsrätt i tenants konfig.

    0ad09f7c.m-1.t-2
  • F15.12.08 Planned

    SSE live-stream-relä — GET /v1/displays/{id}/stream (text/event-stream): leverantörsneutral in-process-relä av D-COMP:s frysta vokabulär snapshot\

    score|match_status|standings (§5d.2, aldrig score_update/mene_completed/connected/update), projicerat/filtrerat per court_ref mot displayens display_court-mängd. Handshake (claim_token eller same-tenant display:view) före strömmen öppnas → 403 utan auth, 404 främmande tenant. snapshot först (subscribe-före-send); config-PATCH/PUT courts pushar färsk snapshot till anslutna klienter. Mock-stream (?mock=1&mock_courts=…, test/scaffolding) kör D-COMP-fritt. Spec: specs/api/sse/events-display.md. | 0ad09f7c.m-2.t-1
  • F15.12.09 Planned

    Snapshot polling-fallback — GET /v1/displays/{id}/snapshot: materialiserad visnings-ställning (kort-TTL ETag), samma handshake som strömmen, svarar även utan aktivt live-event (senast kända / tom), endast visnings-data (inga internfält). OpenAPI + genererad TS-klient i synk.

    0ad09f7c.m-2.t-1
  • F15.12.10 Shipped

    Fullscreen display-klient (web/app/d/[displayId], shell-lös BYO-skärm) — pairing-vy ("Ange koden"), device-claim (POST /v1/display-pairings/{code}/claim, claim_token i localStorage + X-Display-Claim-Token), SSE-konsument via fetch+ReadableStream.getReader() av det frysta vokabuläret (snapshot\

    score|match_status|standings), tre display-axlar ur config (visningsläge single|hall_overview|rotation|feature_ticker · distans-profil near|medium|far · tema indoor|outdoor), upplösnings-oberoende (vw/vh/clamp) med enorma tabular-nums-siffror, status-badge färg+ikon+text (WCAG 2.2 AA), vit-etikett-branding {logo,name,primary,accent}, offline-resiliens (cachad ställning + "återansluter…" + backoff-reconnect + /snapshot-polling, aldrig blank), cast-mottagar-läge. Sponsor-region reserverad men tom (m-4-gräns). | 0ad09f7c.m-2.t-2
  • F15.12.11 Shipped

    Admin renderad förhandsvisning (admin Displayer-sektion) — samma display-variant-rendering mot displayens config (mode/theme/distans/banor) driven av /stream (admin-bärare) eller mock-strömmen (?mock=1) när inget live-event är kopplat; tydligt märkt demo/tom-ställning, inga hårdkodade siffror, sponsor-region tom. Fyller den yta m-1 medvetet lämnade.

    0ad09f7c.m-2.t-2
  • F15.12.12 Shipped

    Publik oautentiserad projektions-yta — GET /public/scoreboard/{id} + /stream: ett publik-projektions-lager ovanpå m-2:s relä/snapshot, nås av vem som helst med displayens UUID (ingen bearer/claim_token). 200 med endast en dokumenterad allowlist av visnings-data (mode/theme/distance_profile/rotation/event_id, banor, matcher {match_id,status,court_ref,score}, standings publik projektion) + white-label branding-tokens {logo,name,primary,accent}; inga internfält (PII/tenant-interna/aktör-id/responder/pager/audit) — en strikt internfält-strippad delmängd av device-ytan. Kort-TTL cachebar (ETag + Cache-Control max-age); okänd/retired → 404; utan live-data → 200 tom (aldrig blank). Publika strömmen bär samma frysta vokabulär + allowlist. OpenAPI + genererad TS-klient i synk. Registrerad via sanktionerat /public/*-mönster (F1-4, aldrig --no-verify). Ingen ny tabell/kolumn. Spec: specs/api/endpoints/displays.md, specs/api/sse/events-display.md. web/app-konsument-vyer levereras i m-3 t-2/t-3. Sponsor-slot + impression-rollup till F11.03 = m-4 (backend sponsor_slot/impression-beacon/rollup = m-4 t-1; frontend-delen = m-4 t-2: sponsor-regionen renderas ur verklig sponsor-data i display-variantens sponsor-region på device-fullscreen (ScoreboardView), publik web-live-vy (PublicScoreboardClient) och app-spectator-ytan — aldrig platshållare, tom när ingen aktiv slot — och varje visning kallar den idempotenta impression-beaconen (device POST /v1/displays/{id}/sponsor-impression, publik/app POST /public/scoreboard/{id}/sponsor-impression) med en stabil dedup_key per (slot, session, tids-bucket) så reconnect/poll/re-render aldrig dubbelräknas; admin kopplar/redigerar/frikopplar sponsor-slot via ett sponsor-steg i Displayer-steppern + redigera-panelen med live-förhandsvisning, allt via den genererade TS-klienten).

    0ad09f7c.m-3.t-1
  • F15.12.13 Shipped

    Publika konsument-vyer (web + app) ovanpå F15.12.12:s projektion. web: oautentiserad SSR/SEO full-white-label publik event-live-vy (web/app/scoreboard/[displayId]), castbar/fullscreen, aldrig blank (cachad ställning + "återansluter…" + /public-snapshot-polling + backoff). app: publik-spårets Live-matchlista (LIVE-pin ikon+text) + per-match mène-progression härledd ur det frysta vokabuläret via den återanvända scoring-presenter; follow som PERSISTERAS via den rebuildade viewer-follow-primitiven POST/GET/DELETE /v1/me/follow (F15.06.20–22: follow + push + digest, notify_push/notify_digest) så D-PUSH kan konsumera den — notis-LEVERANSEN själv byggs ej här (D-PUSH/D-COMM). + liten klubbadmin para/justera-display on-the-go-yta (capability-gatad display:manage, POST /v1/displays/{id}/pairing + PATCH med If-Match) via den genererade klienten. Migration 00075_viewer_follow.sql (self-scopad /me-yta, ingen display/sponsor/hyr-tabell). Spec: specs/api/endpoints/me-follow.md.

    0ad09f7c.m-3.t-2