85 lines
4.9 KiB
Markdown
85 lines
4.9 KiB
Markdown
# 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.
|