docs: add comprehensive technical wiki documentation and flaws analysis; remove legacy BRAIN.md
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 8s

This commit is contained in:
sandrodach committed 2026-10-26 13:27:35 +01:00
1 parent 10d5c6d563
commit 3480859d8a
13 files changed
+1577 -317

No files matched your search

+185
View File
@@ -0,0 +1,185 @@
# 🔌 REST-API Referenz
Die MindSift REST-API ermöglicht den vollständigen Zugriff auf Gedanken, Aufgaben, Workspace-Notizen, Listen, Benutzerkonten und Smarthome-Automationen.
---
## 🔐 1. Authentifizierung
MindSift unterstützt zwei Authentifizierungsmethoden:
1. **JSON Web Token (JWT Bearer):**
Wird beim Login oder Setup erzeugt und im HTTP-Header mitgesendet:
`Authorization: Bearer <jwt-token>`
2. **Persönliche API-Schlüssel (Smarthome / Automatisierung):**
Werden unter *Einstellungen ➔ Private Webhooks* erzeugt (Präfix `mindsift_sec_...`):
- Per HTTP-Header: `X-API-Key: mindsift_sec_xxxxxxxxxxxx`
- Per Authorization-Header: `Authorization: Bearer mindsift_sec_xxxxxxxxxxxx`
- Per Query-Parameter: `?token=mindsift_sec_xxxxxxxxxxxx`
---
## 🚦 2. Status- & Fehler-Codes
- `200 OK`: Erfolgreiche Abfrage oder Aktualisierung.
- `201 Created`: Ressource erfolgreich angelegt.
- `400 Bad Request`: Ungültiges JSON oder fehlende Pflichtfelder.
- `401 Unauthorized`: Token ungültig, abgelaufen oder fehlend.
- `403 Forbidden`: Unzureichende Berechtigungen (z.B. nur Server-Admin oder nur Lesezugriff).
- `404 Not Found`: Ressource existiert nicht oder gehört einem anderen Benutzer.
- `409 Conflict`: Ressource gesperrt (z.B. Dokument wird bereits von anderem Benutzer bearbeitet).
Fehlerrückgaben erfolgen im einheitlichen Format:
```json
{
"error": "Fehlermeldung im Klartext"
}
```
---
## 📋 3. Endpunkte nach Modulen
### 3.1 Authentifizierung & System-Status
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/health` | Öffentlich | Liveness-Check (`{"status":"ok"}`) |
| `GET` | `/api/v1/auth/status` | Öffentlich | Prüft ob Ersteinrichtung nötig ist (`needsSetup: true/false`) |
| `POST` | `/api/v1/auth/setup` | Öffentlich | Führt First-Boot Setup durch (legt ersten Admin an) |
| `POST` | `/api/v1/auth/register` | Öffentlich | Registrierung über Einladungscode (`inviteCode`) |
| `POST` | `/api/v1/auth/login` | Öffentlich | Login via E-Mail oder Benutzername + Passwort |
| `GET` | `/api/v1/auth/me` | JWT | Gibt das aktuelle Benutzerprofil zurück |
| `PATCH` | `/api/v1/auth/settings` | JWT | Aktualisiert Profil, Passwort, Theme oder Alarm-Kanäle |
| `POST` | `/api/v1/auth/alarms/test` | JWT | Sendet Test-Alarm an E-Mail, Discord oder Custom Webhook |
#### Beispiel: `POST /api/v1/auth/login`
```json
// Request
{
"login": "sandro",
"password": "geheimesPasswort123"
}
// Response (200 OK)
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "usr_abc123",
"email": "sandro@example.com",
"username": "sandro",
"displayName": "Sandro",
"role": "admin",
"alarmChannels": ["discord", "webhook"]
}
}
```
---
### 3.2 Triage & Instant Capture
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `POST` | `/api/v1/inbox` | JWT / API-Key | Erfasst einen neuen Quick Dump oder leitet direkt weiter |
| `GET` | `/api/v1/triage/deck` | JWT | Liefert den Stapel aller noch nicht triagierten Gedanken (`status: 'inbox'`) |
| `PATCH` | `/api/v1/triage/{id}` | JWT | Führt Triage-Aktion aus (`keep`, `discard`, `restore`) |
#### Beispiel: `POST /api/v1/inbox`
Ermöglicht flexible Direkt-Zuordnungen:
```json
// Request (Quick Dump in Triage-Deck)
{
"content": "Kellerfeuchtigkeit über 68% gestiegen #smarthome #alarm",
"priority": "urgent"
}
// Request (Direkt als Aufgabe anlegen)
{
"content": "Server Backup prüfen #devops",
"priority": "high",
"target": "task",
"dueDate": "2026-10-30"
}
```
*Hinweis:* Wenn `/api/v1/inbox` über einen API-Key aufgerufen wird und kein `source` definiert ist, wird die Quelle automatisch als `"webhook"` markiert!
---
### 3.3 Aufgaben & Kanban-System
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/tasks` | JWT | Liefert alle Aufgaben des Benutzers (inkl. geteilter Aufgaben) |
| `POST` | `/api/v1/tasks/reorder` | JWT | Speichert Kanban-Status und Reihenfolge (`sort_order`) |
| `GET` | `/api/v1/task-lists` | JWT | Liefert alle Aufgabenlisten (eigene & geteilte) |
| `POST` | `/api/v1/task-lists` | JWT | Erstellt eine neue Aufgabenliste (mit Farbe & Spalten) |
| `PUT` | `/api/v1/task-lists/{id}` | JWT | Ändert Titel, Farbe, Icon oder Kanban-Spalten |
| `DELETE` | `/api/v1/task-lists/{id}` | JWT | Löscht Aufgabenliste |
| `POST` | `/api/v1/task-lists/{id}/shares` | JWT | Teilt Liste mit Team oder Benutzer |
---
### 3.4 Workspace & Dokumente
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/documents` | JWT | Liefert Liste aller Dokumente des Benutzers (Metadaten) |
| `POST` | `/api/v1/documents` | JWT | Erstellt neues Notiz-Dokument (mit Blocks oder Markdown) |
| `GET` | `/api/v1/documents/{id}` | JWT | Lädt komplettes Dokument inklusive aller Blöcke |
| `PUT` | `/api/v1/documents/{id}` | JWT | Aktualisiert Dokumenttitel, Icon oder Ordnerpfad |
| `PATCH` | `/api/v1/documents/{id}/blocks` | JWT | Granulares Patching von Dokument-Blöcken (Database-First) |
| `DELETE` | `/api/v1/documents/{id}` | JWT | Löscht Dokument (Datenbank & physische Datei) |
| `POST` | `/api/v1/documents/{id}/shares` | JWT | Notiz mit anderem Benutzer teilen (`read` / `write`) |
| `GET` | `/api/v1/documents/{id}/lock` | JWT | Fragt Bearbeitungs-Sperrstatus ab |
| `POST` | `/api/v1/documents/{id}/lock` | JWT | Sperrt Dokument für Bearbeitung (30s Lease) |
| `DELETE` | `/api/v1/documents/{id}/lock` | JWT | Gibt Bearbeitungssperre wieder frei |
---
### 3.5 Workspace Ordner & Geteilte Ordner
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/folders` | JWT | Liefert alle Ordnerpfade des Benutzers |
| `POST` | `/api/v1/folders` | JWT | Legt neuen (auch leeren) Ordner an |
| `POST` | `/api/v1/folders/move` | JWT | Benennt Ordner um oder verschiebt ihn hierarchisch |
| `DELETE` | `/api/v1/folders` | JWT | Löscht Ordner und verschiebt Notizen |
| `GET` | `/api/v1/workspace/folders/shared` | JWT | Liefert für den Benutzer freigegebene geteilte Ordner |
| `POST` | `/api/v1/workspace/folders/shared` | JWT | Erstellt neuen geteilten Ordner |
| `PUT` | `/api/v1/workspace/folders/shared/{id}/mount` | JWT | Ändert den lokalen Einhängepfad beim Empfänger |
| `POST` | `/api/v1/workspace/folders/shared/{id}/shares` | JWT | Gibt Ordner für Teams oder Benutzer frei |
---
### 3.6 Geteilte Listen (Listen & Einkauf)
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/lists` | JWT | Liefert alle geteilten Listen |
| `POST` | `/api/v1/lists` | JWT | Erstellt neue geteilte Liste |
| `GET` | `/api/v1/lists/{id}` | JWT | Lädt Liste inklusive aller Einträge |
| `POST` | `/api/v1/lists/{id}/items` | JWT | Fügt Eintrag hinzu |
| `PATCH` | `/api/v1/lists/{id}/items/{itemId}` | JWT | Hakt Eintrag ab (`isCompleted: true/false`) |
| `POST` | `/api/v1/lists/{id}/items/reorder` | JWT | Speichert sortierte Einträge |
| `POST` | `/api/v1/lists/{id}/clear-completed`| JWT | Löscht alle abgehakten Einträge |
| `POST` | `/api/v1/lists/{id}/shares` | JWT | Teilt Liste mit Team oder Benutzer |
---
### 3.7 Smarthome Ingestion & Externe Webhooks
| Methode | Pfad | Auth | Beschreibung |
| :--- | :--- | :--- | :--- |
| `POST` | `/api/v1/webhooks/ingest` | Token / Key | Empfängt externe Webhook-Payloads von Home Assistant / n8n |
#### Beispiel: `POST /api/v1/webhooks/ingest?token=mindsift_sec_...`
Unterstützt flexible Payloads (JSON oder Plain Text):
```json
{
"title": "Waschmaschine Keller fertig",
"priority": "high",
"tags": ["smarthome", "keller"]
}
```
*Live-Aktualisierung:* Sendet automatisch ein `TASK_CREATED` WebSocket-Event an alle Clients des Benutzers, sodass die neue Karte sofort ohne Neuladen im Triage-Deck erscheint!
+113
View File
@@ -0,0 +1,113 @@
# 📡 WebSocket & Echtzeit-Synchronisation
MindSift implementiert eine bidirektionale Echtzeit-Synchronisationsschicht auf Basis von WebSockets ([`internal/ws/hub.go`](../../internal/ws/hub.go)). Sie sorgt dafür, dass Änderungen an Aufgaben, Triage-Karten, Notizen und geteilten Einkaufslisten ohne manuelles Neuladen sofort auf allen geöffneten Geräten und bei allen Kollaborationspartnern sichtbar werden.
---
## 🔌 1. Verbindung & Handshake
### Verbindungs-Endpunkte
```
wss://<domain>/api/v1/ws?token=<jwt-token>
wss://<domain>/api/v1/ws/lists/<listId>?token=<jwt-token>
```
### Authentifizierung & Upgrade
- Die Authentifizierung erfolgt über das JWT-Token im Query-Parameter `?token=...` oder den `Authorization: Bearer`-Header während des HTTP-Upgrade-Requests.
- Der Server extrahiert die `userID` und registriert die Verbindung im internen `Hub`.
- Der `Upgrader` akzeptiert alle Origins (`CheckOrigin: return true`), um volle Kompatibilität mit Reverse-Proxies (Traefik, Nginx, Caddy, Cloudflare) und Docker-Netzwerken zu gewährleisten.
---
## 🏛️ 2. Hub-Architektur & Rooms
Der WebSocket-Hub unterteilt Verbindungen in drei Abstraktionsebenen:
```
┌─────────────────────────────────────────────────────────────────┐
│ WebSocket Hub │
├─────────────────┬─────────────────────────────┬─────────────────┤
│ allClients │ userRooms │ rooms │
│ (Alle aktiven │ (Pro Benutzer-ID) │ (Pro Liste/ │
│ Verbindungen) │ Cross-Device Sync für │ Space) │
│ │ Tasks, Triage & Workspace │ Geteilte Liste │
└────────┬────────┴──────────────┬──────────────┴────────┬────────┘
▼ ▼ ▼
Presence Stats TASK_CREATED ITEM_TOGGLED
DOC_LOCKED TASK_UPDATED ITEM_CREATED
DOC_UNLOCKED DOC_UPDATED LIST_UPDATED
```
1. **`allClients` (Global):** Hält jede aktive Client-Verbindung. Ermöglicht Broadcasts systemweiter Ereignisse (z.B. globale Dokument-Sperrungen).
2. **`userRooms[userID]` (Benutzer-Räume):** Sendet Events an alle Geräte desselben Benutzers (z.B. Desktop und Smartphone). Erzeugt ein Webhook oder Quick Dump auf dem Smartphone einen Eintrag, taucht dieser zeitgleich auf dem Desktop auf.
3. **`rooms[listID]` (Kollaborations-Räume):** Multiplexing für geteilte Listen. Alle Mitglieder einer Liste empfangen Aktionen (wie Abhaken, Löschen, Umsortieren) in Echtzeit.
---
## 📨 3. Nachrichten-Format (Envelope)
Alle WebSocket-Nachrichten werden als JSON mit einheitlicher Hülle übertragen:
```json
{
"event": "ITEM_TOGGLED",
"listId": "lst_12345",
"payload": {
"itemId": "itm_987",
"isCompleted": true,
"completedBy": "usr_sandro",
"completedByName": "Sandro"
},
"timestamp": "2026-10-26T13:30:00Z"
}
```
---
## 🔒 4. Dokument-Sperrsystem (Document Locking)
Um Schreibkonflikte bei Notizen im Workspace zu vermeiden, verwendet MindSift ein **serverseitiges Lease-Locking mit Heartbeat**:
```mermaid
sequenceDiagram
autonumber
actor UserA as Benutzer A
participant WS as WebSocket Hub
actor UserB as Benutzer B
UserA->>WS: LOCK_DOC (docId: "doc_123")
WS-->>UserA: Lock bestätigt (30s TTL)
WS->>UserB: DOC_LOCKED (docId: "doc_123", lockedBy: "Benutzer A")
Note over UserB: Editor gesperrt (Schreibschutz aktiv)
loop Alle 15 Sekunden
UserA->>WS: HEARTBEAT_DOC (docId: "doc_123")
WS-->>UserA: TTL um 30s verlängert
end
alt Reguläres Schließen
UserA->>WS: UNLOCK_DOC (docId: "doc_123")
WS->>UserB: DOC_UNLOCKED (docId: "doc_123")
Note over UserB: Editor wieder freigegeben
else Verbindungsabbruch / Tab geschlossen
Note over WS: Heartbeat bleibt aus (TTL läuft ab)
WS->>UserB: DOC_UNLOCKED (Automatisch nach Ablauf)
end
```
### Locking-Events
- **`LOCK_DOC` (Client ➔ Server):** Fordert eine 30-Sekunden-Sperre für ein Dokument an.
- **`HEARTBEAT_DOC` (Client ➔ Server):** Verlängert die Sperre alle 15 Sekunden, solange der Benutzer das Dokument geöffnet hat.
- **`UNLOCK_DOC` (Client ➔ Server):** Gibt die Sperre beim Verlassen des Dokuments frei.
- **`DOC_LOCKED` (Server ➔ Clients):** Informiert andere Benutzer, dass das Dokument schreibgeschützt ist.
- **`DOC_UNLOCKED` (Server ➔ Clients):** Hebt den Schreibschutz auf.
---
## 🔄 5. Fallback-Strategie & Reconnect
In strikten Firmennetzwerken oder bei Proxy-Problemen (z.B. fehlende `Upgrade`-Header bei HTTP/1.1) kann eine WebSocket-Verbindung fehlschlagen:
1. **Exponentielles Backoff:** Das Frontend ([`frontend/src/lib/api.ts`](../../frontend/src/lib/api.ts)) versucht automatisch die Wiederverbindung nach 1s, 2s, 4s, 8s, bis maximal 30s.
2. **HTTP-Polling Fallback:** Geteilte Listen und Notizen aktivieren im Hintergrund ein periodisches Polling (5s Intervall), falls der WebSocket-Status nicht `CONNECTED` ist.
3. **Status-Indikator:** Ein dezenter grüner bzw. gelber Indikator oben rechts im Header zeigt dem Benutzer jederzeit den aktuellen Live-Verbindungsstatus an.