Webinar Analyzer
Ein Tool, das rohe Webinar-Exporte in zwei Arten von Antworten verwandelt:
- Pro Webinar — wer kam, wie lange sie blieben, wann sie gingen, wer sie waren, was sie sagten.
- Über alle Webinare hinweg — wächst die Teilnehmerzahl, welcher Slot und welches Format funktionieren, wer immer wieder kommt und welche Lob- und Kritikpunkte immer wieder auftauchen.
Dieser Skill ist stack-neutral. Er spezifiziert Datenverträge, Validierungsregeln, Berechnungen und Diagrammsemantiken. Implementieren Sie ihn in dem Web-Stack Ihrer Wahl (Flask/Django/FastAPI + Postgres + eine beliebige Charting-Bibliothek; Streamlit; ein Notebook; ein BI-Tool). Die Referenzimplementierung, aus der diese Anweisungen extrahiert wurden, ist eine Flask + PostgreSQL + ApexCharts App.
Bevor Sie etwas bauen: das Aufnahmegespräch
Nehmen Sie nicht einfach Zoom an. Nehmen Sie nicht einfach YouTube an. Der häufigste Fehler bei diesem Tool ist, das Exportformat einer einzigen Plattform fest zu verdrahten. Der Benutzer nutzt möglicherweise Teams, GoToWebinar, Livestorm, Demio, Webex, Hopin, Riverside, StreamYard, Crowdcast, BigMarker oder einen individuellen Stack und hostet Wiederholungen auf Vimeo, Wistia, dem eigenen CDN oder gar nicht.
Führen Sie diese Sequenz vor dem Schreiben von Code durch:
Schritt 1 — Fragen Sie, welche Plattformen im Spiel sind
Stellen Sie eine kurze Multiple-Choice-Frage:
- Auf welcher Plattform führen Sie Live-Webinare durch? (Zoom Webinars / Zoom Meetings / Microsoft Teams / GoToWebinar / Livestorm / Demio / Webex / Hopin / BigMarker / Crowdcast / andere)
- Wo leben die Umfragen nach dem Webinar? (Im Webinar-Tool integriert / Typeform / Google Forms / SurveyMonkey / Hubspot / keine)
- Wo werden die Aufzeichnungen gehostet, falls vorhanden? (YouTube / Vimeo / Wistia / selbst gehostet / gated Landingpage / keine Aufzeichnungen)
- Haben Sie Registrierungsdaten getrennt von Anwesenheitsdaten? (Ein kombinierter Export / zwei separate Exporte / nur Registrierung / nur Anwesenheit)
Schritt 2 — Fragen Sie nach einem echten Export, bevor Sie etwas entwerfen
Sagen Sie klar: "Laden Sie einen echten Export von jeder Quelle hoch – Teilnehmer, Umfrage, Aufzeichnung – bei dem die persönlichen Daten bereits entfernt wurden. Ich lese die tatsächlichen Spaltenüberschriften, anstatt zu raten, und sage Ihnen, welche Teile des Dashboards Ihre Daten unterstützen können und welche nicht."
Bestehen Sie darauf. Eine einzige echte Datei beseitigt alle Annahmen. Wenn der Benutzer keine echten Daten teilen kann, bitten Sie ihn, die Kopfzeile plus 2-3 vollständig erfundene Zeilen einzufügen.
Schritt 3 — Führen Sie die Privacy-Gate-Prüfung für die hochgeladene Datei durch
Siehe Privacy Gate (Pflicht). Lehnen Sie die Datei ab, wenn sie ungeschwärzte personenbezogene Daten enthält. Fahren Sie erst mit der Zuordnung fort, wenn eine bereinigte Datei bereitgestellt wurde.
Schritt 4 — Ordnen Sie die Spalten des Benutzers dem kanonischen Schema zu
Zeigen Sie dem Benutzer eine explizite Zuordnungstabelle an (seine Spalte → kanonisches Feld → was es freischaltet) und benennen Sie, was fehlt. Siehe Feldanforderungen und references/platform-exports.md.
Schritt 5 — Teilen Sie ihnen mit, welche Diagramme sie erhalten
Erstellen Sie vor dem Bau einen Bericht über die Verfügbarkeit von Funktionen:
✅ Mit Ihren Daten verfügbar
Watch-Time-Verteilung, Verlauf der gleichzeitigen Zuschauer, Drop-Erkennung,
Anwesenheitstrichter, Monatsvergleich, Neu vs. Wiederkehrend.
⚠️ Teilweise verfügbar
Demografie – Sie haben Land, aber keine Berufsbezeichnung, daher wird der
Senioritäts-Donut ausgeblendet.
❌ Nicht verfügbar
Aufzeichnungsanalysen – kein Aufzeichnungsexport. Der Reiter "Aufzeichnungen"
wird ausgeblendet, bis Sie einen hinzufügen (oder Sie können die Werte manuell
über die CSV-Vorlage eingeben).
Erstellen Sie niemals ein Diagramm, dessen Eingabedaten nicht existieren. Blenden Sie das gesamte Panel aus und zeigen Sie eine einzeilige Erklärung, welche Daten es aktivieren würden.
Privacy Gate (PFLICHT)
Jede hochgeladene Datei durchläuft eine Schwärzungsprüfung vor dem Parsing, vor der Speicherung, vor der Analyse. Wenn personenbezogene Daten gefunden werden, lehnen Sie die gesamte Datei ab, nennen Sie die beanstandeten Spalten und Zeilennummern und erklären Sie, wie sie geschwärzt werden kann. Importieren Sie niemals teilweise. Anonymisieren Sie niemals automatisch und stillschweigend.
Was als personenbezogene Daten gilt
| Kategorie | Erkennung |
|---|---|
| E-Mail-Adressen | [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} in einer beliebigen Zelle |
| Telefonnummern | (?:\+?\d[\s\-\(\)]{0,2}){7,15} mit ≥7 Ziffern, reine Zeitstempel/IDs ausgenommen |
| Postanschriften | Zelle, die mit Straßenschlüsselwörtern übereinstimmt (`straße |
| Postleitzahlen | \b\d{5}(-\d{4})?\b oder [A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2} wenn der Spaltenname auf einen Ort hindeutet |
| IP-Adressen | IPv4/IPv6-Literal |
| Behördliche / Zahlungs-IDs | \b\d{3}-\d{2}-\d{4}\b (SSN-ähnlich), \b(?:\d[ -]*?){13,16}\b bestandenem Luhn-Check |
| Verdächtige Spaltennamen | Kopfzeile, die auf `email |
Regeln
- Zuerst Kopfzeilen-Scan. Jede Spalte, deren Name mit der Liste der Verdächtigen übereinstimmt, wird markiert, selbst wenn die abgetasteten Zellen leer erscheinen – eine leere Spalte kann morgen befüllt werden.
- Scannen Sie jede Zelle jeder Zeile. Keine Stichprobe. Dateien sind klein (tausende Zeilen); ein vollständiger Scan ist billig und ein stichprobenartiger Scan vermittelt trügerische Sicherheit.
- Freitext-Umfrageantworten werden ebenfalls gescannt. Leute tippen "mailen Sie mich an [email protected]" in Feedback-Felder. Dies ist die am häufigsten übersehene Undichtigkeit.
- Bei der ersten gefundenen Kategorie ablehnen, aber alle melden. Schließen Sie den Scan ab und präsentieren Sie jedes Problem auf einmal, damit der Benutzer die Datei in einem Durchgang reparieren kann.
- Schreiben Sie eine abgelehnte Datei niemals auf die Festplatte oder in die Datenbank. Halten Sie sie im Speicher, lehnen Sie ab, verwerfen Sie sie.
- Protokollieren Sie die Ablehnung ohne die beanstandeten Werte. Protokollieren Sie nur Spaltennamen und Zeilennummern – niemals die erkannte E-Mail/Telefonnummer selbst.
Zulässige Kennungen (diese führen NICHT zur Ablehnung)
- Eine stabile pseudonyme Personen-ID – ein Hash, eine UUID oder eine fortlaufende Ganzzahl, die über Dateien hinweg konsistent ist. Dies ist erforderlich für die webinärübergreifende Analyse (siehe unten).
- Länder-/Regionsnamen, Organisationsnamen, Berufsbezeichnungen, Senioritätsstufen.
- Zeitstempel, Dauern, Webinar-IDs, Themen-Strings.
Vorlage für Ablehnungsmeldung
❌ Upload abgelehnt – personenbezogene Daten in attendees_march.csv erkannt
Spalte "Email" → 412 E-Mail-Adressen (Zeilen 2–413)
Spalte "Kontaktnummer" → 88 Telefonnummern (Zeilen 2, 5, 9, … )
Spalte "Was können wir verbessern?" → 3 E-Mail-Adressen im Freitext
(Zeilen 47, 112, 288)
Es wurde nichts importiert und die Datei wurde verworfen.
So beheben Sie das Problem:
1. Ersetzen Sie die Email-Spalte durch eine stabile pseudonyme ID – z.B. einen
SHA-256-Hash der kleingeschriebenen E-Mail, abgeschnitten auf 16 Zeichen.
Verwenden Sie für JEDE Datei die GLEICHE Hash-Methode, damit dieselbe Person
über Webinare hinweg erkennbar ist.
2. Löschen Sie die Spalte "Kontaktnummer" vollständig – sie wird nie verwendet.
3. Schwärzen Sie die E-Mail-Adressen in den Freitext-Antworten, behalten Sie
den Rest des Kommentars.
Laden Sie die bereinigte Datei erneut hoch. Siehe references/anonymisation.md für ein
fertiges Schwärzungs-Skript.
Warum eine stabile pseudonyme ID nicht verhandelbar ist
Die Hälfte des Werts dieses Tools liegt in der webinärübergreifenden Analyse: neue vs. wiederkehrende Teilnehmer, Retention-Kohorten, wiederholte Anmeldungen, Erscheinungsrate pro Person. All das erfordert, dass dieselbe Person über Dateien hinweg erkannt wird, ohne zu wissen, wer sie ist. Teilen Sie dies dem Benutzer bei der Aufnahme explizit mit – wenn sie E-Mails auf leere Werte oder Zufallswerte pro Datei schwärzen, wird jedes webinärübergreifende Diagramm stillschweigend bedeutungslos.
Empfohlen: person_id = sha256(lower(strip(email)) + fixed_salt)[:16], wobei das Salt außerhalb des Datensatzes gespeichert wird. references/anonymisation.md enthält ein einsatzbereites Skript.
Feldanforderungen
Das Dashboard basiert auf einem kanonischen Schema. Die Spalten des Benutzerexports werden darauf abgebildet. Was die Zuordnung nicht füllen kann, ist eine Funktion, die ausgeblendet wird.
Kanonische Entität: webinar (eine Zeile pro Sitzung)
| Feld | Erforderlich? | Typ | Schaltet frei | Typische Quellspalte |
|---|---|---|---|---|
external_id | Erforderlich | text, eindeutig | Alles – der Join-Schlüssel über Teilnehmer-/Umfrage-/Aufzeichnungsdateien hinweg | Webinar-ID, Meeting-ID, Event-ID, Session-ID |
topic | Erforderlich | text | Alle Beschriftungen; Kampagnengruppierung von Wiederholungen | Thema, Titel, Veranstaltungsname |
start_time | Erforderlich | timestamp | Jedes zeitbasierte Diagramm; Monatsvergleich; Tageszeit; der Gleichzeitigkeitsverlauf | Tatsächliche Startzeit, Start, Datum |
duration_minutes | Stark empfohlen | int | Gleichzeitigkeitsverlauf-X-Achse; % der gesehenen Sitzung | Tatsächliche Dauer, Dauer |
num_registrants | Empfohlen | int | Trichter, Erscheinungsrate (kann durch Zählen von Zeilen abgeleitet werden) | # Registrierte, Registriert |
unique_viewers | Empfohlen | int | Tageszeit-Diagramm; Reichweiten-Highlight (ableitbar) | Einmalige Zuschauer, Teilnehmer |
max_concurrent | Optional | int | Spitzenpublikums-Statistik | Maximale gleichzeitige Aufrufe |
Zeitzonenregel: Entscheiden Sie einmalig, ob gespeicherte Zeitstempel UTC oder eine feste lokale Zone sind, notieren Sie es im Schema-Kommentar und konvertieren Sie niemals ad hoc. Die Monats-Bucketisierung liest direkt von diesem Feld. Stellen Sie einen manuellen Monats-Override-Mechanismus bereit (siehe Monats-Overrides) für Sitzungen, die kurz nach lokaler Mitternacht für ein Publikum in einer anderen Zeitzone laufen.
Kanonische Entität: attendee_session (eine Zeile pro Person pro Beitritt)
Eine Person, die geht und wiederkommt, erzeugt mehrere Zeilen. Führen Sie niemals beim Import eine Deduplizierung durch – deduplizieren Sie bewusst zur Analysezeit.
| Feld | Erforderlich? | Typ | Schaltet frei | Typische Quellspalte |
|---|---|---|---|---|
webinar_id | Erforderlich | FK | Alles | — |
person_id | Erforderlich (pseudonym) | text | Neu vs. Wiederkehrend, Retention, wiederholte Anmeldungen, Personendeduplizierung | Gehashter E-Mail, Teilnehmer-ID |
attended | Erforderlich | bool | Anwesend/Abwesend-Verteilung, Trichter, Erscheinungsrate | Teilgenommen (Ja/Nein) |
is_registrant | Empfohlen | bool | Abwesend-Kohorte; Trichter | abgeleitet aus dem Vorhandensein von Registrierungszeit |
join_time | Empfohlen | timestamp | Gleichzeitigkeitsverlauf, Drop-Erkennung | Beitrittszeit |
leave_time | Empfohlen | timestamp | Gleichzeitigkeitsverlauf, Drop-Erkennung | Austrittszeit |
minutes | Empfohlen | int | Watch-Time-Histogramm, durchschnittliche Watch-Time | Zeit in Sitzung (Minuten) |
country / region | Optional | text | Geografie-Donut, regionale Zeitanalyse | Land/Region |
organization | Optional | text | Kontoebenen-Ansicht | Organisation, Unternehmen |
job_title | Optional | text | Senioritäts-Donut (abgeleitet) | Jobtitel, Titel, Rolle |
source_name | Optional | text | Akquisitionskanal-Donut | Quellname, UTM-Quelle, Empfehler |
registration_time | Optional | timestamp | Anmeldekurven-Analyse | Registrierungszeit |
custom_answers | Optional | JSON | Ein Donut pro Registrierungsfrage | Jede nicht erkannte Spalte |
Regel für nicht erkannte Spalten: Jede Spalte in der Teilnehmerdatei, die keines der bekannten Felder oben ist, wird als Registrierungsumfragefrage behandelt und in custom_answers als {Frage: Antwort} gespeichert. Jede solche Frage rendert automatisch ihr eigenes Donut-Diagramm. Dadurch funktioniert das Tool auf Plattformen, die Sie noch nie gesehen haben.
Abgeleitetes Feld – seniority: job_title nach Schlüsselworten gruppieren in C-Level / Gründer (ceo, cto, cfo, cmo, coo, chief, founder, owner, president), VP / Direktor (vp, vice president, head of, director), Manager / Lead (manager, lead, principal), Senior IC (senior, sr.), Junior (junior, jr., intern, associate, assistant), sonst Individual Contributor. Das Senioritätsdiagramm vollständig ausblenden, wenn keine Zeile einen Jobtitel hat.
Kanonische Entität: feedback_response (eine Zeile pro Umfrageeinsendung)
| Feld | Erforderlich? | Typ | Schaltet frei | Typische Quellspalte |
|---|---|---|---|---|
webinar_id | Erforderlich | FK | Verbindung von Feedback zur Sitzung | Meeting/Webinar-ID |
person_id | Optional (pseudonym) | text | Verknüpfung von Feedback mit Anwesenheitsverhalten | Gehashte E-Mail-Adresse |
submitted_at | Optional | timestamp | Reihenfolge, Aktualität | Übermittlungsdatum und -zeit |
score | Empfohlen | int 1–5 | Zufriedenheitsverteilung + Durchschnitte | "Wie nützlich fanden Sie…" |
liked_text | Empfohlen | text | Themen-Cluster für Lob | "Was hat Ihnen gefallen…" |
improve_text | Empfohlen | text | Themen-Cluster für Kritik | "Was können wir verbessern…" |
other_answers | Optional | JSON | Alles andere, wörtlich | verbleibende Fragespalten |
Spaltenerkennung: Finden Sie die Score-/Gefallen-/Verbessern-Spalten durch Schlüsselwortabgleich in der Kopfzeile (nützlich/bewerten/score; gefallen/like; verbessern/improve), Groß-/Kleinschreibung ignorieren, erster Treffer gewinnt. Zeigen Sie dem Benutzer die erkannte Zuordnung und lassen Sie ihn sie korrigieren – die Formulierung der Umfragefragen unterscheidet sich in jedem Unternehmen.
Wenn die Umfrage außerhalb der Webinarplattform (Typeform, Google Forms) lebt, enthält sie keine Webinar-ID. Dann fordern Sie den Benutzer auf, entweder ein ausgeblendetes Feld mit der Webinar-ID hinzuzufügen oder das Ziel-Webinar beim Hochladen in der Benutzeroberfläche auszuwählen.
Kanonische Entität: replay_stats (eine Zeile pro Webinar)
Aufzeichnungen sind die am stärksten plattformabhängigen Daten von allen. Unterstützen Sie drei Aufnahmepfade, in dieser Reihenfolge der Präferenz:
- API-Konnektor zum Aufzeichnungshost (YouTube Data/Analytics API, Vimeo, Wistia) – nur, wenn der Benutzer einen hat und Anmeldeinformationen bereitstellt.
- Natives Analytics-CSV-Export vom Aufzeichnungshost, abgebildet auf die kanonischen Felder.
- Manuelle CSV-Vorlage – immer verfügbar, immer die Rückfallebene. Liefern Sie eine herunterladbare Vorlage mit einer Kopfzeile, einem Kommentarblock, der jede Metrik erklärt, und einer Beispielzeile.
| Feld | Erforderlich? | Typ | Schaltet frei |
|---|---|---|---|
webinar_id | Erforderlich | join key | Alles mit Aufzeichnungsbezug |
video_id / video_url | Optional | text | Deep-Link zum gehosteten Video; API-Synchronisation |
views_day1 | Optional | int | Early-Demand-Diagramm |
views_day7 | Optional | int | Sustained-Demand-Diagramm |
total_view_hours | Optional | numeric | Diagramm zum gesamten Aufzeichnungskonsum |
avg_view_duration_sec | Optional | int | Diagramm zum Aufzeichnungs-Engagement |
avg_view_percentage | Optional | numeric | Diagramm zur Aufzeichnungsbindung |
likes, comments, shares, subscribers_gained | Optional | int | Reaktionsstatistiken |
Jedes Aufzeichnungsfeld ist optional. Speichern Sie NULL für leere Felder, niemals 0 – eine nicht gemessene Metrik und eine gemessene Null sind semantisch unterschiedlich.
Monats-Overrides
Das Dashboard-Bucketing verwendet standardmäßig das Monat-Jahr aus start_time. Ein Webinar, das am 1. April um 00:15 Uhr MEZ beginnt, wird vom Server als 31. März 23:15 UTC aufgezeichnet. Das Standard-Bucketing würde es im März anzeigen, obwohl das Publikum es als April-Webinar betrachtet.
Bereitstellung: Eine Tabelle oder Benutzeroberfläche, in der für jedes Webinar das Feld display_month manuell gesetzt werden kann (als Text YYYY-MM). Wenn gesetzt, überschreibt dieses Feld das startzeitbasierte Bucketing für dieses Webinar. Lassen Sie es standardmäßig NULL, um das automatische Bucketing zu verwenden.
Konfiguration des kanonischen Schemas
Dies ist eine empfohlene PostgreSQL-Schemadefinition, an die Sie sich in jedem Ziel-Stack anlehnen können:
-- PostgreSQL-Referenzschema – passen Sie die Typen für Ihre DB an
CREATE TABLE webinar (
webinars_id SERIAL PRIMARY KEY,
external_id TEXT UNIQUE NOT NULL,
topic TEXT NOT NULL,
start_time TIMESTAMPTZ NOT NULL,
duration_minutes INT,
num_registrants INT,
unique_viewers INT,
max_concurrent INT,
display_month TEXT -- 'YYYY-MM' oder NULL
);
CREATE TABLE attendee_session (
attendee_session_id SERIAL PRIMARY KEY,
webinars_id INT NOT NULL REFERENCES webinar(webinars_id),
person_id TEXT NOT NULL,
attended BOOLEAN NOT NULL,
is_registrant BOOLEAN,
join_time TIMESTAMPTZ,
leave_time TIMESTAMPTZ,
minutes INT,
country TEXT,
region TEXT,
organization TEXT,
job_title TEXT,
source_name TEXT,
registration_time TIMESTAMPTZ,
custom_answers JSONB DEFAULT '{}'::JSONB
);
CREATE TABLE feedback_response (
feedback_response_id SERIAL PRIMARY KEY,
webinars_id INT NOT NULL REFERENCES webinar(webinars_id),
person_id TEXT,
submitted_at TIMESTAMPTZ,
score INT CHECK (score >= 1 AND score <= 5),
liked_text TEXT,
improve_text TEXT,
other_answers JSONB DEFAULT '{}'::JSONB
);
CREATE TABLE replay_stats (
replay_stats_id SERIAL PRIMARY KEY,
webinars_id INT NOT NULL REFERENCES webinar(webinars_id),
video_id TEXT,
video_url TEXT,
views_day1 INT,
views_day7 INT,
total_view_hours NUMERIC,
avg_view_duration_sec INT,
avg_view_percentage NUMERIC,
likes INT,
comments INT,
shares INT,
subscribers_gained INT
);
Diagramm-Semantiken
Definieren Sie jedes Diagramm anhand seiner Eingabe, nicht seiner Bibliothek. Dies ist der Vertrag, den Ihre Implementierung erfüllen muss.
Tageszeit-Wärmekarte („Wann schalten sie ein?“)
Erforderliche Daten: attendee_session.join_time, webinar.start_time.
Achsen: Y = Stunde des Tages (0–23), X = Wochentag (So–Sa). Die Farbe jeder Zelle ist die Gesamtzahl der Sitzungen, die zu dieser Stunde/an diesem Tag begonnen wurden.
Anzahl: Wenn join_time den gesamten Daten fehlt, zeigen Sie ein leeres Panel mit der Aufschrift "Stündlicher Beitrittsverlauf erfordert Join-Timestamps pro Teilnehmer."
Implementierung: Gruppieren Sie die Basis nach date_trunc('hour', join_time), pivotieren Sie nach Stunde + Wochentag und verwenden Sie eine 2D-ApexCharts-Heatmap (oder die Heatmap-Funktion Ihrer Bibliothek).
Liste der nächsten und vergangenen Webinare
Inhalt: Alle Webinare, sortiert nach start_time absteigend, mit drei Aktionen pro Webinar: „Details anzeigen" (leitet zu /{webinar_id} weiter), SVG-Export und CSV-Export der Teilnehmer dieses Webinars.
CSV-Export: Exportieren Sie attendee_session für dieses Webinar mit den Spalten person_id, attended, join_time, leave_time, minutes, country, organization, job_title, custom_answers (als abgeflachte Schlüssel-Wert-Paare).
Trichter: Registriert → Teilgenommen → Mindestens X Minuten
Erforderliche Daten: attendee_session.is_registrant, attended, minutes.
Stufen:
- Registriert = # Zeilen mit
is_registrant = true. - Teilgenommen = # Zeilen mit
attended = true. - ≥ 5 Minuten (frühes Engagement)
- ≥ 15 Minuten (Hälfte des Webinars)
- ≥ 30 Minuten (Kernpublikum)
Wenn is_registrant für einen Datensatz fehlt, zeigt der Trichter nur die Stufen 2–5, mit einer Notiz "Registrierungsdaten fehlen; Trichter beginnt bei den Teilnehmern."
Prozentsätze: Jede Stufe wird als Prozentsatz der vorherigen Stufe angezeigt (z. B. 60 % der Teilnehmer blieben ≥5 Minuten).
Verteilung der Watch-Time (Histogramm)
Erforderliche Daten: attendee_session.minutes.
Bucket-Definition: [0, 5), [5, 10), [10, 15), [15, 20), [20, 25), [25, 30), [30, 35), [35, 40), [40, 45), [45, ∞).
Leerer Fall: „Histogramm der Watch-Time erfordert Minuten pro Teilnehmer – geben Sie die Spalte entsprechend an (üblich: ‚Zeit in Sitzung (Min.)', ‚Anwesend (Min.)')."
Verlauf der gleichzeitigen Zuschauer
Erforderliche Daten: join_time und leave_time.
Achsen: X = Minuten relativ zum Start (0 = Startzeit), Y = Anzahl der gleichzeitigen Sitzungen. Der Wertebereich X erstreckt sich vom frühesten bis zum spätesten Join/Leave für das ausgewählte Webinar. Der Anfangsbalken bei t=0 enthält alle Personen, die einen Join-Zeitpunkt vor oder gleich dem Webinar-Startzeitpunkt haben. Der letzte Balken enthält alle Personen, die danach beigetreten sind und noch anwesend sind.
Formel (SQL-Version): Erzeugen Sie für jede ganze Minute zwischen min(join_time) und max(leave_time) einen Bucket und zählen Sie die Zeilen, bei denen join_time <= bucket_time und (leave_time IS NULL oder leave_time > bucket_time).
Erforderlich für diesen Graphen: join_time MUSS ausgefüllt sein. Wenn leave_time vollständig fehlt, zeigen Sie eine Warnung: "Austrittszeit nicht verfügbar – die Kurve der gleichzeitigen Zuschauer nähert sich nur über die Beitrittszeiten an." Auch dann wird der Graph gezeichnet; er zeigt das kumulative Publikum im Laufe der Zeit, keine echte Gleichzeitigkeit.
**Wenn join_time für alle Zeilen fehlt, zeigen Sie: "Die Timeline der gleichzeitigen Zuschauer erfordert Join-Timestamps pro Teilnehmer."
Drop-Erkennung („Wo steigen sie aus?")
Erforderliche Daten: join_time und leave_time.
Implementierung: Dasselbe wie der Verlauf der gleichzeitigen Zuschauer, überlagert mit einem gleitenden Durchschnitt der Änderungsrate (berechnet als delta_y / delta_t in Einheiten von Zuschauern pro Minute). Markieren Sie die 3 Zeitpunkte mit der steilsten negativen Steigung (die häufigsten Ausstiegsmomente). Zeigen Sie diese 3 Zeitpunkte innerhalb eines Tooltips oder als Liste unter dem Graphen an: "Höchste Ausstiegsrate um Minute X (Y Zuschauer/Minute verloren)."
Leerer Fall: Gleich wie bei gleichzeitigen Zuschauern, plus: „Drop-Erkennung erfordert sowohl Join- als auch Leave-Timestamps."
Monatliches Wachstum („Wächst das Publikum?")
Erforderliche Daten: webinar.start_time, attendee_session.attended.
Achsen: X = Monat (YYYY-MM), Y = Anzahl der eindeutigen Personen, die an Webinaren in diesem Monat teilgenommen haben (person_id de-dupliziert nach attended = true).
Zwei Linien: „Einmalige Teilnehmer" (Gesamtzahl der Personen, die diesen Monat mindestens an einem Webinar teilgenommen haben) und „Neue Personen" (Personen, deren erster attended-Datensatz in diesem Monat liegt).
Analyse: Wenn die rote Linie (Neu) sinkt während die blaue Linie (Gesamt) flach bleibt, gewinnen Sie keine neuen Leute, aber die alten kommen wieder. Wenn beide fallen, erodiert Ihr Publikum.
Liniendiagramm: Verwenden Sie den Liniendiagramm-Modus von ApexCharts (oder das Äquivalent Ihrer Bibliothek).
Neu vs. Wiederkehrend (Kohorten-Donut)
Erforderliche Daten: attendee_session.person_id, webinar.start_time.
Definition: Eine Person ist für die aktuelle Webinar-Sitzung „wiederkehrend", wenn sie eine frühere Sitzung mit attended = true hat. Andernfalls ist sie „neu".
Donut: Zwei Segmente: Neu (Anzahl der Personen, die zum ersten Mal teilnehmen) vs. Wiederkehrend (Personen, die zum zweiten, dritten usw. Mal teilnehmen). Berechnen Sie dies pro ausgewähltem Webinar oder aggregiert über alle Zeit.
Wenn person_id komplett fehlt: Zeigen Sie: „Für die Unterscheidung zwischen neuen und wiederkehrenden Teilnehmern ist pro Person eine stabile pseudonyme Kennung erforderlich. Siehe Aufnahme-Anleitung."
Referenzen
references/platform-exports.md– Dokumentation der Kanonisierung für jede gängige Export-Plattform.references/anonymisation.md– Bereites Schwärzungs-Skript und Anleitung.references/csv-templates/– Herunterladbare CSV-Vorlagen für manuelle Eingaben.
Wie Sie diesen Skill in Ihrem eigenen Repository verwenden
Dieses Skill-Repository enthält:
- Diese
SKILL.md– die vollständige Spezifikation. references/– Dokumentation und Skripte.src/– Eine Referenzimplementierung (optional, kann geforkt werden).
So starten Sie:
- Forken Sie dieses Repo oder kopieren Sie die Ordnerstruktur.
- Lesen Sie
SKILL.mdvollständig. - Implementieren Sie die Aufnahmeschritte in Ihrer Web-App Ihrer Wahl.
- Implementieren Sie das Privacy Gate.
- Implementieren Sie die Schemazuordnung und die Diagramm-Semantiken.
- Implementieren Sie den Feature-Availability-Report.
Hinweis: Dieser Skill ist für die Verwendung mit AI-Agenten konzipiert. Er kann in jede Sprache und Umgebung integriert werden, die die Spezifikation unterstützt.