Initial release 0.1.0
This commit is contained in:
commit
9f97d8407a
52 files changed
+6774
No files matched your search
@@ -0,0 +1,38 @@
|
||||
# Abnahme
|
||||
|
||||
## Etappe 1
|
||||
|
||||
| Kriterium | Nachweis | Stand |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------- |
|
||||
| Frischer Checkout startet ohne Cloudron | `npm ci` erfolgreich; README-Setup und lokaler Produktionsstart ausgeführt | erfüllt am 21.10.2026 |
|
||||
| Typprüfung und Build erfolgreich | `npm run check`, `npm run build` | erfüllt am 21.10.2026 |
|
||||
| Theme bleibt nach Neuladen erhalten | Playwright: System auf Hell wechseln, Reload, DOM und Schalterzustand prüfen | erfüllt am 21.10.2026 |
|
||||
| Testdaten überleben Neustart | Gebauten Server zweimal gegen `.data/sendewerk.sqlite` gestartet; Fundusdaten und `/healthz` jeweils vorhanden | erfüllt am 21.10.2026 |
|
||||
| Migration wiederholt ausführbar | lokal mehrfach ausgeführt; Verhaltenstest führt Migration zweimal in temporärer DB aus | erfüllt am 21.10.2026 |
|
||||
| Seed reproduzierbar | lokal und im Verhaltenstest zweimal ausgeführt; danach 4 Pieces, 1 Sendung und 3 Verwendungen | erfüllt am 21.10.2026 |
|
||||
| Tests verwenden getrennte Daten | Vitest und Playwright erzeugen je eigene Datenbank im Betriebssystem-Tempdir | erfüllt am 21.10.2026 |
|
||||
| Desktop und Smartphone ohne horizontales Scrollen | 4 Playwright-Abläufe; 1440x1000, 1280x900 und 390x844; Screenshots visuell kontrolliert | erfüllt am 21.10.2026 |
|
||||
| Cloudron-Pfade und Healthcheck vorbereitet | Manifestpfad `/app/data/sendewerk.sqlite`, `/healthz`, `start.sh`; JSON-Kernfelder und Bash-Syntax geprüft | vorbereitet; Container offen |
|
||||
| Echte Cloudron-Prüfung | Installation, Backup/Restore, Proxy und read-only Laufzeit | offen, kein Serverzugang |
|
||||
|
||||
## Ausgeführte Prüfungen
|
||||
|
||||
- `npm ci`: erfolgreich, 190 Pakete geprüft, 0 gemeldete Schwachstellen
|
||||
- `npm run setup`, anschließend erneute Migration und erneuter Seed: erfolgreich
|
||||
- `npm test`: 2 Verhaltenstests erfolgreich
|
||||
- `npm run lint`: erfolgreich
|
||||
- `npm run check`: 0 Fehler und 0 Warnungen
|
||||
- `npm run build`: erfolgreich mit `@sveltejs/adapter-node`
|
||||
- `npm run test:e2e`: 4 von 4 Browsertests erfolgreich
|
||||
- Zwei getrennte `npm start`-Läufe: Healthcheck und persistente Daten erfolgreich
|
||||
- `bash -n start.sh` und programmatische Manifest-Kernfeldprüfung: erfolgreich
|
||||
|
||||
## Nicht erfolgreich oder nicht ausführbar
|
||||
|
||||
- `docker build -t sendewerk:local .`: nicht ausgeführt, weil der installierte
|
||||
Docker-Client keinen laufenden Daemon unter `/var/run/docker.sock` erreichen
|
||||
konnte.
|
||||
- Echte Cloudron-Installation: mangels Serverzugang nicht ausgeführt.
|
||||
- Ein zusätzlicher Python-Playwright-Lauf: nicht gestartet, weil das optionale
|
||||
Python-Modul `playwright` nicht installiert war. Die projektgebundene
|
||||
TypeScript-Playwright-Suite lief stattdessen vollständig erfolgreich.
|
||||
@@ -0,0 +1,84 @@
|
||||
# Architektur
|
||||
|
||||
## Systemgrenze
|
||||
|
||||
Sendewerk ist ein einzelner SvelteKit-Prozess. Browserseiten, serverseitige
|
||||
Actions, spätere REST-Endpunkte und Hintergrundaufgaben verwenden dieselbe
|
||||
Geschäftslogik. SQLite und ein lokales Upload-Verzeichnis sind die einzigen
|
||||
persistenten Laufzeitabhängigkeiten. Externe Mail-, RSS- oder KI-Dienste sind
|
||||
nicht Voraussetzung für Kernfunktionen.
|
||||
|
||||
```text
|
||||
Browser -> SvelteKit-Routen -> Anwendungsdienste -> SQLite
|
||||
| -> Upload-Verzeichnis
|
||||
+-> später: Mail/RSS über Adapter
|
||||
```
|
||||
|
||||
Servercode lebt unter `src/lib/server` und darf nicht in Browser-Bundles
|
||||
gelangen. Routen liefern nur die für ihre Ansicht erlaubten Daten. Fachlogik
|
||||
wird nicht an Svelte-Komponenten gebunden, damit Browseraktionen und die
|
||||
spätere API dieselben Regeln verwenden.
|
||||
|
||||
## Laufzeit und Speicher
|
||||
|
||||
- Lokal: `.data/sendewerk.sqlite` und `.data/uploads`, jeweils konfigurierbar.
|
||||
- Tests: pro Lauf ein temporäres Verzeichnis unter dem Betriebssystem-Tempdir.
|
||||
- Cloudron: `/app/data/sendewerk.sqlite` und `/app/data/uploads`.
|
||||
- Migrationen liegen nummeriert unter `migrations/`, laufen in Transaktionen
|
||||
und werden in `schema_migrations` protokolliert.
|
||||
- Der Seed nutzt stabile IDs und Transaktionen. Wiederholung liefert denselben
|
||||
fachlichen Ausgangsbestand, ohne Migrationstabellen anzutasten.
|
||||
- Zeitpunkte werden als ISO-8601-UTC-Text gespeichert. Dauern sind nichtnegative
|
||||
ganze Sekunden. Zeitzonendarstellung ist `Europe/Berlin`.
|
||||
|
||||
## Geplantes Gesamtdatenmodell
|
||||
|
||||
Etappe 1 materialisiert nur den für echte Vorschau- und Seed-Daten benötigten
|
||||
Kern. Folgende Grenzen sind für spätere Migrationen bereits festgelegt.
|
||||
|
||||
| Bereich | Geplante Entitäten und Beziehungen |
|
||||
| ----------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Identität | `users`, Rollen, Sessions, Einladungen, Reset-Tokens, Sperren und technische Zugänge; Tokens nur gehasht |
|
||||
| Taxonomie | getrennte `section_categories`, `formats`, `topics`; Pieces und Vorschläge über Zuordnungstabellen mehrfach verknüpft |
|
||||
| Inhalt | `pieces` mit Status und Dauer; Quellen, Medien, private Recherche, Moderation, Präsentation und Vorlagen als getrennte Daten |
|
||||
| Sendungsbau | `shows`, geordnete `show_sections`, kopierte `piece_usages`, Reservebank und Sendungsvorlagen; Original-ID bleibt Referenz |
|
||||
| Live | expliziter Live-Stand, aktuelles Element, Status je Verwendung, tatsächliche Zeiten und getrennte Präsentationsausgabe |
|
||||
| Historie | unveränderliche Abschluss-Snapshots und Verwendungshistorie; Übersprungenes zählt nicht als gesendet |
|
||||
| Freigaben | widerrufbare, gehashte Lesetokens mit Sendung, Umfang, Passwortoption und Ablaufzeit |
|
||||
| RSS | Feedquellen, Abrufläufe und externe Einträge mit stabiler Herkunfts-ID sowie Status neu/übernommen/verworfen |
|
||||
| API/Audit | technische Berechtigungen, Idempotenzschlüssel und Audit-Ereignisse mit Akteur, Aktion und Ziel |
|
||||
| Betrieb | Anwendungseinstellungen und spätere Job-Zustände, keine Geheimnisse im Klartext ohne begründete Schutzstrategie |
|
||||
|
||||
### Historien- und Kopierregel
|
||||
|
||||
Beim Einplanen entsteht eine bearbeitbare `piece_usage`-Kopie der
|
||||
sendungsrelevanten Texte und Dauer. Das Original bleibt verknüpft, wird aber
|
||||
nicht live gespiegelt. Beim Abschluss wird der damalige Sendungsinhalt stabil
|
||||
eingefroren. Eine historische Sendung wird dupliziert, nie weiterbearbeitet.
|
||||
|
||||
### Dauerregel
|
||||
|
||||
Eine Abschnittsdauer ist entweder die Summe ihrer eingeplanten Verwendungen
|
||||
oder eine explizite Abschnittsdauer. Beides wird nie addiert. Reserveelemente
|
||||
zählen erst nach dem Einplanen. Geplante und tatsächliche Dauer bleiben
|
||||
getrennt.
|
||||
|
||||
## Oberflächenstruktur
|
||||
|
||||
Die Hauptnavigation umfasst Eingang, Fundus, Sendungen, Archiv und Verwaltung.
|
||||
Auf breiten Ansichten stehen Fundus und Ablauf nebeneinander. Auf schmalen
|
||||
Ansichten werden sie über eine gut erreichbare Umschaltung einzeln gezeigt.
|
||||
Der Live-Modus ist eine eigene, fokussierte Ansicht; die spätere
|
||||
Präsentationsausgabe erhält eine separate, strikt reduzierte Datenansicht.
|
||||
|
||||
Etappe 1 zeigt Fundus, Sendungsbau und Live-Modus als sichtbare
|
||||
`Gestaltungsvorschau`. Die Daten kommen bereits aus SQLite, mutierende
|
||||
Fachabläufe werden jedoch nicht vorgetäuscht.
|
||||
|
||||
## Sicherheitsgrenzen ab den Folgeetappen
|
||||
|
||||
Authentifizierung und Autorisierung werden serverseitig an jeder Route und
|
||||
Action geprüft. Markdown und fremdes HTML werden vor Ausgabe bereinigt.
|
||||
Uploadzugriff folgt denselben Rechten. Netzwerkabrufe erhalten Schutz gegen
|
||||
interne Ziele, Größen-/Zeitlimits und kontrollierte Redirects. Diese Regeln
|
||||
sind geplant, aber nicht Bestandteil der Etappe-1-Vorschauen.
|
||||
@@ -0,0 +1,83 @@
|
||||
# Entscheidungen
|
||||
|
||||
Stand der Quellenprüfung: 21. Oktober 2026. Verwendet wurden offizielle
|
||||
Dokumentationen und die npm-Registry für konkrete Paket-Metadaten.
|
||||
|
||||
## D-001: SvelteKit 3 und Node-Unterstützung
|
||||
|
||||
Die Anwendung verwendet SvelteKit 3, Svelte 5, TypeScript und Vite 8. Das
|
||||
Projekt wurde gemäß aktueller Empfehlung mit `npx sv create` angelegt. Die
|
||||
Kit-Konfiguration liegt bei SvelteKit 3 in `vite.config.ts`, nicht in einer
|
||||
`svelte.config.js`.
|
||||
|
||||
Die lokale Mindestversion ist Node 22.17. Das Cloudron-Image nutzt Node 24 LTS.
|
||||
Der vorhandene lokale Lauf wurde mit Node 22.23.1 geplant.
|
||||
|
||||
Quellen:
|
||||
|
||||
- <https://svelte.dev/docs/kit/creating-a-project>
|
||||
- <https://svelte.dev/docs/kit/migrating-to-sveltekit-3>
|
||||
- <https://svelte.dev/docs/cli/sv-create>
|
||||
- npm-Metadaten für `@sveltejs/kit` 3.1.0 am 21.10.2026
|
||||
|
||||
## D-002: Offizieller Node-Adapter
|
||||
|
||||
`@sveltejs/adapter-node` erzeugt den Produktionsserver in `build/`. Gebaut wird
|
||||
mit `npm run build`, gestartet mit `node build`. `HOST` und `PORT` konfigurieren
|
||||
den Server. Der Adapter behandelt SIGTERM/SIGINT und kontrolliertes Herunter-
|
||||
fahren; ein eigener Server ist für Etappe 1 nicht erforderlich.
|
||||
|
||||
Quelle: <https://svelte.dev/docs/kit/adapter-node>
|
||||
|
||||
## D-003: SQLite mit better-sqlite3
|
||||
|
||||
`better-sqlite3` 13.x wird als gekapselter synchroner Treiber verwendet. Das
|
||||
Paket ist MIT-lizenziert und verlangt Node 22 oder neuer. Gegenüber
|
||||
`node:sqlite` wird damit in Etappe 1 keine API verwendet, die in der offiziellen
|
||||
Node-24-Dokumentation noch als Release Candidate gekennzeichnet ist. Die
|
||||
Datenbankgrenze bleibt in `src/lib/server` gekapselt.
|
||||
|
||||
Migrationen sind eigene nummerierte SQL-Dateien und laufen transaktional. WAL
|
||||
wird in Etappe 1 nicht aktiviert; für die kleine Redaktion ist das
|
||||
Rollback-Journal zunächst ausreichend und vereinfacht die frühe
|
||||
Betriebsprüfung.
|
||||
|
||||
Quellen:
|
||||
|
||||
- <https://nodejs.org/docs/latest-v24.x/api/sqlite.html>
|
||||
- <https://www.sqlite.org/lang_transaction.html>
|
||||
- npm-Metadaten für `better-sqlite3` 13.0.3 am 21.10.2026
|
||||
|
||||
## D-004: Cloudron-Paket
|
||||
|
||||
Das Paket nutzt `manifestVersion: 2`, internen HTTP-Port 3000 und `/healthz`.
|
||||
`localstorage.sqlite.paths` nennt `/app/data/sendewerk.sqlite`, damit Cloudron
|
||||
eine konsistente Sicherung der aktiven SQLite-Datei erstellen kann. Das
|
||||
Startskript stellt Verzeichnisse und Besitzrechte her, migriert als Benutzer
|
||||
`cloudron` und ersetzt sich zuletzt per `exec` durch den Node-Prozess.
|
||||
|
||||
Das Image ist auf die am 21.10.2026 offiziell dokumentierte datierte Node-24-
|
||||
Basis samt Digest gepinnt. Außer `/app/data`, `/run` und `/tmp` wird das
|
||||
Laufzeitdateisystem als read-only behandelt.
|
||||
|
||||
Quellen:
|
||||
|
||||
- <https://docs.cloudron.io/packaging/>
|
||||
- <https://docs.cloudron.io/packaging/manifest/>
|
||||
- <https://docs.cloudron.io/packaging/addons/#localstorage>
|
||||
- <https://docs.cloudron.io/packaging/cheat-sheet/>
|
||||
|
||||
## D-005: Theme ohne serverseitiges Nutzerkonto
|
||||
|
||||
Etappe 1 speichert `light`, `dark` oder `system` in `localStorage`. Ein kurzes
|
||||
Inline-Skript in `app.html` setzt das resultierende Theme vor dem ersten Paint
|
||||
auf dem Wurzelelement. Dies vermeidet einen falschen Theme-Blitz und benötigt
|
||||
vor Etappe 2 weder Cookie noch Konto. Die Einstellung bleibt bei Neuladen im
|
||||
gleichen Browser erhalten.
|
||||
|
||||
## D-006: Etappe-1-Vorschauen statt Attrappen
|
||||
|
||||
Vorschauseiten lesen echte persistente SQLite-Seed-Daten, bieten aber keine
|
||||
funktionslosen Speichern- oder Live-Schaltflächen. Ein sichtbarer Hinweis
|
||||
grenzt Gestaltungsvorschauen von den späteren Fachfunktionen ab. Damit wird
|
||||
keine noch nicht implementierte Funktion als fertig dargestellt.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Projektstatus
|
||||
|
||||
## Aktueller Umfang
|
||||
|
||||
Etappe 1 ist abgeschlossen. Architektur, Gesamtdatenmodell, Entscheidungen und
|
||||
lokaler Betriebsweg sind dokumentiert. Etappe 2 wurde nicht begonnen.
|
||||
|
||||
## Umgesetzter Stand Etappe 1
|
||||
|
||||
- SvelteKit-/TypeScript-Monolith mit Node-Adapter
|
||||
- konfigurierbare lokale SQLite- und Uploadpfade
|
||||
- wiederholbare Migrationen und realistischer Seed
|
||||
- persistentes Light-/Dark-/System-Theme
|
||||
- responsive Navigation und gekennzeichnete Vorschauen für Fundus,
|
||||
Sendungsbau und Live-Modus
|
||||
- Healthcheck, Produktionsstart und frühes Cloudron-Paket
|
||||
- getrennte Unit-/Integrations- und Browser-Testdaten
|
||||
|
||||
Die Vorschauen lesen echte Daten aus SQLite. Suche und mobile Pane-Umschaltung
|
||||
funktionieren lokal; redaktionelle Schreiboperationen bleiben bewusst den
|
||||
späteren Etappen vorbehalten.
|
||||
|
||||
## Nicht Bestandteil dieser Etappe
|
||||
|
||||
Anmeldung, Rollen, echte Inhaltsbearbeitung, Autospeichern, Sendungsplanung,
|
||||
Live-Steuerung, Präsentationsfenster, Archivabschluss, Freigaben, RSS und API.
|
||||
Die Vorschauen dürfen nicht als Implementierung dieser Funktionen verstanden
|
||||
werden.
|
||||
|
||||
## Bekannte offene Betriebsprüfung
|
||||
|
||||
Eine echte Cloudron-Installation samt Backup/Restore, Reverse-Proxy-Verhalten
|
||||
und read-only Laufzeit konnte ohne bereitgestellten Cloudron-Server nicht
|
||||
durchgeführt werden. Auch der lokale Container-Smoke-Test blieb offen, weil
|
||||
auf der Prüfmaschine kein Docker-Daemon lief. Manifestkernfelder und
|
||||
Startskript-Syntax wurden lokal geprüft.
|
||||
|
||||
## Verifizierte Umgebung
|
||||
|
||||
- Node.js 22.23.1, npm 10.9.8
|
||||
- SvelteKit 3.1.0, Svelte 5.57.2, Vite 8.3.5
|
||||
- SQLite-Treiber `better-sqlite3` 13.0.3
|
||||
- Playwright 1.64.1 mit Chromium 156.0.8078.4 (Fallback-Build für Ubuntu 24.04)
|
||||
Reference in new issue
Block a user