Turnierverwaltung für Flipper-Ligen & Turniere. flip4fun unterstützt die Planung und Durchführung von Flipper-Ligen und TwinPin-Turnieren — von der Flipper-Auslosung über die Ergebniserfassung bis hin zur automatischen Rangliste und Urkundengenerierung.
Tech Stack: Svelte 5 • SvelteKit • Vite • Tailwind CSS • Flowbite • Prisma • PostgreSQL
# Repository klonen
git clone https://github.com/reilo/flip4fun-svelte.git
cd flip4fun-svelte
# Abhängigkeiten installieren
npm install
# .env-Datei erstellen (siehe Umgebungsvariablen Abschnitt)
cp .env.example .env
# Entwicklungsserver starten
npm run dev
Die App ist dann verfügbar unter http://localhost:5173.
Folgende Konstanten können bzw. müssen in der Datei .env im Root-Verzeichnis dieser App gesetzt werden:
postgresql://<DB-Owner>:<DB-Passwort>@<server>:<port>/<DB-Name>localhost)adapter-auto (in vite.config.js)npm run dev → http://localhost:5173VITE_APP_FULL gesetztlocalhost)adapter-node (muss manuell in vite.config.js umgestellt werden)npm run build gefolgt von npm run preview → http://localhost:4173adapter-auto (standard, für Vercel)Es wird empfohlen, regelmäßig manuell ein Backup der Datenbank zu erstellen bzw. die Tabellen als CSV zu exportieren. Insbesondere nach einem abgeschlossenen Spieltag sollte dies unbedingt durchgeführt werden. Eine detaillierte Anleitung findet sich im Abschnitt "Daten exportieren / importieren" unten.
Siehe auch den Abschnitt "Setup" oben.
Entwicklung:
npm run dev
App unter http://localhost:5173
Produktion (lokal):
npm run build
npm run preview
App unter http://localhost:4173
Sollte die App nicht laufen, kann sie manuell im Verzeichnis C:/flip4fun-svelte durch npm run preview gestartet werden.
Im Repository ist der Svelte‑Adapter auf adapter-auto eingestellt. Diese Einstellung muss beibehalten werden, damit die unter Vercel gehostete Version korrekt funktioniert.
Auf dem System, auf dem das Projekt lokal im Spielbetrieb kompiliert wird, muss der Adapter auf adapter-node umgestellt werden (siehe auch Abschnitt "Umgebungen" oben).
npm run dev # Entwicklungsserver mit HMR
npm run build # Production Build
npm run preview # Preview des Production Build
npm run lint # Prettier & ESLint Check
npm run format # Code automatisch formatieren
npm run test # Vitest Tests ausführen
Das Projekt nutzt Svelte 5 mit SvelteKit. Weitere Informationen in den Resourcen oben.
Datenbank-Schema mit der Datenbank synchronisieren:
npx prisma db push
Nach Schema-Änderung Migration erstellen:
npx prisma migrate dev --name=<beschreibung>
Prisma Client neu generieren:
npx prisma generate
Prisma Studio starten (Web-UI für Datenbankdaten):
npx prisma studio
Empfohlen für Remote-Datenbanken. Für lokale Datenbanken wird pgAdmin bevorzugt.
Das Projekt nutzt Tailwind CSS für Styling und Flowbite Svelte für vorgefertigte UI-Komponenten.
npm install tailwindcss flowbite flowbite-svelte
DATABASE_URL in .env setzennpx prisma db push
Die unten angegebenen psql-Kommandos befinden sich auch im psql-Verzeichnis.
Um Daten von einer Datenbank in eine andere zu bringen (z.B. lokal ↔ remote via NeonDB):
Export (Quellsystem):
\copy (SELECT * FROM pin) to '..\pin.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM player) to '..\player.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM tourney) to '..\tourney.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM round) to '..\round.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM match) to '..\match.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM matchn) to '..\matchn.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
\copy (SELECT * FROM frame) to '..\frame.csv' WITH CSV DELIMITER '|' QUOTE '^' HEADER ENCODING 'UTF8'
Hinweise:
|, nicht ,)^)Import (Zielsystem):
Erst Tabellen leeren (optional):
DELETE FROM pin; DELETE FROM player; DELETE FROM tourney;
DELETE FROM round; DELETE FROM match; DELETE FROM matchn; DELETE FROM frame;
Dann importieren:
\copy pin FROM '..\pin.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy player FROM '..\player.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy tourney FROM '..\tourney.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy round FROM '..\round.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy match FROM '..\match.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy matchn FROM '..\matchn.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
\copy frame FROM '..\frame.csv' DELIMITER '|' QUOTE '^' CSV HEADER ENCODING 'UTF8'
tournament.settings
baseline: Basispunkte für jeden Spieler zu SaisonbeginnchallengeSame: Wie oft darf der gleiche Gegner je Saison gefordert werdenmatchBonus: Bonuspunkt(e) für jedes absolvierte MatchmatchPenalty: Strafpunkt(e) für Fehlmatches pro Spieltag (neu)showToast: Toast-Benachrichtigungen nach Match-Eingabe anzeigenminMatchesRound: Wie viele Matches muss ein Spieler pro Spieltag spielen?penaltyFirstRound: Ab welcher Runde erfolgen Punktabzüge?tournament.settings
numFinalists: Wieviele Spieler sollen in die Finalebene aufrückenpinTypes: Welche Art von Flipper sollen beim Double-Match gewählt werden (0 = beliebig, 1 = 1xDMD 1xEarly, 2 = mindestens 1xDMD)maxStartBonus: Wie hoch soll der maximale Startbonus seintournament.settings
allowBye: Freilos erlauben bei 4n+1 Spielernround.settings.rankInit
bonus: Bonuspunkte zu Spieltagbeginnplayer: player IDpoints: Punkte zu Spieltagbeginnmatches: Anzahl Matches zu Spieltagbeginnmismatch: Anzahl der fehlenden Spielepenalty: Strafpunkte zu Spieltagbeginnstrength: Spielstärke zu Spieltagbeginnround.results.rankFinal
bonus: Bonuspunkte Gesamt nach Spieltagplayer: player IDpoints: Gesamtpunkte nach Spieltagmatches: Gesamtanzahl Matches nach Spieltagmismatch: Anzahl der fehlenden Spielepenalty: Strafpunkte Gesamt nach SpieltagrankChange: Rangänderung nach Spieltag