MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 8s
105 lines
6.6 KiB
Markdown
105 lines
6.6 KiB
Markdown
# 📝 Kernmodul 3: Workspace Outliner-Engine, Wiki-Links & Pure-DB Storage
|
|
|
|
Der MindSift Workspace ([`WorkspaceView.tsx`](../../frontend/src/features/workspace/WorkspaceView.tsx)) kombiniert ein **hierarchisches Bullet-Point Notizsystem (inspiriert von Logseq)** mit einem **persönlichen Wiki**, **Live-Kollaboration** und einem **globalen To-Do Rollup Dashboard**.
|
|
|
|
---
|
|
|
|
## 🌳 1. Die Logseq-Outliner-Engine
|
|
|
|
Im Gegensatz zu klassischen Fließtext-Editoren basiert der MindSift Workspace auf einer **flachen, relationalen Liste von Blöcken** (`blocks`-Tabelle in SQLite). Jeder Block ist ein gedanklicher Knotenpunkt mit einer flexiblen Einrückungsebene (`level: 0, 1, 2, ...`) und einer fortlaufenden Fließkommaposition (`position`):
|
|
|
|
```
|
|
• Projekt MindSift v2.0 (level 0)
|
|
• Architektur-Entscheidung (level 1)
|
|
- [x] Database-First Blocks implementieren (level 2)
|
|
- [ ] Performance Benchmark mit 10.000 Blöcken (level 2)
|
|
• Notizen aus dem Dev-Meeting (level 1)
|
|
> Wichtig: Keine verschachtelten SQLite Queries ausführen! (level 2)
|
|
```
|
|
|
|
### Tastatur-Navigation & Shortcuts
|
|
- `Enter`: Erstellt einen neuen Block auf derselben Hierarchieebene.
|
|
- `Tab`: Rückt den aktuellen Block ein (wird Kindknoten des vorherigen Blocks).
|
|
- `Shift + Tab`: Rückt den Block um eine Ebene aus (verringert die Tiefe).
|
|
- `Shift + Enter`: Weicher Zeilenumbruch innerhalb desselben Blocks (z.B. für mehrzeilige Notizen oder Code).
|
|
- `Backspace` (auf leerem Block): Löscht den Block sofort. Das Ausrücken erfolgt strikt und kontrolliert über `Shift + Tab`.
|
|
- `/` (Slash-Commands): Öffnet das Umwandlungsmenü (`/todo`, `/link`, `/h1`, `/h2`, `/h3`, `/code`, `/callout`, `/quote`, `/divider`).
|
|
- **Markdown-Tastatur-Kürzel:** Tippen von `[] ` oder `[ ] ` wandelt den Block sofort in ein Todo um; `# `, `## `, `### ` erzeugt Überschriften.
|
|
|
|
### Eingabestabilität & Zombie-Fokus-Schutz (`OutlinerBlock.tsx`)
|
|
1. **Echter Fokus-Check:** Remote-Updates (`block_updated`) werden nur dann abgewehrt, wenn der Block tatsächlich aktiv im Betriebssystem editiert wird:
|
|
`isFocusedRef.current === true && document.hasFocus()`.
|
|
2. **Sofort-Flush bei Fensterwechsel:** Sobald das Browser-Fenster den Fokus verliert (`window.addEventListener('blur', ...)`), wird ein offener 150ms-Debounce sofort gecancelt und der Text augenblicklich per WebSocket übertragen.
|
|
3. **Stale Closures eliminiert:** Alle Callbacks werden in `useRef` gehalten, sodass asynchrone Debounce-Timer garantiert die aktuellste Komponenten-Referenz verwenden.
|
|
|
|
### Zoom-In Hoisting (Fokus-Modus)
|
|
Klickt der Benutzer auf den Bullet-Dot (`•`) eines Blocks, blendet der Editor alle übergeordneten und benachbarten Blöcke aus und zoomt **ausschließlich in diesen Ast** hinein:
|
|
- Der gewählte Punkt wird zur prominenten Überschrift im Fokus-Modus.
|
|
- Eine klickbare Breadcrumb-Leiste oben zeigt den Pfad an (z.B. `Workspace / Projekte / MindSift / Architektur`).
|
|
- Ein Klick auf ein beliebiges Breadcrumb-Element zoomt sofort auf die jeweilige Ebene zurück.
|
|
|
|
### Drag & Drop von Blöcken
|
|
Der Bullet-Dot dient gleichzeitig als Drag-Anfasser. Wird ein Block verschoben, erkennt die Engine automatisch alle untergeordneten Kind-Blöcke (`isDescendantBlock`) und verschiebt den **kompletten Unterbaum** an die neue Zielposition.
|
|
|
|
---
|
|
|
|
## 🔗 2. Wiki-Links (`[[Link]]`), Web-Links (`/link`) & Hashtags
|
|
|
|
1. **Interne Wiki-Links:**
|
|
- Text in doppelten eckigen Klammern (z.B. `[[Reiseplanung 2026]]`) wird automatisch als klickbare Notiz-Pille gerendert.
|
|
- Klick darauf öffnet die verknüpfte Notiz direkt im Editor.
|
|
2. **Slash-Befehl `/link` & Link-Modal:**
|
|
- `/link` öffnet ein Modal mit zwei Modi:
|
|
- **Notiz verknüpfen:** Durchsucht bestehende Notizen und fügt `[[Titel]]` ein.
|
|
- **Web-Link:** Eingabe von Titel und URL, fügt Standard-Markdown `[Titel](url)` ein.
|
|
3. **Hashtags (`#tag`):**
|
|
- Hashtags im Fließtext werden automatisch indiziert (`block_tags`-Tabelle).
|
|
- In der linken Leiste listet der Tag-Explorer alle verwendeten Schlagworte auf. Klick auf ein Tag filtert alle Dokumente und Blöcke, die dieses Tag enthalten.
|
|
|
|
---
|
|
|
|
## ⚡ 3. Echtzeit-Kollaboration & Automatische Markdown-Kompilierung
|
|
|
|
MindSift setzt auf eine latenzfreie In-Memory Kollaborations-Architektur ([`internal/ws/docroom.go`](../../internal/ws/docroom.go)):
|
|
|
|
### Funktionsweise
|
|
1. **In-Memory DocRoom pro geöffnetem Dokument:**
|
|
- Hält den synchronen Zustand von `title` und `blocks[]` im RAM.
|
|
- Granulare Mutations-Events (`block_updated`, `block_created`, `block_deleted`, `block_moved`, `title_updated`).
|
|
- Ephemeres Presence-Tracking (`cursor_moved`, `client_left`) zeigt farbige Benutzer-Avatare im Header und Cursors am aktiven Block an.
|
|
2. **Echo-Schutz:**
|
|
- Jeder Client identifiziert sich mit einer eindeutigen `clientId`.
|
|
- Der Server sendet Mutations-Events ausschließlich an andere Clients im selben Raum (`clientId != senderClientId`), um Cursor-Springen und Selbstechos zu verhindern.
|
|
|
|
### Automatische Markdown-Kompilierung & SQLite Debounce-Flush
|
|
```
|
|
Eingabe im OutlinerBlock
|
|
│
|
|
├──▶ WebSocket (block_updated Event)
|
|
│ │
|
|
│ ▼
|
|
│ Go DocRoom: In-Memory Mutation & Broadcast an Peers
|
|
│
|
|
└──▶ 1.5s Inaktivitäts-Debounce (oder Raum-Exit)
|
|
│
|
|
▼
|
|
SQLite Transaktion:
|
|
1. Persistiert Blöcke in `blocks`
|
|
2. Regex-Extraktion von #tags in `block_tags`
|
|
3. Kompiliert Block-Hierarchie zu Standard-Markdown
|
|
und speichert Cache in `documents.markdown_cache`
|
|
```
|
|
|
|
1. **Kompiliertes Markdown:** Jeder Block wird gemäß seiner `level`-Tiefe mit 2 Leerzeichen pro Einrückungsebene als sauberes Markdown formatiert (`documents.markdown_cache`).
|
|
2. **Pure Database Architecture:** Alle Daten liegen transaktional und sicher in SQLite. Es werden keine unkontrollierten Dateien auf der Festplatte abgelegt; Notizen können jederzeit per Klick als `.md`-Datei exportiert werden.
|
|
|
|
---
|
|
|
|
## 📊 4. Globaler To-Do Rollup Dashboard
|
|
|
|
Über den Tab **„Globale To-Dos"** bietet der Workspace eine aggregierte Übersicht aller im gesamten Wiki verteilten Aufgaben:
|
|
- Scannt in Echtzeit alle unvollendeten `- [ ] ` Checkboxen über alle Ordner und Notizen hinweg.
|
|
- Übersichtliche Gruppierung nach **Ordner ➔ Dokument ➔ Aufgabe**.
|
|
- **Ordner-Filter:** Klick auf einen Ordner isoliert nur dessen Aufgaben für fokussiertes Arbeiten.
|
|
- **2-Wege-Live-Sync:** Wird eine Checkbox im Rollup abgehakt, wird der Block in SQLite sofort auf `checked = 1` aktualisiert und via WebSocket an alle aktiven Clients gebroadcastet.
|