diff --git a/docs/architecture/backend.md b/docs/architecture/backend.md index 146d4df..1c28ecd 100644 --- a/docs/architecture/backend.md +++ b/docs/architecture/backend.md @@ -29,23 +29,33 @@ Das Backend ist in Node.js/Express geschrieben und in **Services** aufgeteilt, d ### Zustandsübergänge +
+ ```mermaid -stateDiagram-v2 - [*] --> IDLE - IDLE --> ANALYZING: analyzeDisc() - ANALYZING --> METADATA_SELECTION: MakeMKV fertig - METADATA_SELECTION --> READY_TO_START: selectMetadata() - READY_TO_START --> RIPPING: startJob() - RIPPING --> MEDIAINFO_CHECK: MKV erstellt - MEDIAINFO_CHECK --> READY_TO_ENCODE: Tracks analysiert - READY_TO_ENCODE --> ENCODING: confirmEncode() - ENCODING --> FINISHED: HandBrake fertig - ENCODING --> ERROR: Fehler - RIPPING --> ERROR: Fehler - ERROR --> IDLE: retryJob() / cancel - FINISHED --> IDLE: cancel / neue Disc +flowchart LR + START(( )) --> IDLE + IDLE -->|analyzeDisc()| ANALYZING[ANALYZING] + ANALYZING -->|MakeMKV fertig| META[METADATA\nSELECTION] + META -->|selectMetadata()| RTS[READY_TO\nSTART] + RTS -->|startJob()| RIP[RIPPING] + RIP -->|MKV erstellt| MIC[MEDIAINFO\nCHECK] + MIC -->|Tracks analysiert| RTE[READY_TO\nENCODE] + RTE -->|confirmEncode()| ENC[ENCODING] + ENC -->|HandBrake fertig| FIN([FINISHED]) + ENC -->|Fehler| ERR([ERROR]) + RIP -->|Fehler| ERR + ERR -->|retryJob() / cancel| IDLE + FIN -->|cancel / neue Disc| IDLE + + style FIN fill:#e8f5e9,stroke:#66bb6a,color:#2e7d32 + style ERR fill:#ffebee,stroke:#ef5350,color:#c62828 + style ENC fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + style RIP fill:#e3f2fd,stroke:#42a5f5,color:#1565c0 + style MIC fill:#e3f2fd,stroke:#42a5f5,color:#1565c0 ``` +
+ --- ## diskDetectionService.js diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index 4531c6d..ccaaca9 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -6,24 +6,106 @@ Nach der [Installation](installation.md) und [Konfiguration](configuration.md) f ## Übersicht: Pipeline-Zustände -```mermaid -stateDiagram-v2 - direction LR - [*] --> IDLE - IDLE --> DISC_DETECTED: Disc eingelegt - DISC_DETECTED --> METADATA_SELECTION: Analyse gestartet - METADATA_SELECTION --> READY_TO_START: Metadaten bestätigt\n(keine Obfuskierung) - METADATA_SELECTION --> WAITING_FOR_USER_DECISION: Obfuskierung erkannt\n→ Playlist wählen - WAITING_FOR_USER_DECISION --> READY_TO_START: Playlist bestätigt - READY_TO_START --> MEDIAINFO_CHECK: Vorhandene Raw-Datei\ngefunden - READY_TO_START --> RIPPING: Ripping starten - RIPPING --> MEDIAINFO_CHECK: MakeMKV fertig - MEDIAINFO_CHECK --> READY_TO_ENCODE: Track-Review bereit - READY_TO_ENCODE --> ENCODING: Encode bestätigt - ENCODING --> FINISHED: Erfolg - ENCODING --> ERROR: Fehler - RIPPING --> ERROR: Fehler -``` +
+
+
+
IDLE
+
Warten
+
+
+
1
+
DISC_DETECTED
+
Disc erkannt
+
+
+
2
+
METADATA_SELECTION
+
Scan & Metadaten
+
+
+
+
WAITING_FOR_USER_DECISION
+
Playlist wählen
(nur bei Obfusk.)
+
+
+
3
+
READY_TO_START
+
Bereit
+
+
+
4
+
RIPPING
+
MakeMKV
+
+
+
5
+
MEDIAINFO_CHECK
+
HandBrake-Scan
+
+
+
6
+
READY_TO_ENCODE
+
Track-Review
+
+
+
7
+
ENCODING
+
HandBrake
+
+
+
8
+
POST_ENCODE_SCRIPTS
+
Skripte
(optional)
+
+
+
+
FINISHED
+
Fertig
+
+
+ +**Legende:** ● Warten  |  ■ Läuft automatisch  |  ■ Benutzeraktion  |  ⚠ Optional  |  ■ Encodierung  |  ✓ Fertig + +??? note "Vollständiges Zustandsdiagramm (inkl. Fehler- & Alternativpfade)" + +
+ + ```mermaid + flowchart LR + START(( )) --> IDLE + + IDLE -->|Disc erkannt| DD[DISC_DETECTED] + DD -->|Analyse starten| META[METADATA\nSELECTION] + + META -->|1 Kandidat| RTS[READY_TO\nSTART] + META -->|mehrere Kandidaten| WUD[WAITING_FOR\nUSER_DECISION] + WUD -->|Playlist bestätigt| RTS + + RTS -->|Raw vorhanden| MIC[MEDIAINFO\nCHECK] + RTS -->|Ripping starten| RIP[RIPPING] + RIP -->|MKV fertig| MIC + RIP -->|Fehler| ERR + + MIC --> RTE[READY_TO\nENCODE] + RTE -->|bestätigt| ENC[ENCODING] + + ENC -->|mit Skripten| PES[POST_ENCODE\nSCRIPTS] + ENC -->|ohne Skripte| FIN([FINISHED]) + ENC -->|Fehler| ERR + + PES -->|Erfolg| FIN + PES -->|Fehler| ERR + + ERR([ERROR]) -->|Retry / Cancel| IDLE + + style FIN fill:#e8f5e9,stroke:#66bb6a,color:#2e7d32 + style ERR fill:#ffebee,stroke:#ef5350,color:#c62828 + style WUD fill:#fff8e1,stroke:#ffa726,color:#e65100 + style PES fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + style ENC fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + ``` + +
--- diff --git a/docs/index.md b/docs/index.md index 3947fa9..7a5b7fd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -112,19 +112,31 @@ open http://localhost:5173 ## Pipeline-Überblick +
+ ```mermaid -stateDiagram-v2 - [*] --> IDLE - IDLE --> ANALYZING: Disc erkannt - ANALYZING --> METADATA_SELECTION: Analyse abgeschlossen - METADATA_SELECTION --> READY_TO_START: Metadaten bestätigt - READY_TO_START --> RIPPING: Start gedrückt - RIPPING --> MEDIAINFO_CHECK: MKV erstellt - MEDIAINFO_CHECK --> READY_TO_ENCODE: Tracks analysiert - READY_TO_ENCODE --> ENCODING: Encode bestätigt - ENCODING --> FINISHED: Encoding fertig - ENCODING --> ERROR: Fehler - RIPPING --> ERROR: Fehler - ERROR --> [*] - FINISHED --> [*] +flowchart LR + IDLE --> DD[DISC_DETECTED] + DD --> META[METADATA\nSELECTION] + META -->|1 Kandidat| RTS[READY_TO\nSTART] + META -->|Obfuskierung| WUD[WAITING_FOR\nUSER_DECISION] + WUD --> RTS + RTS --> RIP[RIPPING] + RTS -->|Raw vorhanden| MIC + RIP --> MIC[MEDIAINFO\nCHECK] + MIC --> RTE[READY_TO\nENCODE] + RTE --> ENC[ENCODING] + ENC --> PES[POST_ENCODE\nSCRIPTS] + ENC -->|keine Skripte| FIN([FINISHED]) + PES --> FIN + ENC --> ERR([ERROR]) + RIP --> ERR + + style FIN fill:#e8f5e9,stroke:#66bb6a,color:#2e7d32 + style ERR fill:#ffebee,stroke:#ef5350,color:#c62828 + style WUD fill:#fff8e1,stroke:#ffa726,color:#e65100 + style PES fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + style ENC fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a ``` + +
diff --git a/docs/pipeline/workflow.md b/docs/pipeline/workflow.md index 69de26a..abcacd1 100644 --- a/docs/pipeline/workflow.md +++ b/docs/pipeline/workflow.md @@ -6,40 +6,48 @@ Der Ripping-Workflow von Ripster ist als **State Machine** implementiert. Jeder ## Zustandsdiagramm +
+ ```mermaid -stateDiagram-v2 - direction TB - [*] --> IDLE +flowchart LR + START(( )) --> IDLE - IDLE --> DISC_DETECTED: Disc erkannt - DISC_DETECTED --> METADATA_SELECTION: Analyse starten + IDLE -->|Disc erkannt| DD[DISC_DETECTED] + DD -->|Analyse starten| META[METADATA\nSELECTION] - METADATA_SELECTION --> READY_TO_START: Kein Obfuskierungsverdacht\n(ein Kandidat) - METADATA_SELECTION --> WAITING_FOR_USER_DECISION: Mehrere Playlist-Kandidaten\n→ manuelle Auswahl nötig + META -->|1 Kandidat| RTS[READY_TO\nSTART] + META -->|mehrere Kandidaten| WUD[WAITING_FOR\nUSER_DECISION] + WUD -->|Playlist bestätigt| RTS - WAITING_FOR_USER_DECISION --> READY_TO_START: Playlist bestätigt + RTS -->|Raw vorhanden| MIC[MEDIAINFO\nCHECK] + RTS -->|Ripping starten| RIP[RIPPING] + RIP -->|MKV fertig| MIC + RIP -->|Fehler| ERR - READY_TO_START --> RIPPING: Starten\n(kein Raw vorhanden) - READY_TO_START --> MEDIAINFO_CHECK: Starten\n(Raw bereits vorhanden) + MIC --> RTE[READY_TO\nENCODE] + RTE -->|Tracks + Skripte\nbestätigt| ENC[ENCODING] - RIPPING --> MEDIAINFO_CHECK: MKV/Backup erstellt + ENC -->|mit Skripten| PES[POST_ENCODE\nSCRIPTS] + ENC -->|ohne Skripte| FIN([FINISHED]) + ENC -->|Fehler| ERR - MEDIAINFO_CHECK --> READY_TO_ENCODE: Track-Scan\nabgeschlossen + PES -->|Erfolg| FIN + PES -->|Fehler| ERR - READY_TO_ENCODE --> ENCODING: Tracks + Skripte\nbestätigt + ERR([ERROR]) -->|Retry / Cancel| IDLE + FIN -->|Neue Disc| IDLE - ENCODING --> POST_ENCODE_SCRIPTS: Erfolg\n(Skripte konfiguriert) - ENCODING --> FINISHED: Erfolg\n(keine Skripte) - POST_ENCODE_SCRIPTS --> FINISHED: Alle Skripte\nerfolgt - - RIPPING --> ERROR: Fehler - ENCODING --> ERROR: Fehler - POST_ENCODE_SCRIPTS --> ERROR: Skript-Fehler - - ERROR --> IDLE: Abbrechen / Retry - FINISHED --> IDLE: Neue Disc + style FIN fill:#e8f5e9,stroke:#66bb6a,color:#2e7d32 + style ERR fill:#ffebee,stroke:#ef5350,color:#c62828 + style WUD fill:#fff8e1,stroke:#ffa726,color:#e65100 + style PES fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + style ENC fill:#f3e5f5,stroke:#ab47bc,color:#6a1b9a + style RIP fill:#e3f2fd,stroke:#42a5f5,color:#1565c0 + style MIC fill:#e3f2fd,stroke:#42a5f5,color:#1565c0 ``` +
+ --- ## Zustandsbeschreibungen diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index cdfd134..9c24353 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -37,13 +37,99 @@ font-size: 0.85em; } -/* Mermaid diagrams */ +/* Mermaid diagrams – standard */ .md-typeset .mermaid { display: flex; justify-content: center; margin: 1.5rem 0; } +/* Large pipeline flowchart: horizontal scroll + min-height */ +.pipeline-diagram { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + margin: 1.5rem 0; + padding-bottom: 0.5rem; +} + +.pipeline-diagram .mermaid { + min-width: 900px; + justify-content: flex-start; +} + +.pipeline-diagram .mermaid svg { + min-width: 900px; + height: auto; +} + +/* Pipeline step track */ +.pipeline-steps { + display: flex; + flex-wrap: nowrap; + gap: 0; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 1rem 0 1.5rem 0; + margin: 1.5rem 0; + scrollbar-width: thin; +} + +.pipeline-step { + display: flex; + flex-direction: column; + align-items: center; + min-width: 110px; + flex: 0 0 auto; + position: relative; +} + +.pipeline-step:not(:last-child)::after { + content: '→'; + position: absolute; + right: -14px; + top: 22px; + font-size: 1.2rem; + color: var(--md-default-fg-color--light); + z-index: 1; +} + +.pipeline-step-badge { + width: 44px; + height: 44px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.75rem; + font-weight: 700; + margin-bottom: 0.5rem; + border: 2px solid transparent; +} + +.pipeline-step-label { + font-size: 0.7rem; + text-align: center; + line-height: 1.2; + max-width: 90px; + color: var(--md-default-fg-color); +} + +.pipeline-step-sub { + font-size: 0.6rem; + color: var(--md-default-fg-color--light); + text-align: center; + margin-top: 0.2rem; +} + +/* Step colors */ +.step-idle { background: #eceff1; color: #546e7a; border-color: #90a4ae; } +.step-user { background: #e8eaf6; color: #3949ab; border-color: #7986cb; } +.step-running { background: #e3f2fd; color: #1565c0; border-color: #42a5f5; } +.step-wait { background: #fff8e1; color: #e65100; border-color: #ffa726; } +.step-encode { background: #f3e5f5; color: #6a1b9a; border-color: #ab47bc; } +.step-done { background: #e8f5e9; color: #2e7d32; border-color: #66bb6a; } +.step-error { background: #ffebee; color: #c62828; border-color: #ef5350; } + /* Table improvements */ .md-typeset table:not([class]) { width: 100%;