Athleten
oder lege einen neuen an.
Athleten auswΓ€hlen
πΈ Spinnendiagramm β Spielervergleich
Γbersichtstabelle β alle Kennzahlen (letzter Test)
Bereit?
Klicke auf Neue Vorlage, um den Test zu starten. Der Timer beginnt, sobald du die Zahl 1 anklickst.
Geschafft!
NEXUS Speed Verlauf (Cloud-synchronisiert)
Athletenvergleich NEXUS Speed
' '') oben
und/oder Punkte (. ..) unten,
die zusammen 2 ergeben (d'' Β· d'. Β· d..).
Pro Zeile hast du eine feste Zeit. Klicke auf ein Zeichen, um es zu markieren. Γber den Button NΓ€chste Zeile oder per Leertaste springst du vorzeitig zur nΓ€chsten Zeile.
NEXUS Focus Verlauf (Cloud-synchronisiert)
Athletenvergleich NEXUS Focus
π Trainingsplan & Anwesenheit
Voraussetzung: Mindestens eine Trainingseinheit mit erfasster Anwesenheit und Spieler mit Testergebnissen (Tests-Tab). Das Diagramm zeigt dann: Anwesenheitsrate % β Testergebnis pro Spieler.
Anwesenheitsrate Γ Testergebnis
X-Achse: Anwesenheitsrate (%) der Spieler Β· Y-Achse: zuletzt gemessener Testwert Β· Farbe: grΓΌn β₯ 70 % Β· gelb β₯ 40 % Β· rot < 40 %
Das PDF wird direkt im Browser generiert und als E-Mail-Anhang verschickt. Die Adresse wird nicht gespeichert.
| Benutzername | Name | Rolle | Erstellt | Verein/Klassen | Aktionen | |
|---|---|---|---|---|---|---|
Spieler, die sich ΓΌber eine Einladung registriert haben. E-Mail-Adressen kommen aus Supabase Auth β βπ Auth-E-Mails prΓΌfen" klicken um sie anzuzeigen (einmalig pro Session).
| Name | Rolle | Erstellt | Aktionen |
|---|
| Nutzer | Verein | Erlaubte Klassen | Rolle |
|---|
Plan-Zuweisung pro Verein. Γnderungen werden sofort gespeichert und beim nΓ€chsten Login des Vereins aktiv.
| Verein | Nachname β | Vorname | Klasse | Position | Tests | Erstellt | Verein Γ€ndern |
|---|
Exportiere alle Vereinsdaten (Spieler, Tests, Schwellwerte) als JSON-Datei. Diese Datei kann spΓ€ter wieder importiert werden um den Datenstand vollstΓ€ndig wiederherzustellen.
Damit Spieler in ihrer Kalenderansicht zu Trainingseinheiten zu-/absagen kΓΆnnen, muss einmalig eine RLS-Policy angelegt werden. Trainer und Admins kΓΆnnen den Status jederzeit ΓΌberschreiben.
SQL β Supabase SQL-Editor
-- Spieler dΓΌrfen ihre eigene Anwesenheit eintragen / Γ€ndern
CREATE POLICY "player_rsvp_own_attendance"
ON public.training_attendance
FOR ALL
TO authenticated
USING (
player_id IN (
SELECT id FROM players WHERE auth_user_id = auth.uid()
)
)
WITH CHECK (
player_id IN (
SELECT id FROM players WHERE auth_user_id = auth.uid()
)
);
-- Sicherstellen dass RLS aktiviert ist
ALTER TABLE public.training_attendance ENABLE ROW LEVEL SECURITY;
Damit Vereins-Admins eingeladene Spieler-Logins lΓΆschen kΓΆnnen, muss einmalig eine RLS-Policy angelegt werden.
SQL β Supabase SQL-Editor
-- Erlaubt Vereins-Admins, Spieler-Profile in ihrem Club zu lΓΆschen
DROP POLICY IF EXISTS "admin_delete_player_profiles" ON user_profiles;
CREATE POLICY "admin_delete_player_profiles" ON user_profiles
FOR DELETE USING (
role = 'player'
AND id IN (
SELECT auth_user_id FROM players
WHERE auth_user_id IS NOT NULL
AND club_id IN (
SELECT club_id FROM user_club_memberships
WHERE user_id = auth.uid()
)
)
);
Einmalig ausfΓΌhren um die Bug-Reports-Tabelle anzulegen.
SQL β Supabase SQL-Editor
CREATE TABLE IF NOT EXISTS bug_reports (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
description TEXT NOT NULL,
severity TEXT DEFAULT 'normal',
context_tab TEXT,
reporter TEXT,
reporter_role TEXT,
browser TEXT,
app_version TEXT,
status TEXT DEFAULT 'open' CHECK (status IN ('open','in_progress','resolved','wontfix')),
created_at TIMESTAMPTZ DEFAULT now()
);
ALTER TABLE bug_reports ENABLE ROW LEVEL SECURITY;
-- Jeder eingeloggte Nutzer darf Bug-Reports einreichen
DROP POLICY IF EXISTS "bug_reports_insert" ON bug_reports;
CREATE POLICY "bug_reports_insert" ON bug_reports
FOR INSERT WITH CHECK (true);
-- Nur Superadmin darf lesen
DROP POLICY IF EXISTS "bug_reports_superadmin" ON bug_reports;
CREATE POLICY "bug_reports_superadmin" ON bug_reports
FOR ALL USING (
EXISTS (SELECT 1 FROM user_profiles WHERE id = auth.uid() AND role = 'superadmin')
);
Damit der Login per E-Mail-Adresse UND Benutzername funktioniert, wird eine Datenbankfunktion benΓΆtigt. Einmalig im Supabase SQL-Editor ausfΓΌhren.
SQL β Supabase SQL-Editor
-- ErmΓΆglicht Login-Fallback: E-Mail zu Username nachschlagen
-- SECURITY DEFINER: bypassed RLS, sicher weil nur eigene E-Mail zurΓΌckgegeben wird
CREATE OR REPLACE FUNCTION public.get_login_email_for_username(p_username TEXT)
RETURNS TEXT
LANGUAGE SQL
SECURITY DEFINER
SET search_path = public
AS $$
SELECT email FROM user_profiles
WHERE lower(username) = lower(p_username)
AND email IS NOT NULL
AND email NOT LIKE '%@merc.internal'
AND email NOT LIKE '%.internal'
LIMIT 1;
$$;
GRANT EXECUTE ON FUNCTION public.get_login_email_for_username TO anon, authenticated;
clubs.plan)βΆ
Einmalig ausfΓΌhren um die plan-Spalte zur clubs-Tabelle hinzuzufΓΌgen. Alle bestehenden Vereine werden auf Club gesetzt (Bestandsschutz).
SQL β Supabase SQL-Editor
ALTER TABLE clubs
ADD COLUMN IF NOT EXISTS plan TEXT
NOT NULL DEFAULT 'starter'
CHECK (plan IN ('starter', 'club', 'pro'));
-- Bestandsschutz: bestehende Vereine erhalten Club-Plan
UPDATE clubs SET plan = 'club' WHERE plan = 'starter';
FΓΌr die Trainingsplan-Funktion mΓΌssen zwei neue Tabellen in Supabase angelegt werden. Kopiere das folgende SQL in den Supabase SQL-Editor und fΓΌhre es aus (einmalig, nur bei der Ersteinrichtung von V9).
π SQL Migration (einmalig ausfΓΌhren)
-- HOLULA APEX V9 β Training Tables Migration
CREATE TABLE IF NOT EXISTS training_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
club_id UUID NOT NULL REFERENCES clubs(id) ON DELETE CASCADE,
trainer_id UUID REFERENCES auth.users(id),
date DATE NOT NULL,
start_time TEXT,
treffzeit TEXT,
title TEXT,
notes TEXT,
planned_tests TEXT[] DEFAULT '{}',
jahrgangsklassen TEXT[] DEFAULT '{}',
ort TEXT,
trainer_names TEXT,
material TEXT,
phasen JSONB DEFAULT '[]',
saison TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- Falls Tabelle bereits existiert (V9.0 β V9.1 Upgrade):
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS treffzeit TEXT;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS jahrgangsklassen TEXT[] DEFAULT '{}';
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS ort TEXT;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS trainer_names TEXT;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS material TEXT;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS phasen JSONB DEFAULT '[]';
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS practice_no INTEGER;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS duration_min INTEGER;
CREATE TABLE IF NOT EXISTS training_attendance (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES training_sessions(id) ON DELETE CASCADE,
player_id UUID NOT NULL REFERENCES players(id) ON DELETE CASCADE,
club_id UUID NOT NULL,
status TEXT NOT NULL DEFAULT 'absent'
CHECK (status IN ('present','absent','late','excused')),
note TEXT,
UNIQUE(session_id, player_id)
);
-- RLS aktivieren
ALTER TABLE training_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE training_attendance ENABLE ROW LEVEL SECURITY;
-- Bestehende Policies entfernen (idempotent)
DROP POLICY IF EXISTS "sessions_club_access" ON training_sessions;
DROP POLICY IF EXISTS "sessions_superadmin_access" ON training_sessions;
DROP POLICY IF EXISTS "sessions_service_role" ON training_sessions;
DROP POLICY IF EXISTS "attendance_club_access" ON training_attendance;
DROP POLICY IF EXISTS "attendance_superadmin_access" ON training_attendance;
DROP POLICY IF EXISTS "attendance_service_role" ON training_attendance;
-- Lese- und Schreibzugriff fΓΌr eigenen Verein
CREATE POLICY "sessions_club_access" ON training_sessions
FOR ALL USING (
club_id IN (SELECT club_id FROM user_club_memberships WHERE user_id = auth.uid())
);
CREATE POLICY "attendance_club_access" ON training_attendance
FOR ALL USING (
club_id IN (SELECT club_id FROM user_club_memberships WHERE user_id = auth.uid())
);
-- Superadmin: vereinsΓΌbergreifender Vollzugriff
CREATE POLICY "sessions_superadmin_access" ON training_sessions
FOR ALL USING (
EXISTS (SELECT 1 FROM user_profiles WHERE id = auth.uid() AND role = 'superadmin')
);
CREATE POLICY "attendance_superadmin_access" ON training_attendance
FOR ALL USING (
EXISTS (SELECT 1 FROM user_profiles WHERE id = auth.uid() AND role = 'superadmin')
);
-- Service Role Bypass (fΓΌr Admin-Operationen)
CREATE POLICY "sessions_service_role" ON training_sessions
FOR ALL TO service_role USING (true) WITH CHECK (true);
CREATE POLICY "attendance_service_role" ON training_attendance
FOR ALL TO service_role USING (true) WITH CHECK (true);
Damit der Superadmin alle Trainingseinheiten aller Vereine sieht, mΓΌssen zwei RLS-Policies ergΓ€nzt werden. Kopiere das SQL in den Supabase SQL-Editor und fΓΌhre es aus (idempotent β kann jederzeit erneut ausgefΓΌhrt werden).
π SQL (einmalig ausfΓΌhren)
-- HOLULA APEX β Superadmin RLS Fix (Trainingsplan)
-- ErmΓΆglicht vereinsΓΌbergreifenden Zugriff fΓΌr Superadmin
DROP POLICY IF EXISTS "sessions_superadmin_access" ON training_sessions;
DROP POLICY IF EXISTS "attendance_superadmin_access" ON training_attendance;
CREATE POLICY "sessions_superadmin_access" ON training_sessions
FOR ALL USING (
EXISTS (SELECT 1 FROM user_profiles WHERE id = auth.uid() AND role = 'superadmin')
);
CREATE POLICY "attendance_superadmin_access" ON training_attendance
FOR ALL USING (
EXISTS (SELECT 1 FROM user_profiles WHERE id = auth.uid() AND role = 'superadmin')
);
FΓΌr das Login-Protokoll muss einmalig eine neue Tabelle angelegt werden. Kopiere das SQL in den Supabase SQL-Editor und fΓΌhre es aus.
π SQL Migration (einmalig ausfΓΌhren)
-- HOLULA APEX β Login-Protokoll Tabelle
CREATE TABLE IF NOT EXISTS login_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
username TEXT,
display_name TEXT,
role TEXT,
club_id UUID,
club_name TEXT,
logged_in_at TIMESTAMPTZ DEFAULT now()
);
ALTER TABLE login_logs ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS "login_logs_insert" ON login_logs;
DROP POLICY IF EXISTS "login_logs_superadmin" ON login_logs;
DROP POLICY IF EXISTS "login_logs_service" ON login_logs;
-- Jeder eingeloggte Nutzer darf seinen eigenen Login eintragen
CREATE POLICY "login_logs_insert" ON login_logs
FOR INSERT WITH CHECK (user_id = auth.uid());
-- Nur Superadmin darf alle EintrΓ€ge lesen
CREATE POLICY "login_logs_superadmin" ON login_logs
FOR SELECT USING (
EXISTS (
SELECT 1 FROM user_profiles
WHERE id = auth.uid() AND role = 'superadmin'
)
);
-- Service Role Bypass
CREATE POLICY "login_logs_service" ON login_logs
FOR ALL TO service_role USING (true) WITH CHECK (true);
Damit Spieler-Logins ihre eigene Anwesenheit sehen kΓΆnnen, mΓΌssen zwei neue RLS-Policies angelegt werden. Einmalig in den Supabase SQL-Editor kopieren und ausfΓΌhren.
π SQL Migration (einmalig ausfΓΌhren)
-- HOLULA APEX β Spieler-Lesezugriff auf Trainingsplan-Daten
-- Spieler dΓΌrfen Einheiten ihres Vereins lesen
DROP POLICY IF EXISTS "sessions_player_access" ON training_sessions;
CREATE POLICY "sessions_player_access" ON training_sessions
FOR SELECT USING (
club_id IN (
SELECT club_id FROM players WHERE auth_user_id = auth.uid()
)
);
-- Spieler dΓΌrfen ihre eigenen Anwesenheits-EintrΓ€ge lesen
DROP POLICY IF EXISTS "attendance_player_access" ON training_attendance;
CREATE POLICY "attendance_player_access" ON training_attendance
FOR SELECT USING (
player_id IN (
SELECT id FROM players WHERE auth_user_id = auth.uid()
)
);
FΓΌgt die Felder typ, gegner und ergebnis zur
training_sessions-Tabelle hinzu. Einmalig in den Supabase SQL-Editor
kopieren und ausfΓΌhren.
π SQL Migration (einmalig ausfΓΌhren)
-- HOLULA APEX β Eistraining & Turnier Migration
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS typ TEXT DEFAULT 'sommer' CHECK (typ IN ('sommer', 'eis', 'turnier'));
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS gegner TEXT;
ALTER TABLE training_sessions ADD COLUMN IF NOT EXISTS ergebnis TEXT;
FΓΌgt lineup (Spieleraufstellung fΓΌr Turniere) und test_label (Eingangs-/Ausgangstest-Markierung)
zur training_sessions-Tabelle hinzu. Einmalig ausfΓΌhren.
π SQL Migration (einmalig ausfΓΌhren)
-- HOLULA APEX v13 β Spieleraufstellung & Test-Label ALTER TABLE public.training_sessions ADD COLUMN IF NOT EXISTS lineup JSONB DEFAULT NULL; ALTER TABLE public.training_sessions ADD COLUMN IF NOT EXISTS test_label TEXT DEFAULT NULL;
Einmalig das optionale E-Mail-Feld zu user_profiles hinzufΓΌgen.
Kopiere das SQL in den Supabase SQL-Editor und fΓΌhre es aus.
π SQL Migration (einmalig ausfΓΌhren)
-- MERC App β Optionales E-Mail-Feld fΓΌr Trainer/Admin ALTER TABLE user_profiles ADD COLUMN IF NOT EXISTS email TEXT;
Legt fest welche Saison in Formularen vorausgewΓ€hlt ist. Die App erkennt die aktuelle Saison automatisch (Mai = Saisonwechsel), du kannst sie aber manuell ΓΌberschreiben.
Aktiviere die Testkategorien, die fΓΌr dich relevant sind. Inaktive Kategorien werden im Testformular ausgeblendet.
Definiere Low / Mid / Best Schwellwerte pro Metrik. Diese werden in der Datenbank gespeichert und im Vergleich-Tab automatisch geladen. Im Vergleich-Tab kΓΆnnen Werte lokal temporΓ€r ΓΌberschrieben werden.
Hinterlege eine echte E-Mail-Adresse, damit du bei Bedarf dein Passwort zurΓΌcksetzen kannst.