0.13.1-4 release snapshot
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
# Backend-Services
|
||||
|
||||
Das Backend ist in Services aufgeteilt, die von Express-Routen orchestriert werden. Seit v0.12.0 erfolgt die Medienverarbeitung über ein **Plugin-System**.
|
||||
|
||||
---
|
||||
|
||||
## Plugin-System (`src/plugins/`)
|
||||
|
||||
Ab v0.12.0 ist die Pipeline modular aufgebaut. Jeder Medientyp wird von einem eigenen Plugin verwaltet.
|
||||
|
||||
### Basisklassen
|
||||
|
||||
- **`PluginBase.js`** — Abstrakte Basisklasse `SourcePlugin` mit Lifecycle-Methoden
|
||||
- **`PluginRegistry.js`** — Dynamische Plugin-Erkennung, prioritätsbasierte Auswahl, Settings-Schema-Aggregation
|
||||
- **`PluginContext.js`** — Ausführungskontext (Logger, Callbacks, Signals) für Plugin-Aufrufe
|
||||
|
||||
### Plugin-Lifecycle
|
||||
|
||||
Jedes Plugin implementiert die folgenden Methoden:
|
||||
|
||||
| Methode | Beschreibung |
|
||||
|---|---|
|
||||
| `detect(discInfo)` | Medientyp-Erkennung |
|
||||
| `analyze(devicePath, job, ctx)` | Analyse / Metadaten-Extraktion |
|
||||
| `rip(job, ctx)` | Rohdaten-Extraktion |
|
||||
| `review(job, ctx)` | Optionale Vorschau-Vorbereitung |
|
||||
| `encode(job, ctx)` | Finales Encoding/Konvertierung |
|
||||
| `finalize(job, ctx)` | Nachbearbeitung |
|
||||
| `onCancel(job, ctx)` | Bereinigung bei Abbruch |
|
||||
| `onRetry(job, ctx)` | Zustand-Reset vor Retry |
|
||||
|
||||
### Implementierte Plugins
|
||||
|
||||
- **`BluRayPlugin.js`** — Blu-ray via MakeMKV (Backup-Modus)
|
||||
- **`DVDPlugin.js`** — DVD via MakeMKV (MKV-Modus)
|
||||
- **`CdPlugin.js`** — Audio-CD via cdparanoia + FFmpeg (experimentell)
|
||||
- **`AudiobookPlugin.js`** — AAX/M4B via FFmpeg mit Kapitel-Splitting
|
||||
- **`ConverterPlugin.js`** — Generische Audio/Video-Konvertierung via FFmpeg
|
||||
- **`VideoDiscPlugin.js`** — Gemeinsame Basis für Blu-ray/DVD (MediaInfo-Parsing)
|
||||
|
||||
---
|
||||
|
||||
## `pipelineService.js`
|
||||
|
||||
Zentrale Workflow-Orchestrierung.
|
||||
|
||||
Aufgaben:
|
||||
|
||||
- Pipeline-State-Machine + Persistenz (`pipeline_state`)
|
||||
- Disc-Analyse/Rip/Review/Encode via Plugin-Delegation
|
||||
- Queue-Management (Jobs + `script|chain|wait` Einträge)
|
||||
- Retry/Re-Encode/Restart-Flows
|
||||
- WebSocket-Broadcasts für State/Progress/Queue
|
||||
- Converter-Job-Verwaltung (`createConverterJobFromEntry`, `uploadConverterFiles`, `startConverterJob`)
|
||||
|
||||
Wichtige Methoden:
|
||||
|
||||
- `analyzeDisc()`
|
||||
- `selectMetadata()`
|
||||
- `startPreparedJob()`
|
||||
- `confirmEncodeReview()`
|
||||
- `cancel()`
|
||||
- `retry()`
|
||||
- `reencodeFromRaw()`
|
||||
- `restartReviewFromRaw()`
|
||||
- `restartEncodeWithLastSettings()`
|
||||
- `resumeReadyToEncodeJob()`
|
||||
- `enqueueNonJobEntry()`, `reorderQueue()`, `removeQueueEntry()`
|
||||
- `createConverterJobFromEntry()`, `createConverterJobsFromSelection()`
|
||||
- `uploadConverterFiles()`, `startConverterJob()`
|
||||
|
||||
---
|
||||
|
||||
## `diskDetectionService.js`
|
||||
|
||||
Pollt Laufwerk(e) und emittiert:
|
||||
|
||||
- `discInserted`
|
||||
- `discRemoved`
|
||||
- `error`
|
||||
|
||||
Zusatz:
|
||||
|
||||
- Modus `auto` oder `explicit`
|
||||
- heuristische `mediaProfile`-Erkennung (`bluray`/`dvd`/`other`)
|
||||
- `rescanAndEmit()` für manuellen Trigger
|
||||
|
||||
---
|
||||
|
||||
## `settingsService.js`
|
||||
|
||||
Settings-Layer mit Validation/Serialisierung.
|
||||
|
||||
Features:
|
||||
|
||||
- `getCategorizedSettings()` für UI-Form
|
||||
- `setSettingValue()` / `setSettingsBulk()`
|
||||
- profilspezifische Auflösung (`resolveEffectiveToolSettings`)
|
||||
- CLI-Config-Building für MakeMKV/HandBrake/MediaInfo/FFmpeg
|
||||
- HandBrake-Preset-Liste via `HandBrakeCLI -z`
|
||||
- MakeMKV-Registration-Command aus `makemkv_registration_key`
|
||||
- Pfadauflösung für alle Medienprofile inkl. Audiobook und Converter
|
||||
|
||||
---
|
||||
|
||||
## `historyService.js`
|
||||
|
||||
Historie + Dateioperationen.
|
||||
|
||||
Features:
|
||||
|
||||
- Job-Liste/Detail inkl. Log-Tail
|
||||
- Orphan-RAW-Erkennung und Import
|
||||
- OMDb-Nachzuweisung
|
||||
- Dateilöschung (`raw|movie|both`)
|
||||
- Job-Löschung (`none|raw|movie|both`)
|
||||
|
||||
---
|
||||
|
||||
## `audiobookService.js`
|
||||
|
||||
Audiobook-Verarbeitung (AAX/M4B).
|
||||
|
||||
Features:
|
||||
|
||||
- FFprobe-basierte Analyse (Kapitel, Metadaten)
|
||||
- FFmpeg-basiertes Encoding mit Kapitel-Splitting
|
||||
- Ausgabeformate: M4B, MP3, FLAC
|
||||
- Template-basierte Pfade (`{author}`, `{title}`, `{year}`, `{narrator}`, `{series}`, `{part}`)
|
||||
|
||||
---
|
||||
|
||||
## `activationBytesService.js`
|
||||
|
||||
Verwaltung von Audible-Activation-Bytes für AAX-DRM-Handling.
|
||||
|
||||
Features:
|
||||
|
||||
- SHA-1-Prüfsumme der AAX-Datei berechnen
|
||||
- Activation Bytes in `aax_activation_bytes`-Tabelle cachen
|
||||
- Lookup via `audnexService` (wenn konfiguriert)
|
||||
|
||||
---
|
||||
|
||||
## `converterScanService.js`
|
||||
|
||||
Dateisystem-Überwachung des Converter-Eingangsordners.
|
||||
|
||||
Features:
|
||||
|
||||
- Vollständiger FS-Baum (`getTree()`)
|
||||
- DB-basierter Datei-Explorer (`getEntries()`)
|
||||
- Manueller und automatischer Scan (Polling)
|
||||
- Pfad-Normalisierung mit Traversal-Schutz
|
||||
- WebSocket-Broadcast: `CONVERTER_SCAN_UPDATE`
|
||||
|
||||
---
|
||||
|
||||
## `downloadService.js`
|
||||
|
||||
Download-Queue für Ausgabedateien aus der Historie.
|
||||
|
||||
Features:
|
||||
|
||||
- Job in Download-Queue einreihen (`enqueueHistoryJob`)
|
||||
- ZIP-Archiv aus Ausgabedateien erstellen (`archiver`)
|
||||
- Datei-Streaming via `res.download()`
|
||||
- WebSocket-Broadcast: `DOWNLOADS_UPDATED` bei Status-Änderungen
|
||||
- Download-Item löschen
|
||||
|
||||
---
|
||||
|
||||
## `cronService.js`
|
||||
|
||||
Integriertes Cron-System ohne externe Parser-Library.
|
||||
|
||||
Features:
|
||||
|
||||
- 5-Feld-Cron-Parser + `nextRun`-Berechnung
|
||||
- Quellen: `script` oder `chain`
|
||||
- Laufzeitlogs (`cron_run_logs`)
|
||||
- manuelles Triggern
|
||||
- WebSocket-Events: `CRON_JOBS_UPDATED`, `CRON_JOB_UPDATED`
|
||||
|
||||
---
|
||||
|
||||
## `runtimeActivityService.js`
|
||||
|
||||
In-Memory-Tracking aller laufenden und kürzlich abgeschlossenen Aktivitäten (Skripte, Ketten, Cron-Jobs, Tasks).
|
||||
|
||||
Features:
|
||||
|
||||
- `startActivity(type, payload)` → Aktivität registrieren, ID zurückgeben
|
||||
- `updateActivity(id, patch)` → Laufende Aktivität aktualisieren
|
||||
- `completeActivity(id, payload)` → Aktivität abschließen und in `recent` verschieben
|
||||
- `setControls(id, { cancel, nextStep })` → Steuer-Handler registrieren (für `canCancel`/`canNextStep`)
|
||||
- `requestCancel(id)` / `requestNextStep(id)` → Steuer-Handler aufrufen
|
||||
- `clearRecent()` → Abgeschlossene Aktivitäten löschen
|
||||
- `getSnapshot()` → Snapshot mit `active` + `recent` + `updatedAt`
|
||||
- Broadcasts `RUNTIME_ACTIVITY_CHANGED` über WebSocket bei jeder Änderung
|
||||
|
||||
Limits:
|
||||
|
||||
- `recent` max. 120 Einträge
|
||||
- `stdout`/`stderr`/`output` max. 12.000 Zeichen
|
||||
- `message`/`errorMessage` max. 2.000 Zeichen
|
||||
|
||||
Vollständige API-Dokumentation: [Runtime Activities API](../api/runtime-activities.md)
|
||||
|
||||
---
|
||||
|
||||
## Weitere Services
|
||||
|
||||
- `scriptService.js` (CRUD + Test + Wrapper-Ausführung)
|
||||
- `scriptChainService.js` (CRUD + Step-Execution)
|
||||
- `userPresetService.js` (HandBrake User-Presets)
|
||||
- `hardwareMonitorService.js` (CPU/RAM/GPU/Storage)
|
||||
- `websocketService.js` (Client-Registry + Broadcast)
|
||||
- `notificationService.js` (PushOver)
|
||||
- `cdRipService.js` (CD-Ripping mit cdparanoia)
|
||||
- `musicBrainzService.js` (MusicBrainz-Metadaten-Lookup)
|
||||
- `audnexService.js` (Audnex-API für Audiobook-Metadaten)
|
||||
- `coverArtRecoveryService.js` (Cover-Art-Wiederherstellung)
|
||||
- `thumbnailService.js` (Vorschaubild-Generierung)
|
||||
- `omdbService.js` (OMDb-Metadaten-Suche)
|
||||
- `logger.js` (rotierende Datei-Logs)
|
||||
|
||||
---
|
||||
|
||||
## Bootstrapping (`src/index.js`)
|
||||
|
||||
Beim Start:
|
||||
|
||||
1. DB init/migrate
|
||||
2. Pipeline-Init (inkl. Plugin-Registry)
|
||||
3. Cron-Init
|
||||
4. Express-Routes + Error-Handler
|
||||
5. WebSocket-Server auf `/ws`
|
||||
6. Hardware-Monitoring-Init
|
||||
7. Disk-Detection-Start
|
||||
8. Converter-Scan-Service-Init (Polling falls aktiviert)
|
||||
@@ -0,0 +1,186 @@
|
||||
# Datenbank
|
||||
|
||||
Ripster verwendet SQLite (`backend/data/ripster.db`).
|
||||
|
||||
---
|
||||
|
||||
## Tabellen
|
||||
|
||||
```text
|
||||
settings_schema
|
||||
settings_values
|
||||
jobs
|
||||
job_lineage_artifacts
|
||||
job_output_folders
|
||||
pipeline_state
|
||||
scripts
|
||||
script_chains
|
||||
script_chain_steps
|
||||
user_presets
|
||||
cron_jobs
|
||||
cron_run_logs
|
||||
aax_activation_bytes
|
||||
user_prefs
|
||||
converter_scan_entries
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `jobs`
|
||||
|
||||
Speichert Pipeline-Lifecycle und Artefakte pro Job.
|
||||
|
||||
Zentrale Felder:
|
||||
|
||||
- Metadaten: `title`, `year`, `imdb_id`, `poster_url`, `omdb_json`, `selected_from_omdb`
|
||||
- Laufzeit: `start_time`, `end_time`, `status`, `last_state`
|
||||
- Pfade: `raw_path`, `output_path`, `encode_input_path`
|
||||
- Tool-Ausgaben: `makemkv_info_json`, `handbrake_info_json`, `mediainfo_info_json`, `encode_plan_json`
|
||||
- Kontrolle: `encode_review_confirmed`, `rip_successful`, `error_message`
|
||||
- Medientyp: `media_type` (`bluray|dvd|cd|audiobook|converter`)
|
||||
- Prüfsumme: `aax_checksum` (für AAX-Dateien)
|
||||
- Audit: `created_at`, `updated_at`
|
||||
|
||||
---
|
||||
|
||||
## `job_lineage_artifacts`
|
||||
|
||||
Verknüpft Jobs mit ihren Quell-Jobs (z. B. Re-Encode aus einem vorherigen Rip).
|
||||
|
||||
Felder:
|
||||
|
||||
- `job_id` — der abgeleitete Job
|
||||
- `source_job_id` — der Quell-Job
|
||||
- `artifact_type` — Art der Verknüpfung (z. B. `reencode`, `restart_review`)
|
||||
- `created_at`
|
||||
|
||||
---
|
||||
|
||||
## `job_output_folders`
|
||||
|
||||
Verfolgt Ausgabepfade pro Job (mehrere Ausgaben möglich, z. B. bei Kapitel-Splitting).
|
||||
|
||||
Felder:
|
||||
|
||||
- `job_id`
|
||||
- `folder_path`
|
||||
- `label` — optionaler Bezeichner
|
||||
- `created_at`
|
||||
|
||||
---
|
||||
|
||||
## `pipeline_state`
|
||||
|
||||
Singleton-Tabelle (`id = 1`) für aktiven Snapshot:
|
||||
|
||||
- `state`
|
||||
- `active_job_id`
|
||||
- `progress`
|
||||
- `eta`
|
||||
- `status_text`
|
||||
- `context_json`
|
||||
- `updated_at`
|
||||
|
||||
---
|
||||
|
||||
## `settings_schema` + `settings_values`
|
||||
|
||||
- `settings_schema`: Definition (Typ, Default, Validation, Reihenfolge)
|
||||
- `settings_values`: aktueller Wert pro Key
|
||||
|
||||
---
|
||||
|
||||
## `scripts`, `script_chains`, `script_chain_steps`
|
||||
|
||||
- `scripts`: Shell-Skripte (`name`, `script_body`, `order_index`)
|
||||
- `script_chains`: Ketten (`name`, `order_index`)
|
||||
- `script_chain_steps`: Schritte je Kette
|
||||
- `step_type`: `script` oder `wait`
|
||||
- `script_id` oder `wait_seconds`
|
||||
|
||||
---
|
||||
|
||||
## `user_presets`
|
||||
|
||||
Benannte HandBrake-Preset-Sets:
|
||||
|
||||
- `name`
|
||||
- `media_type` (`bluray|dvd|other|all`)
|
||||
- `handbrake_preset`
|
||||
- `extra_args`
|
||||
- `description`
|
||||
|
||||
---
|
||||
|
||||
## `cron_jobs` + `cron_run_logs`
|
||||
|
||||
- `cron_jobs`: Zeitplan + Status
|
||||
- `cron_run_logs`: einzelne Läufe
|
||||
- `status`: `running|success|error`
|
||||
- `output`
|
||||
- `error_message`
|
||||
|
||||
---
|
||||
|
||||
## `aax_activation_bytes`
|
||||
|
||||
Cache für Audible-Activation-Bytes (AAX-DRM).
|
||||
|
||||
Felder:
|
||||
|
||||
- `checksum` — SHA-1-Prüfsumme der AAX-Datei (Primärschlüssel)
|
||||
- `activation_bytes` — Hex-String der Activation Bytes
|
||||
- `created_at`
|
||||
|
||||
---
|
||||
|
||||
## `user_prefs`
|
||||
|
||||
Benutzer-spezifische Einstellungen (Key-Value).
|
||||
|
||||
Felder:
|
||||
|
||||
- `key`
|
||||
- `value`
|
||||
- `updated_at`
|
||||
|
||||
---
|
||||
|
||||
## `converter_scan_entries`
|
||||
|
||||
DB-seitige Erfassung gescannter Dateien im Converter-Eingangsordner.
|
||||
|
||||
Felder:
|
||||
|
||||
- `rel_path` — relativer Pfad zum `converter_raw_dir`
|
||||
- `is_dir` — Verzeichnis-Flag
|
||||
- `size` — Dateigröße in Bytes
|
||||
- `modified_at` — Datei-Änderungsdatum
|
||||
- `job_id` — zugewiesener Converter-Job (falls vorhanden)
|
||||
- `scanned_at`
|
||||
|
||||
---
|
||||
|
||||
## Migration/Recovery
|
||||
|
||||
Beim Start werden Schema und Settings-Metadaten automatisch abgeglichen.
|
||||
|
||||
Bei korruptem SQLite-File:
|
||||
|
||||
1. Datei wird nach `backend/data/corrupt-backups/` verschoben
|
||||
2. neue DB wird initialisiert
|
||||
3. Schema wird neu aufgebaut
|
||||
|
||||
---
|
||||
|
||||
## Direkte Inspektion
|
||||
|
||||
```bash
|
||||
sqlite3 backend/data/ripster.db
|
||||
|
||||
.mode table
|
||||
SELECT id, status, title, media_type, created_at FROM jobs ORDER BY created_at DESC;
|
||||
SELECT key, value FROM settings_values ORDER BY key;
|
||||
SELECT checksum, activation_bytes FROM aax_activation_bytes;
|
||||
SELECT rel_path, job_id FROM converter_scan_entries;
|
||||
```
|
||||
@@ -0,0 +1,117 @@
|
||||
# Frontend-Komponenten
|
||||
|
||||
Frontend: React + PrimeReact + Vite.
|
||||
|
||||
---
|
||||
|
||||
## Hauptseiten
|
||||
|
||||
### `RipperPage.jsx`
|
||||
|
||||
Pipeline-Steuerung:
|
||||
|
||||
- Status/Progress/ETA
|
||||
- Metadaten-Dialog
|
||||
- Playlist-Entscheidung
|
||||
- Review-Panel (Track-Auswahl)
|
||||
- Queue-Interaktion (reorder/add/remove)
|
||||
- Job-Aktionen (Start/Cancel/Retry/Re-Encode)
|
||||
- Hardware-Monitoring-Anzeige
|
||||
- Aktivitäts-Tracking (Skripte, Ketten, Cron)
|
||||
|
||||
### `SettingsPage.jsx`
|
||||
|
||||
Konfiguration:
|
||||
|
||||
- dynamisches Settings-Formular (`DynamicSettingsForm`)
|
||||
- Skripte/Ketten inkl. Reorder/Test
|
||||
- User-Presets
|
||||
- Cron-Jobs (`CronJobsTab`)
|
||||
|
||||
### `HistoryPage.jsx`
|
||||
|
||||
Historie:
|
||||
|
||||
- Job-Liste/Filter
|
||||
- Job-Details + Logs
|
||||
- OMDb-Nachzuweisung
|
||||
- Re-Encode/Restart-Workflows
|
||||
|
||||
### `ConverterPage.jsx`
|
||||
|
||||
Datei-Converter:
|
||||
|
||||
- Datei-Explorer des Converter-Eingangsordners (Baum-Ansicht)
|
||||
- Upload von Audio/Video-Dateien (bis zu 50 Dateien gleichzeitig)
|
||||
- Dateiverwaltung: Umbenennen, Verschieben, Löschen, Ordner erstellen
|
||||
- Jobs aus Dateiauswahl erstellen
|
||||
- Converter-Job-Konfiguration (Ausgabeformat, Preset, Tracks)
|
||||
- Job-Start, Abbruch, Löschung
|
||||
- Automatischer Scan-Status
|
||||
|
||||
### `DownloadsPage.jsx`
|
||||
|
||||
Download-Queue:
|
||||
|
||||
- Ausgabedateien aus der Job-Historie in die Queue einreihen
|
||||
- Download-Status verfolgen (ausstehend, wird verarbeitet, bereit, fehlgeschlagen)
|
||||
- Dateien als ZIP herunterladen
|
||||
- Download-Einträge löschen
|
||||
|
||||
### `DatabasePage.jsx`
|
||||
|
||||
Expert-Modus:
|
||||
|
||||
- Tabellarische Rohsicht der Job-Datenbank
|
||||
- Orphan-RAW-Import
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Komponenten
|
||||
|
||||
- `PipelineStatusCard.jsx` — Pipeline-Status-Anzeige mit Progress
|
||||
- `MetadataSelectionDialog.jsx` — OMDb-Metadaten-Auswahl
|
||||
- `MediaInfoReviewPanel.jsx` — Track-Auswahl-Interface (Video/Audio/Untertitel)
|
||||
- `JobDetailDialog.jsx` — Job-Detailansicht mit Logs
|
||||
- `CronJobsTab.jsx` — Cron-Job-Verwaltung
|
||||
- `DynamicSettingsForm.jsx` — Schema-gesteuertes Einstellungsformular
|
||||
- `ConverterJobCard.jsx` — Converter-Job-Darstellung
|
||||
- `CdRipConfigPanel.jsx` — Konfiguration für Audio-CD-Ripping
|
||||
|
||||
---
|
||||
|
||||
## API-Client (`api/client.js`)
|
||||
|
||||
- zentraler `request()` mit JSON-Handling
|
||||
- Fehlerobjekt aus API wird auf `Error(message)` gemappt
|
||||
- `VITE_API_BASE` default `/api`
|
||||
|
||||
---
|
||||
|
||||
## WebSocket (`hooks/useWebSocket.js`)
|
||||
|
||||
- URL: `VITE_WS_URL` oder automatisch `ws(s)://<host>/ws`
|
||||
- Auto-Reconnect mit 1500ms Intervall
|
||||
|
||||
In `App.jsx` werden u. a. verarbeitet:
|
||||
|
||||
- `PIPELINE_STATE_CHANGED`
|
||||
- `PIPELINE_PROGRESS`
|
||||
- `PIPELINE_QUEUE_CHANGED`
|
||||
- Disk erkannt / Disk entfernt
|
||||
- `HARDWARE_MONITOR_UPDATE`
|
||||
- `DOWNLOADS_UPDATED`
|
||||
- `CONVERTER_SCAN_UPDATE`
|
||||
- `RUNTIME_ACTIVITY_CHANGED`
|
||||
|
||||
---
|
||||
|
||||
## Build/Run
|
||||
|
||||
```bash
|
||||
# dev
|
||||
npm run dev --prefix frontend
|
||||
|
||||
# prod build
|
||||
npm run build --prefix frontend
|
||||
```
|
||||
@@ -0,0 +1,52 @@
|
||||
# Anhang: Architektur
|
||||
|
||||
Ripster ist eine Client-Server-Anwendung mit REST + WebSocket und externen CLI-Tools.
|
||||
|
||||
---
|
||||
|
||||
## Systemüberblick
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph Browser["Browser (React)"]
|
||||
Ripper[Ripper]
|
||||
Settings[Einstellungen]
|
||||
History[Historie]
|
||||
end
|
||||
|
||||
subgraph Backend["Node.js Backend"]
|
||||
API[REST API\nExpress]
|
||||
WS[WebSocket\n/ws]
|
||||
Pipeline[pipelineService]
|
||||
Cron[cronService]
|
||||
DB[(SQLite)]
|
||||
end
|
||||
|
||||
subgraph Tools["Externe Tools"]
|
||||
MakeMKV[makemkvcon]
|
||||
HandBrake[HandBrakeCLI]
|
||||
MediaInfo[mediainfo]
|
||||
end
|
||||
|
||||
Browser <-->|HTTP| API
|
||||
Browser <-->|WebSocket| WS
|
||||
Pipeline --> MakeMKV
|
||||
Pipeline --> HandBrake
|
||||
Pipeline --> MediaInfo
|
||||
API --> DB
|
||||
Pipeline --> DB
|
||||
Cron --> DB
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Details
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [:octicons-arrow-right-24: Übersicht](overview.md)
|
||||
- [:octicons-arrow-right-24: Backend-Services](backend.md)
|
||||
- [:octicons-arrow-right-24: Frontend-Komponenten](frontend.md)
|
||||
- [:octicons-arrow-right-24: Datenbank](database.md)
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,94 @@
|
||||
# Architektur-Übersicht
|
||||
|
||||
---
|
||||
|
||||
## Kernprinzipien
|
||||
|
||||
### Event-getriebene Pipeline
|
||||
|
||||
`pipelineService` hält einen Snapshot der State-Machine und broadcastet Änderungen sofort via WebSocket.
|
||||
|
||||
```text
|
||||
State-Änderung -> PIPELINE_STATE_CHANGED/PIPELINE_PROGRESS -> Frontend-Update
|
||||
```
|
||||
|
||||
### Service-Layer
|
||||
|
||||
```text
|
||||
Route -> Service -> DB/Tool-Execution
|
||||
```
|
||||
|
||||
Routes enthalten kaum Business-Logik.
|
||||
|
||||
### Schema-getriebene Settings
|
||||
|
||||
Settings sind DB-schema-getrieben (`settings_schema` + `settings_values`), UI rendert dynamisch aus diesen Daten.
|
||||
|
||||
---
|
||||
|
||||
## Echtzeit-Kommunikation
|
||||
|
||||
WebSocket läuft auf `/ws`.
|
||||
|
||||
Wichtige Events:
|
||||
|
||||
- `PIPELINE_STATE_CHANGED`, `PIPELINE_PROGRESS`, `PIPELINE_QUEUE_CHANGED`
|
||||
- Disk erkannt, Disk entfernt
|
||||
- `HARDWARE_MONITOR_UPDATE`
|
||||
- `SETTINGS_UPDATED`, `SETTINGS_BULK_UPDATED`
|
||||
- `SETTINGS_SCRIPTS_UPDATED`, `SETTINGS_SCRIPT_CHAINS_UPDATED`, `USER_PRESETS_UPDATED`
|
||||
- `CRON_JOBS_UPDATED`, `CRON_JOB_UPDATED`
|
||||
- `PIPELINE_ERROR`, `DISK_DETECTION_ERROR`
|
||||
|
||||
---
|
||||
|
||||
## Prozessausführung
|
||||
|
||||
Externe Tools werden als Child-Processes gestartet (`processRunner`):
|
||||
|
||||
- Streaming von stdout/stderr
|
||||
- Progress-Parsing (`progressParsers.js`)
|
||||
- kontrollierter Abbruch (SIGINT/SIGKILL-Fallback)
|
||||
|
||||
---
|
||||
|
||||
## Persistenz
|
||||
|
||||
SQLite-Datei: `backend/data/ripster.db`
|
||||
|
||||
Kern-Tabellen:
|
||||
|
||||
- `jobs`, `pipeline_state`
|
||||
- `settings_schema`, `settings_values`
|
||||
- `scripts`, `script_chains`, `script_chain_steps`
|
||||
- `user_presets`
|
||||
- `cron_jobs`, `cron_run_logs`
|
||||
|
||||
Beim Start werden Schema und Settings-Migrationen automatisch ausgeführt.
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
Zentrales Error-Handling liefert:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"message": "...",
|
||||
"statusCode": 400,
|
||||
"reqId": "...",
|
||||
"details": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Fehlgeschlagene Jobs bleiben in der Historie (`Fehler` oder `Abgebrochen`) und können erneut gestartet werden.
|
||||
|
||||
---
|
||||
|
||||
## CORS & Runtime-Konfig
|
||||
|
||||
- `CORS_ORIGIN` default: `*`
|
||||
- `LOG_LEVEL` default: `info`
|
||||
- DB-/Log-Pfade über `DB_PATH`/`LOG_DIR` konfigurierbar
|
||||
Reference in New Issue
Block a user