296 lines
23 KiB
Markdown
296 lines
23 KiB
Markdown
<!--
|
||
SPDX-FileCopyrightText: 2026 Paul Schoeneck
|
||
|
||
SPDX-License-Identifier: AGPL-3.0-only AND LicenseRef-KIBU-Additional-Terms
|
||
-->
|
||
|
||
# KIBU – Kinder-Betreuung Online
|
||
|
||
Lokale Web-App für die Kinderbetreuung mit Next.js, TypeScript und einer echten PostgreSQL-Datenbank. Keine externen Dienste, Fonts oder Bild-Uploads. Kinderkarten verwenden Initialen.
|
||
|
||
## Docker und oeffentliche Demo
|
||
|
||
Das gleiche Image unterstuetzt normale Instanzen und einen ausdruecklichen
|
||
Demomodus. Die Demo ist eine voll bearbeitbare, gemeinsam genutzte Instanz mit
|
||
12 fiktiven Kindern, Wochenplaenen, Abholberechtigungen und Anwesenheitsverlauf.
|
||
Nur im Demomodus sind E-Mail und Passwort im normalen Login vorausgefuellt:
|
||
`demo@kibu.local` / `KIBU-Demo-2026!`. Es gibt keinen Authentifizierungs-Bypass.
|
||
Aufnahmerunden koennen wie in einer normalen Instanz angelegt werden.
|
||
|
||
**Keine echten Daten eingeben! Jeder App-Start loescht alle Demo-Daten und
|
||
Zugaenge, ersetzt sie durch Beispieldaten und macht alte Sitzungen ungueltig.**
|
||
Auch ein automatischer App-Neustart nach einem Fehler setzt die Demo zurueck.
|
||
Die Demo-Datenbank liegt zusaetzlich auf einem fluechtigen `tmpfs`.
|
||
Nicht mehrfach skalieren: es ist eine einzelne App mit gemeinsamer Datenbank.
|
||
Der Login, Passwortaenderungen und andere Funktionen verhalten sich normal;
|
||
aendert jemand das gemeinsame Passwort, stellt ein App-Neustart es wieder her.
|
||
|
||
### Lokal bauen und starten
|
||
|
||
Docker Desktop mit Linux-Containern muss laufen. Compose verwendet ein separates
|
||
Projekt `kibu-demo`, eine separate Datenbank ohne veroeffentlichten DB-Port und
|
||
standardmaessig <http://127.0.0.1:3001>. Die bisherige lokale Instanz auf Port 3000
|
||
und ihr Datenvolume bleiben unberuehrt.
|
||
|
||
```powershell
|
||
docker compose -f compose.demo.yaml up -d --build --wait
|
||
docker compose -f compose.demo.yaml logs app
|
||
# App neu starten und damit Demo-Daten neu erzeugen:
|
||
docker compose -f compose.demo.yaml restart app
|
||
# Nur diese Demo stoppen:
|
||
docker compose -f compose.demo.yaml down
|
||
```
|
||
|
||
### Image pushen und auf einem anderen Host starten
|
||
|
||
```powershell
|
||
docker build -t git.voidcube.de/pixo2000/kibu:demo .
|
||
docker login git.voidcube.de
|
||
docker push git.voidcube.de/pixo2000/kibu:demo
|
||
```
|
||
|
||
Auf dem Zielhost nur `compose.demo.yaml` bereitstellen. Bei privater Registry
|
||
vorher dort ebenfalls anmelden, dann:
|
||
|
||
```powershell
|
||
docker compose -f compose.demo.yaml pull
|
||
docker compose -f compose.demo.yaml up -d --no-build --wait
|
||
```
|
||
|
||
`KIBU_IMAGE` kann ein anderes Image/Tag oder einen unveraenderlichen Digest setzen.
|
||
`DEMO_PORT` aendert den Host-Port. `DEMO_BIND_ADDRESS` ist absichtlich
|
||
`127.0.0.1`; fuer direkten externen Zugriff muss die Bindung bewusst geaendert
|
||
werden. Vorzugsweise HTTPS ueber einen Reverse Proxy nutzen und dann
|
||
`DEMO_SESSION_SECURE=true` setzen. Gemeinsame Demo-Zugaenge sind keine
|
||
Sicherheitsgrenze fuer vertrauliche Daten. Vor oeffentlichem Betrieb sind
|
||
Ressourcen-/Request-Limits am Proxy und die Betriebsgrenzen unten zu beachten.
|
||
|
||
### Normale Instanz mit dem Image
|
||
|
||
Ohne `DEMO_MODE=true` bleiben die Loginfelder leer; der Container fuehrt nur
|
||
`db:setup` aus und behaelt bestehende Daten. `DATABASE_URL` auf die eigene
|
||
PostgreSQL-Datenbank setzen; optional `BOOTSTRAP_EMAIL`, `BOOTSTRAP_PASSWORD`,
|
||
`APP_TIMEZONE` und `SESSION_SECURE` konfigurieren. Die App lauscht im Container
|
||
auf `0.0.0.0:3000`. DB-Readiness vor App-Start sicherstellen.
|
||
|
||
Der destruktive Container-Demostart erfordert gemeinsam `DEMO_MODE=true`,
|
||
`DEMO_RESET_ON_START=true` und genau `demo-db/kibu_demo` als Datenbankziel.
|
||
Diese Einstellungen niemals auf echte Daten umbiegen. Die normalen lokalen
|
||
Reset-Befehle bleiben auf lokale Ziele begrenzt; nur das ausdruecklich
|
||
aktivierte, benannte Container-Demoziel ist zusaetzlich erlaubt.
|
||
|
||
Das Image laeuft als unprivilegierter Node-Benutzer und enthaelt Lizenztexte,
|
||
Quellcode sowie die fuer Einrichtung und Build erforderlichen Werkzeuge.
|
||
`.env`, lokale Daten, Git-Metadaten und lokale Build-Artefakte werden nicht
|
||
in den Build-Kontext uebernommen. Vor dem Push muessen Lizenz-/Quellcodehinweise
|
||
und die veroeffentlichte Quellversion zum Image passen (siehe unten).
|
||
|
||
## Lizenz
|
||
|
||
Copyright (C) 2026 Paul Schoeneck. Originaler KIBU-Code steht unter
|
||
**AGPL-3.0-only mit Zusatzbedingungen nach §7**:
|
||
[Lizenzhinweis](LICENSE), [vollständige AGPL](LICENSES/AGPL-3.0-only.txt)
|
||
und [Zusatzbedingungen](LICENSES/LicenseRef-KIBU-Additional-Terms.txt).
|
||
SPDX: `AGPL-3.0-only AND LicenseRef-KIBU-Additional-Terms`.
|
||
`AND` bildet die zusätzlich geltenden Bedingungen ab, keine Wahl einer anderen Lizenz.
|
||
|
||
- Private, interne und kommerzielle Nutzung, Änderungen, Hosting und Verkauf sind
|
||
erlaubt, wenn die jeweils einschlägigen Lizenzbedingungen eingehalten werden.
|
||
- Bei Weitergabe müssen Lizenz-/Urheberhinweise erhalten bleiben und die
|
||
Anforderungen an korrespondierenden Quellcode erfüllt werden. Veränderte
|
||
Fassungen müssen als solche mit relevantem Änderungsdatum gekennzeichnet sein.
|
||
- Veränderte, über ein Netzwerk genutzte Versionen müssen den interagierenden
|
||
Nutzern einen gut sichtbaren kostenlosen Zugang zu ihrem vollständigen
|
||
korrespondierenden Quellcode anbieten (§13). Dazu gehören auch erforderliche
|
||
Build-/Installationsskripte, nicht aber Kinderdaten, Zugangsdaten oder `.env`.
|
||
Das bedeutet nicht, dass private Änderungen ohne Weitergabe oder Netzwerkangebot
|
||
generell veröffentlicht werden müssen.
|
||
- Die Oberfläche muss den festgelegten Herkunftshinweis bewahren. Es werden
|
||
keine Markenrechte eingeräumt; daraus folgt keine pauschale Pflicht zur
|
||
Umbenennung jeder Änderung. Gesetzlich erlaubte Herkunftsnennungen bleiben möglich.
|
||
- Es gibt keine Gewährleistung. Die Zusatzbedingungen gelten nur für Material,
|
||
für das entsprechende Rechte vorliegen, nicht automatisch für Abhängigkeiten.
|
||
Diese behalten ihre eigenen Lizenztexte und Hinweispflichten; siehe auch
|
||
[Drittanbieterhinweise](THIRD_PARTY_NOTICES.md).
|
||
|
||
Der globale Footer und die öffentliche Seite `/license` zeigen Herkunft, Lizenz,
|
||
Gewährleistungsausschluss und Projektlink. **Vor Veröffentlichung muss der
|
||
Quellcode-Link tatsächlich den vollständigen Quellcode der bereitgestellten
|
||
Version verfügbar machen.** Betreiber veränderter Versionen müssen ihren eigenen
|
||
passenden Quellcodezugang verlinken; der Herkunftslink zum Original bleibt bestehen.
|
||
Bei gebündelten Deployments müssen die von der Lizenzseite gelesenen Dateien aus
|
||
`LICENSES` mit ausgeliefert werden.
|
||
|
||
REUSE-Kennzeichnung: editierbare Quelldateien haben SPDX-Header.
|
||
JSON-Dateien und das generierte `next-env.d.ts` sind in `REUSE.toml` erfasst;
|
||
`KIBU.md` besitzt eine `.license`-Begleitdatei, damit der Inhalt unverändert bleibt.
|
||
`next-env.d.ts` ist eine generierte Next.js-Datei und behält die MIT-Kennzeichnung.
|
||
Prüfung (Python-Werkzeug, keine App-Abhängigkeit):
|
||
|
||
```powershell
|
||
python -m pip install reuse
|
||
python -m reuse lint
|
||
```
|
||
|
||
Diese Erläuterung ist keine Rechtsberatung. Vor Veröffentlichung sind Rechte an
|
||
allen Beiträgen/Assets, Drittanbieterhinweise, die konkrete Zulässigkeit der
|
||
Zusatzbedingungen und gegebenenfalls Markenfragen zu prüfen. Datenschutz und
|
||
Pflichten beim Betrieb mit echten Kinderdaten sind von der Softwarelizenz unabhängig.
|
||
|
||
## Starten
|
||
|
||
Voraussetzungen: Node.js 20.9 oder neuer, npm und Docker Desktop mit lokalem Linux-Container-Kontext.
|
||
|
||
```powershell
|
||
npm install
|
||
npm run configure
|
||
docker compose up -d --wait
|
||
npm run db:setup
|
||
npm run dev
|
||
```
|
||
|
||
App: <http://127.0.0.1:3000>. `db:setup` erstellt Tabellen und beim ersten Lauf einen Zugang `admin@kibu.local`. Das zufällige Passwort erscheint einmal im Terminal. Nach der Anmeldung über den Betreuungsnamen bzw. das Konto-Symbol ändern.
|
||
|
||
Alternativ vor dem ersten `db:setup` in `.env` eine `BOOTSTRAP_EMAIL` und ein `BOOTSTRAP_PASSWORD` mit mindestens 12 Zeichen setzen. Wiederholtes Setup verändert bestehende Konten nicht. `.env` nicht einchecken. Für diese lokale Testinstanz kann das vorhandene Passwort beibehalten werden.
|
||
|
||
Bei vorhandener Installation: App beenden, `npm run db:setup` und `npm run build` ausführen und mit `npm start` neu starten. `db:setup` wendet ausstehende SQL-Migrationen aus `scripts/migrations` einmalig, geordnet und transaktional an. Bestehende Konten, Kinder und Zeiten bleiben erhalten.
|
||
|
||
## Enthalten
|
||
|
||
- Betreuungs-Login mit gesalzenen scrypt-Passworthashes, gehashten Sitzungstokens, HTTP-only-Cookie, 12 Stunden Sitzungsdauer und Login-Limit (10 Versuche pro E-Mail/15 Minuten).
|
||
- Kinder anlegen/bearbeiten: Vorname, Nachname, Klasse/Gruppe und Wochenzeiten mit Abholslots von Montag bis Sonntag; individuelle Abholzeit als ausdrückliche Ausnahme.
|
||
- Für jedes Datum: Wochenplan übernehmen, andere Zeiten setzen oder für den Tag abmelden. Eine Abmeldung im Plan ist unabhängig von der Krankmeldung.
|
||
- Suche, Klassenfilter, Namens-/Abholzeitsortierung und Statusfilter.
|
||
- Tagesstatus: erwartet → angekommen → abgeholt; erwartet → krank. Krankmeldungen können am selben Tag aufgehoben werden. Auch außerplanmäßig ankommende Kinder können eingecheckt werden.
|
||
- Tatsächliche Ankunft und Abholung bleiben je Kalendertag in PostgreSQL gespeichert. Außerplanmäßige Abholung durch Eltern wird gesondert dokumentiert.
|
||
- „Jetzt abholen“ zeigt **anwesende** Kinder mit beginnendem Abholslot bis einschließlich der nächsten 15 Minuten, laufendem Fenster sowie überfälliger Abholung. Ein Slot wird erst nach seinem Ende überfällig (15:00–15:15 ist um 15:15 noch fällig, ab 15:16 überfällig). Bei individueller Zeit gilt diese als Beginn und Ende. Bereits abgeholte oder kranke Kinder erscheinen dort nicht.
|
||
- Tageswechsel und Zeiten verwenden `APP_TIMEZONE` (Standard `Europe/Berlin`), nicht die Browserzeitzone. Automatische Aktualisierung alle 30 Sekunden und beim Zurückkehren in den Tab.
|
||
- Andere Tage können geplant und angesehen werden. Schnelle Anwesenheitsaktionen im Dashboard gelten ausschließlich für heute.
|
||
|
||
### Abholslots und Filter
|
||
|
||
- Zentrale Verwaltung unter „Abholslots“ (`/slots`), nur für angemeldete Betreuung. Anfangs vier unbegrenzte Fenster: **14:00–14:15, 15:00–15:15, 16:00–16:15, 17:00–17:15**.
|
||
- Neue Kinder erhalten standardmäßig den aktiven 16-Uhr-Slot (oder den ersten aktiven Slot). Wochen- und Tagespläne bieten zuerst Slots an; „Individuelle Zeit (Ausnahme)“ blendet die freie Uhrzeit ein. Ohne aktive Slots bleibt die individuelle Zeit verfügbar.
|
||
- Zusätzliche Zeitfenster können angelegt, vorhandene aktiviert/deaktiviert werden. Zeitfenster selbst werden nicht nachträglich umgeschrieben: für andere Zeiten einen neuen Slot anlegen und den alten deaktivieren. So ändern sich bestehende Pläne nicht unbemerkt.
|
||
- Ein ausgewähltes Fenster wird mit Start, Ende und Slot-Referenz im Plan gespeichert. Deaktivierte Slots bleiben in vorhandenen Plänen sichtbar und bei deren Bearbeitung auswählbar, werden für neue Zuordnungen in den Formularen nicht angeboten. Wochenpläne/Tagespläne mit vorher exakt passender Abholzeit werden bei der Migration auf den jeweiligen Standardslot umgestellt; andere freie Zeiten bleiben unverändert.
|
||
- Dashboard mit Slot-Übersicht, Zahl aktuell anwesender Kinder je Slot und eigenem Slotfilter. Slot-Buttons filtern alle zugeordneten Kinder (einschließlich bereits abgeholter), nicht nur anwesende.
|
||
- Klick auf Statistik-, Slot- oder Abholhinweis-Buttons setzt widersprechende Such-/Klassen-/Slotfilter zurück und scrollt zur neu gefilterten Kinderliste; Fokus folgt der Liste. Wiederholte Klicks scrollen erneut. Bei reduzierter Bewegung erfolgt der Sprung ohne Animation.
|
||
|
||
### Aufnahme und Warteliste (Schritt 3)
|
||
|
||
Betreuungsbereich: `/admissions` über „Aufnahme & Warteliste“. Eltern-Einstieg: `/join`, alternativ der direkte Einladungslink.
|
||
|
||
1. **Aufnahmerunde erstellen:** Name und Anmeldefrist (einschließlich, in `APP_TIMEZONE`) festlegen. Der 48-stellige zufällige Einladungscode wird nur einmal angezeigt, in der Datenbank nur als SHA-256-Hash gespeichert. Einladungslink kopieren und selbst mit den Eltern teilen. Verlorene Codes können für offene Runden ersetzt werden; der alte Link wird sofort ungültig.
|
||
2. **Eltern melden ein Kind an:** Ohne Betreuungslogin, nur mit gültigem Code. Vor-/Nachname, Klasse zum Betreuungsstart, Kontaktname, E-Mail, optionale organisatorische Hinweise und ausdrückliche Verarbeitungsbestätigung. Keine anderen Anmeldungen, Profile oder Auslosungsergebnisse sind öffentlich sichtbar. Es gibt keinen automatischen E-Mail-Versand, kein Elternkonto und noch keine spätere Selbstverwaltung.
|
||
3. **Anmeldung schließen:** Manuell vor der Auslosung. Abgelaufene Codes nehmen auch bei noch offen markierter Runde keine Anmeldungen mehr an. Geschlossene Runden können nicht wieder geöffnet werden.
|
||
4. **Einmalig X Plätze auslosen:** X muss zwischen 1 und Anzahl der Anmeldungen liegen (maximal 10.000). Jede Anmeldung hat die gleiche Chance; `crypto.randomInt` mit partieller Fisher-Yates-Auswahl ohne Zurücklegen. Ausgewählte Kinder sind zunächst „Ausgewählt“, die übrigen „Warteliste“. Ziehungszeit, Zugang und Platzzahl werden gespeichert. Eine zweite Auslosung derselben Runde ist ausgeschlossen.
|
||
5. **Aufnahme einzeln bestätigen:** Erst dann wird ein Kind im Dashboard angelegt und die Anmeldung mit dem Profil verknüpft. Wiederholte Bestätigung erzeugt kein zweites Kind. Wochenplan und geprüfte Abholberechtigungen im Profil ergänzen; Kontaktangaben aus der Anmeldung bedeuten nicht automatisch Abholberechtigung. Vor Übernahme bitte auf bereits separat angelegte Kinder prüfen.
|
||
|
||
Anmeldung, Schließen, Auslosung und Bestätigung verwenden gemeinsame Datenbanksperren je Runde und Transaktionen. Damit rutscht keine neue Anmeldung in eine bereits geschlossene/ausgeloste Runde und doppelte Auslosungen/Übernahmen werden verhindert. Listen sind nach Runde getrennt und mit 25 Anmeldungen pro Seite paginiert.
|
||
|
||
Duplikate derselben Runde mit gleichem Kindernamen und gleicher Kontakt-E-Mail (unabhängig von Groß-/Kleinschreibung) werden abgelehnt. Pro Einladung und E-Mail sind maximal zehn Anmeldeversuche pro Stunde möglich. Es gibt noch keine E-Mail-/Identitätsprüfung: mehrfache Anmeldungen mit anderen Angaben lassen sich in dieser Testversion nicht zuverlässig erkennen. Vor echtem Betrieb sind Identitätsprüfung und belastbare Missbrauchsbegrenzung erforderlich. Ein Code ist ein vertraulich zu teilender Zugang zur Anmeldung, keine Platzzusage. Die App bleibt lokal gebunden; Links sind ohne separate Bereitstellung nicht von anderen Geräten erreichbar.
|
||
|
||
Nachrücken, Zusagen-Fristen, Rückzug/Löschen und Benachrichtigungsversand sind noch nicht implementiert; dazu stehen weitere Ideen unten in `KIBU.md`. Wartelistenanmeldungen sind keine Kinderprofile und bleiben vom Anwesenheits-Audit getrennt.
|
||
|
||
### Kinderprofile (Schritt 2)
|
||
|
||
- Über Namen, Initialen oder „Profil, Abholberechtigte & Verlauf“ auf jeder Karte erreichbar. Profile sind nur nach Anmeldung zugänglich.
|
||
- Tagesdetails und Anwesenheitsverlauf mit tatsächlichen Ankunfts-/Abholzeiten, Art des Verlassens und seitenweisem Verlauf (25 Datensätze). Die historischen tatsächlichen Zeiten werden durch Änderungen am heutigen Wochenplan nicht verändert. Historische Planansichten verwenden den aktuellen Wochenplan plus Tagesabweichungen, nicht einen versionierten Planstand.
|
||
- Vergessene Ankunft/Abholung nachtragen, Zeiten korrigieren, Krankmeldungen ändern oder falsche Einträge zurücksetzen. Datum in den Tagesdetails auswählen, dann „Anwesenheit korrigieren/nachtragen“. Ein Grund (5–500 Zeichen) ist Pflicht.
|
||
- Korrekturen sind nur für heute oder vergangene Tage möglich. Tatsächliche Zeiten dürfen nicht in der Zukunft liegen; Abholung nicht vor Ankunft. Alle Zeiten gelten in `APP_TIMEZONE`. Nicht existente bzw. mehrdeutige Zeiten während einer Zeitumstellung werden ausdrücklich abgelehnt.
|
||
- Versionsprüfung und gemeinsame Kind-Sperren verhindern, dass eine Korrektur neuere Anwesenheitsänderungen unbemerkt überschreibt. In diesem Fall Profil neu laden und aktuelle Werte prüfen.
|
||
- Abholpersonen mit Name, Beziehung, optional Telefon/Hinweisen und expliziter Berechtigung. Berechtigung entziehen statt Historie löschen. Die Elternabholungs-Bestätigung im Dashboard zeigt aktuell erlaubte Personen; fehlende Angaben bedeuten keine bestätigte Berechtigung.
|
||
- Pro Wochentag eine ausdrückliche Erlaubnis zum Alleingehen ab einer Uhrzeit. Ohne Regel kein Alleingang. Das Dashboard zeigt die Regel und erlaubt „Alleingang bestätigen“ nur für ein anwesendes Kind am erlaubten Tag ab der erlaubten Uhrzeit; die Regel wird auch serverseitig geprüft. Es erfolgt niemals ein automatischer Checkout. Geplante Abholzeit und früheste Alleingehzeit bleiben getrennte Angaben.
|
||
- Historische Korrekturen dokumentieren tatsächliche Ereignisse: Ein nachgetragener Alleingang wird nicht anhand der heutigen Erlaubnis blockiert. Der Grund und die Betreuungsperson bleiben sichtbar.
|
||
- Klassenwechsel über „Stammdaten & Wochenplan“: Klasse bearbeiten, ohne Kind neu anzulegen. Identität, Verlauf, Abholpersonen und Regeln bleiben erhalten; die Änderung erscheint im Audit-Log.
|
||
|
||
### Audit-Log
|
||
|
||
PostgreSQL-Trigger protokollieren Stammdaten, Wochenpläne, Tagesabweichungen, Anwesenheiten, Abholpersonen und Alleingehregeln in derselben Transaktion wie die Änderung. Pro Eintrag: alter/neuer Zustand, Betreuungstag soweit vorhanden, Änderungszeit, ausführender Zugang und Grund. Reine Änderungen ohne andere Werte erzeugen keinen zusätzlichen Log-Eintrag.
|
||
|
||
Das Profil zeigt Änderungen verständlich aufgeschlüsselt und seitenweise (25 Einträge), neueste zuerst. Auch Zurücksetzen/Entziehen ist nachvollziehbar. Bestehende Anwesenheiten vor Einführung werden einmalig als Bestandsübernahme markiert; frühere, damals nicht erfasste Änderungen werden nicht erfunden.
|
||
|
||
UPDATE, DELETE und TRUNCATE des Logs werden durch Datenbank-Trigger abgelehnt. Direkte Datenbankänderungen ohne Anwendungskontext werden als „Datenbank / Einrichtung“ gekennzeichnet. Das ist ein nachvollziehbares Anwendungsprotokoll, kein Schutz gegen privilegierte Datenbankadministratoren, die Trigger deaktivieren könnten. Der derzeit gemeinsam genutzte Testzugang identifiziert den Zugang, nicht einzelne reale Betreuungspersonen.
|
||
|
||
### Fiktive Testdaten
|
||
|
||
```powershell
|
||
npm run db:seed
|
||
```
|
||
|
||
Erstellt zwölf **rein fiktive** Kinder mit verschiedenen Klassen, Wochenzeiten, heutigen Status/Abholfenstern, Abholberechtigten, Alleingehregeln und zwei Wochen Anwesenheitsverlauf. Mila Sonnental hat im letzten Betreuungstag eine vergessene Abholung zum Korrigieren. Namen und Kontakte sind ausschließlich Testdaten; Telefonnummern werden nicht erfunden.
|
||
|
||
Das Skript verwendet feste Demo-IDs und überspringt vorhandene Kinder vollständig. Erneutes Ausführen überschreibt weder manuelle Tests noch Zugangsdaten und aktualisiert bewusst auch nicht die täglich wechselnden Demostatus. Die initialen heutigen Zeiten beziehen sich auf den Zeitpunkt des ersten Seeds; zum Testen später bei Bedarf Tagespläne und Anwesenheiten anpassen.
|
||
|
||
## Datenbank
|
||
|
||
PostgreSQL 17 läuft unter dem Compose-Projektnamen `kibu` und ist nur an `127.0.0.1:55432` gebunden. `npm run configure` erzeugt ein zufälliges Datenbankpasswort in der lokalen `.env`; vorhandene Konfiguration wird nicht überschrieben.
|
||
|
||
```powershell
|
||
docker compose ps
|
||
docker compose stop
|
||
docker compose up -d --wait
|
||
```
|
||
|
||
Das benannte Volume `kibu_kibu_postgres` erhält die Daten bei Neustarts. **Nicht** `docker compose down -v` verwenden, wenn Daten erhalten bleiben sollen. Regelmäßige verschlüsselte Backups sind vor realem Einsatz erforderlich.
|
||
|
||
## Testinstanz leeren oder neu befuellen
|
||
|
||
**Achtung: unwiderruflich, nur fuer lokale Testdatenbanken!** Vorher die App
|
||
beenden. Beide Befehle loeschen alle Kinder, Wochen-/Tagesplaene, Anwesenheit,
|
||
Abholberechtigungen, Alleingehregeln, den gesamten Audit-Verlauf,
|
||
Aufnahmerunden, Anmeldungen, Limits, Betreuungskonten und Sitzungen.
|
||
Eigene Slots werden durch die vier aktiven Standardslots ersetzt.
|
||
Schema, angewendete Migrationen und die lokale `.env` bleiben erhalten.
|
||
Der Audit-Loeschschutz wird nur innerhalb der Reset-Transaktion kurz aufgehoben;
|
||
bei einem Fehler wird die gesamte Leerung zurueckgerollt.
|
||
|
||
```powershell
|
||
# Nur leeren, noch ohne neuen Zugang oder Demokinder:
|
||
npm run db:clear -- --confirm-reset
|
||
|
||
# Leeren, neuen Zugang erstellen und 12 fiktive Kinder mit Verlauf anlegen:
|
||
npm run db:reset -- --confirm-reset
|
||
```
|
||
|
||
Ohne `--confirm-reset` wird nichts geloescht. Remote-Datenbankadressen und
|
||
PostgreSQL-Verwaltungsdatenbanken werden abgelehnt. Die Adresse allein ersetzt
|
||
keine Pruefung des Ziels: auch eine lokale Portweiterleitung darf nicht auf
|
||
Produktivdaten zeigen.
|
||
|
||
`db:reset` fuehrt nach dem Leeren die vorhandenen Befehle `db:setup` und
|
||
`db:seed` aus. Ein neues zufaelliges Passwort erscheint im Terminal; wenn in
|
||
`.env` `BOOTSTRAP_EMAIL`/`BOOTSTRAP_PASSWORD` gesetzt sind, werden diese benutzt.
|
||
Alte Passwoerter und Sitzungen funktionieren danach nicht mehr. Die Demodaten
|
||
umfassen Kinder, Wochenplaene, Tagesabweichungen, Kontakte, Alleingehregeln und
|
||
zwei Wochen Anwesenheitsverlauf; Aufnahmerunden bleiben leer.
|
||
|
||
Nach `db:clear` bei Bedarf `npm run db:setup` und `npm run db:seed` einzeln
|
||
ausfuehren. `db:seed` allein ist weiterhin nicht destruktiv und ueberschreibt
|
||
keine vorhandenen Kinder. Schlaegt die Neueinrichtung nach erfolgreichem Leeren
|
||
fehl, bleibt die Instanz leer bzw. teilweise eingerichtet; Ursache beheben und
|
||
`db:setup`/`db:seed` erneut ausfuehren. Anschliessend die App wieder starten.
|
||
|
||
## Prüfen
|
||
|
||
```powershell
|
||
npm test
|
||
npm run test:db
|
||
npm run test:reset
|
||
npm run build
|
||
```
|
||
|
||
`test:db` benötigt eine eingerichtete Datenbank. Eigene Kinder-/Audit-Testdatensätze werden innerhalb von Transaktionen geprüft und vollständig zurückgerollt. Der Paralleltest verwendet eine eigene kurzlebige Aufnahmerunde und entfernt diese samt Anmeldungen im Anschluss. Bestehende Demodaten bleiben erhalten. Geprüft werden unter anderem Korrekturen, Versionskonflikte, Vorher-/Nachher-Protokollierung, unveränderliches Audit-Log, Berechtigungen, Slots, Anmeldungen, konkurrierende Auslosungen und einmalige Übernahme. Unit-Tests prüfen exakte Fenstergrenzen und die gleichberechtigten Auswahlpfade kleiner Ziehungen. `npm run typecheck` prüft TypeScript ohne Build.
|
||
|
||
`test:reset` erstellt eine eigene zufaellig benannte lokale Testdatenbank und
|
||
entfernt ausschliesslich diese wieder. Der Datenbankzugang benoetigt dafuer
|
||
`CREATEDB` (beim lokalen Compose-Zugang vorhanden). Der Test prueft Schutzabfragen,
|
||
vollstaendige Leerung, Standardslots, erneute Demo-Befuellung, neue Zugangsdaten
|
||
und den nach dem Reset wieder aktiven Audit-Loeschschutz.
|
||
|
||
## Betriebsgrenze
|
||
|
||
Diese Version ist für den lokalen Testbetrieb gedacht, nicht zur unveränderten Veröffentlichung im Internet. Entwicklungs- und Produktionsserver binden standardmäßig nur an `127.0.0.1`. Für einen echten Einsatz mit Kinderdaten sind unter anderem HTTPS, datenschutzgerechte Betriebs-/Löschkonzepte einschließlich Audit-Daten, Backup/Restore und individuelle Betreuungszugänge erforderlich. Bei HTTPS `SESSION_SECURE=true` setzen. Der erste Zugang ist kein öffentliches Standardpasswort.
|
||
|
||
Ein lokaler Produktionsbuild lässt sich mit `npm run build` und `npm start` starten. Ein laufender Entwicklungsserver muss dafür vorher beendet werden oder ein anderer Port gewählt werden.
|