Communitygithub.com

timerise-ai/digital-signage

Agent-Fähigkeit: Baue ein Digital-Signage-Modul – Medienbibliothek, bildschirmspezifische Wiedergabelisten, Display-Registrierung, PIN- und Provisioning-URL-Gerätekopplung, Vollbild-TV-Player mit Wiedergabe-Stall-Wiederherstellung, Bildschirmzustand und Fernsteuerung – in Next.js App Router auf Firestore oder Supabase.

Was ist digital-signage?

Diese Fähigkeit bietet ein vollständiges Digital-Signage-Modul für Next.js App Router, das auf Firestore (Firebase) oder Supabase (Postgres) läuft. Es umfasst eine Medienbibliothek, bildschirmspezifische Wiedergabelisten, eine Display-Registrierung, PIN- und Provisioning-URL-basierte Gerätekopplung sowie einen robusten Vollbild-TV-Player, der Abstürze und eingefrorene Frames erkennt und automatisch überspringt. Der Player läuft auf einem stabilen 30–60 Sekunden Polling (kein Streaming), um Netzwerkausfälle zu überleben, und sendet Telemetriedaten sowie empfängt Befehle über denselben API-Kanal. Die Architektur behandelt das Display als nicht vertrauenswürdiges, unbeaufsichtigtes Gerät: Es erhält ein pro Display eindeutiges, widerrufbares Token, und alle Inhaltsänderungen werden serverseitig validiert. Ziel ist es, ein zuverlässiges, wartungsarmes System für physische Bildschirme in öffentlichen Räumen zu schaffen, bei dem ein eingefrorenes Bild nicht länger als eine Woche unbemerkt bleibt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/digital-signage

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Digital Signage – Displays + Werbung

Ein Bildschirm an einem Ort ist keine Webseite. Er läuft monatelang unbeaufsichtigt auf einem billigen TV-Stick, niemand beobachtet die Konsole, und die Fehlerart ist ein eingefrorenes Bild, das eine Woche lang niemand bemerkt. Jede Entscheidung unten existiert, um das zu überleben.

Diese Fähigkeit enthält ein komplettes Modul: Admin-CRUD für Medien und Wiedergabelisten, ein Display-Register, PIN- und Provisioning-URL-Kopplung, einen Vollbild-Player und die operative Schicht (Zustand, Vorschau, Fernsteuerung), die es verwaltbar macht.

Verwendung

Aufbau oder Erweiterung von Bildschirmen, die Medien in einem physischen Raum in einer Schleife abspielen, auf Next.js App Router mit Firestore oder Supabase/Postgres.

Wann NICHT verwenden

  • Web-Anzeigenauslieferung (Impressionen, Gebote, Tracking-Pixel, Drittanbieter-Tags) – ein anderes Problem mit anderer Infrastruktur.
  • Interaktive Kioske, bei denen der Benutzer tippt, um Transaktionen durchzuführen. Signage ist unidirektional.
  • Ein einzelnes eingebettetes Video auf einer Marketingseite. Verwende ein <video>-Tag.
  • Generisches Next.js, CMS oder Auth-Setup – wird als vorhanden angenommen.

Architektur

 ADMIN (browser)                     SERVER                      DEVICE (TV)
 ─────────────────                   ──────                      ───────────
 media upload ──────────────► object storage ◄──── public/signed URL ─┐
 ad CRUD ─────────┐                                                   │
 playlist edit ───┼──► /api/admin/*  ──► ads + displays ──┐           │
 issue command ───┘      (staff auth)      (scoped)       │           │
                                                          ▼           │
 pair screen ◄──── PIN ────────────► /api/display/pair    │           │
                                     mints per-display    │           │
                                     token                ▼           │
                                    /api/display/playlist ─── poll ───┤
                                     ▲ resolves adIds → ads           │
                                     └── carries telemetry up,        │
                                         commands down          player loop

Ein Anforderungstyp trägt die gesamte Laufzeit: Das Gerät fragt /api/display/playlist ab, sendet Telemetriedaten hoch und erhält Inhalte und Befehle herunter. Alles Betriebliche reist über diesen Kanal.

Kritische Tatsachen – vor dem Design lesen

  1. Die Wiedergabeliste ist ein geordnetes Array auf dem Display, keine separate Entität. display.adIds: string[] ist die Wiedergabeliste – Reihenfolge ist kostenlos, keine Joins, ein Lesevorgang. Führe eine eigenständige Wiedergabelisten-Entität nur ein, wenn derselbe Inhalt auf mehreren Bildschirmen laufen muss; siehe data-model.md für den Kompromiss und extensions.md für die Migration.
  2. Pollen; nicht streamen. Ein Poll von 30–60 s ist günstiger, überlebt schlafende Netzwerk-Stacks und verbindet sich automatisch neu. Echtzeit ist ein optionales Upgrade, nicht die Basislinie. Cache die Antwort mit einem ETag, sonst bezahlst du für einen vollständigen Lesevorgang pro Bildschirm pro Poll.
  3. Medien-Uploads gehen vom Browser direkt zum Speicher, niemals über eine API-Route. Route-Handler haben Body-Größenbeschränkungen und verbrauchen Rechenleistung beim Proxy von Bytes.
  4. Das Gerät ist nicht vertrauenswürdig und unbeaufsichtigt. Es enthält eine langlebige Anmeldeinformation in localStorage auf Hardware, zu der jeder Zugang hat. Diese Anmeldeinformation muss pro Bildschirm und widerrufbar sein.
  5. Der Player darf niemals anhalten können. Jedes Medienelement erhält ein Timeout, einen Fehlerhandler und eine Möglichkeit zum Überspringen. Ein defektes Asset wird vorgerückt; es blockiert nicht.

Harte Regeln

Leite das Poll-Intervall niemals aus dem Render-Zustand ab. Polle in einem stabilen Intervall und lese den Folienzustand aus einem Ref. Ein Timer, dessen Effekt vom Folienindex abhängt, wird bei jeder Folie zerstört und neu erstellt, sodass eine Aktualisierung, die länger als eine Folie dauert, nie ausgelöst würde; der Verhaltensvertrag bindet das Timing des Polls an die Wanduhrzeit.

Überlaste niemals ein boolesches Feld mit sowohl „pausiert“ als auch „gelöscht“. Verwende active für die Absicht des Bedieners und ein separates deletedAt für den Lebenszyklus, sonst erscheint ein gelöschtes Element wieder, sobald jemand es wieder einschaltet.

Vertraue niemals einem client-seitig gelieferten Mandanten/Standort-Bereich. Leite ihn serverseitig von der authentifizierten Mitarbeiter-Sitzung oder der Display-Zeile, auf die das Token aufgelöst wird, ab und erzwinge ihn auf jeder [id]-Route – gib 404, nicht 403, zurück, damit IDs nicht sondiert werden können.

Stelle niemals ein gemeinsames Token für jeden Bildschirm aus. Minte bei der Kopplung ein pro Display eindeutiges Token, speichere nur seinen Hash und mache den Widerruf zu einer einzelnen Zeilenaktualisierung.

Starte den Zeitgeber für die Dauer eines Bildes niemals vor onLoad. Auf einem langsamen Fernseher läuft die Folie sonst ab, bevor sie sichtbar ist.

Trage dauerhaften Bildschirmzustand niemals in einem einmaligen Befehl. Leere und Übernahme müssen den täglichen Neustart des Geräts und einen Stromausfall überleben – liefere sie als Zustand bei jedem Poll (mode) und behalte den quittierungsgelöschten Befehls-Kanal für echte einmalige Befehle wie Neuladen. Und jeder Befehl, dessen Wirkung ein Neuladen ist, muss seine Quittung vor dem Neuladen speichern, sonst liefert der Server ihn für immer erneut aus.

Schnellstart

  1. Fülle den Nahtstellenvertrag für deine App aus und bestätige die Domänenumbenennung – adaptation.md.
  2. Modelliere die Entitäten und wähle Array vs. Verknüpfungstabelle – data-model.md.
  3. Erstelle Tabellen/Sammlungen, Indizes, Sicherheitsregeln und den Medien-Bucket – firestore-backend.md oder supabase-backend.md.
  4. Baue die Geräte- und Admin-Endpunkte, einschließlich Kopplung und Token-Verifikation – api-routes.md.
  5. Kopple einen Bildschirm – pairing.md – und füge dann die Player-Schleife ein – player-runtime.md.
  6. Baue das Back-Office: Medienbibliothek, Display-Liste, Wiedergabelisten-Editor – admin-ui.md.
  7. Füge Zustand, Vorschau und Fernsteuerung hinzu, bevor das System in Betrieb geht – operations.md.
  8. Überprüfe gegen die Verhaltensvertragstabelle in player-runtime.md – ziehe das Netzwerkkabel, lösche die aktuelle Werbung während der Schleife, starte einen Neuladevorgang – und veröffentliche die Player-Maschinen-Tests als Regressionsabsicherung.

Referenzverzeichnis

Lade die Referenz, die mit den Auslöse-Schlüsselwörtern übereinstimmt. Für neuartiges Design lies zuerst data-model.md.

Code in api-routes.md und operations.md ist gegen Firestore als kanonisches Backend geschrieben; supabase-backend.md definiert jede Ersetzung – die Verknüpfungstabelle, die adIds ersetzt, und SQL-Äquivalente der Dienstfunktionen.

SzenarioAuslöse-SchlüsselwörterReferenz
Einpassen in eine bestehende Appanpassen, umbenennen, Nahtstelle, integrieren, Mandant, Host-Appadaptation.md
Entitäten, Felder, WiedergabelistenformSchema, Modell, Anzeige, Display, Wiedergabeliste, Verknüpfungstabelle, weiches Löschendata-model.md
Firestore/Firebase-BackendFirestore, firebase-admin, Sicherheitsregeln, zusammengesetzter Index, Firebase Storagefirestore-backend.md
Supabase/Postgres-BackendSupabase, Postgres, RLS, Migration, Storage-Bucket, Echtzeitsupabase-backend.md
Endpunkte, Kopplung, Token, CachingAPI-Route, Kopplung, PIN, Token, ETag, Bereichsprüfung, Zodapi-routes.md
Einen Bildschirm koppelnKopplung, PIN, Provisioning-URL, Hub, Anmeldeinformation, entkoppelnpairing.md
Die TV-Player-SchleifePlayer, Schleife, Überblendung, Video-Stall, Drehung, Hochformat, Wachhalte-Sperre, offlineplayer-runtime.md
Back-Office-BenutzeroberflächeAdmin, Hochladen, Medienbibliothek, Wiedergabelisten-Editor, Provisioning-URLadmin-ui.md
Zustand, Vorschau, FernsteuerungHeartbeat, zuletzt gesehen, offline, Vorschau, Neuladen, leeren, Notfall-Übernahme, Prüfprotokolloperations.md
Zeitplanung, Wiederverwendung, BerichterstattungTageszeit-Steuerung, Startdatum, Kampagne, gemeinsame Wiedergabeliste, Wiedergabenachweis, Voraus-Caching, Multi-Zoneextensions.md
Warum sich die Vorlagen von einem naiven Port unterscheidenHerkunft, Hauptbuch, Begründung, behalten, hinzugefügtprovenance.md

Verwandte Skills