# 🧠 BRAIN.md — MindSift Internal Dev Cheat Sheet & Architecture Log > **Zweck:** Zentrales, technisch präzises Nachschlagewerk für Entwicklung, Design-System, Datenbank-Architektur, State-Machines und aktuellen Umsetzungsstand. Wird bei jeder Änderung aktuell gehalten. --- ## 📋 0. Aktueller Projektplan & Umsetzungs-Status ### Erledigte Meilensteine - [x] **CI/CD & Multi-Stage Docker Build (`Dockerfile`, `.gitea/workflows/build-and-publish.yaml`):** - Alle Frontend-Checks (`tsc --noEmit`, `vite build`) und Backend-Tests (`go test -v ./...`) laufen direkt im Multi-Stage Container-Build ohne doppelte Vorab-Steps. - Push auf `dev` baut und überschreibt `git.dsit.me/sandrodach/mindsift:dev`. - [x] **Monochromes, eckiges Desktop-Design & Zentrale CSS-Steuerung (`frontend/src/index.css`, `frontend/tailwind.config.js`):** - Zentrale CSS-Variablen (`--bg-app`, `--bg-panel`, `--accent-primary`, `--border-color`, `--radius-card: 0px`) in `frontend/src/index.css`. - Eckige Tabs, eckige Panels/Karten (`0px` Radius), nur die Schnell-Eingabe-Blase oben im Header und Profil-Avatare sind rund (`rounded-full`). - Untere doppelte Navigationsleiste entfernt; Schnell-Notiz-Blase (`InstantCaptureBar`) sitzt ganz oben im Header über den Tabs. - Workspace links als eckiger, monochromer Datei-/Ordner-Baum (File Explorer Tree mit Unterordnern). - [x] **Quick Dump Notes + Triage Swipen + Direkt-Zuordnung (`InstantCaptureBar.tsx`, `TriageDeck.tsx`, `server.go`):** - **Quick Dump (Standard):** Text oben eingeben + `Enter` wirft den Gedanken sofort als Quick Dump (`status: 'inbox'`) ins Triage-Deck. - **Direkt-Zuordnung bei der Eingabe:** Über das Auswahl-Menü (`Quick Dump ▾`) in der Eingabeleiste kann ein Eintrag alternativ direkt als **Aufgabe** (`target: 'task'`), direkt auf eine **Geteilte Liste** (`target: 'list_item'`) oder direkt als **Workspace-Notiz** (`target: 'document'`) gespeichert werden. - **Triage-Entscheidung & Warteschlange:** Im Triage-Deck per Swipe/Klick **Wegwerfen** (`←` / `H`), **Später** (`Leertaste` – ans Ende schieben), **Auf Liste**, **Als Notiz** (`D`), **Mit Termin** (`T`) oder **Als Aufgabe** (`→` / `L`). Inklusive Inline-Textbearbeitung und Warteschlangen-Liste unter der aktiven Karte. - [x] **Root-Cause Fixes für Browser-Hänger & Cross-Browser-Kompatibilität (Chrome & Firefox):** - **SQLite Connection-Pool Deadlock behoben (`internal/storage/sqlite.go`):** Vorher war `db.SetMaxOpenConns(1)` aktiv, während `GetAllListsForUser`, `GetListsForSpace` und `GetSpacesForUser` innerhalb von `for rows.Next()` (bei offenem Cursor!) Unterabfragen (`s.GetListItems`, `s.GetSpaceMembers`) aufriefen. Sobald eine Liste existierte, blockierte die einzige DB-Verbindung dauerhaft und alle nachfolgenden Requests (`POST /api/v1/inbox` etc.) hingen bis zum 15-Minuten-TCP-Timeout. Jetzt werden alle `rows` strikt vor jeder Unterabfrage geschlossen (`rows.Close()`), WAL-Pragmas + `busy_timeout(10000)` per DSN übergeben und `MaxOpenConns(8)` gesetzt. - **Stale JWT User-Auflösung (`internal/api/server.go`):** Wenn nach einem Container-Neustart eine neue SQLite-DB initialisiert wird, löst `authMiddleware` alte Browser-Tokens automatisch auf `EnsureDefaultUser()` (mit `sync.Mutex` gegen Race-Conditions) auf. - **Service-Worker & Cache-Busting (`frontend/public/sw.js`, `frontend/index.html`, `internal/api/server.go`):** Kein Caching veralteter Bundles in Firefox/Chrome; `Cache-Control: no-store` auf allen `/api/*`-Routen und `index.html`. - **Optimistisches Input-Clearing & Request-Timeout (`frontend/src/lib/api.ts`, `InstantCaptureBar.tsx`):** Eingabefeld leert sich sofort (<10ms) bei `Enter`, alle Fetch-Calls haben einen 8-Sekunden-`AbortController`-Timeout. --- ## 🎨 1. Design-System & CSS-Architektur (`frontend/src/index.css`) Alle Farben, Abstände und Radien werden zentral in [`frontend/src/index.css`](file:///home/sandro/Dokumente/git/MindSift/frontend/src/index.css) über CSS-Variablen gesteuert: ```css :root { /* Monochromer Hintergrund (Dunkles Schiefer/Anthrazit) */ --bg-app: #121316; --bg-panel: #1a1c20; --bg-panel-elevated: #22252a; --bg-panel-hover: #282c33; /* Einzige Akzentfarbe + hellere/gedimmte Variante */ --accent-primary: #2563eb; --accent-hover: #3b82f6; --accent-dim: rgba(37, 99, 235, 0.14); --accent-border: rgba(59, 130, 246, 0.45); /* Kanten & Linien */ --border-color: rgba(255, 255, 255, 0.09); --border-subtle: rgba(255, 255, 255, 0.05); /* Eckiges Layout (0px für Karten/Panels, minimal für Inputs) */ --radius-card: 0px; --radius-btn: 2px; --radius-input: 2px; } ``` ### Zentrale Komponenten-Klassen - `.panel-surface` / `.panel-elevated`: Eckige Container mit `1px solid var(--border-color)`. - `.btn-action`: Monochromer, kompakter Button (`border-radius: var(--radius-btn)`). - `.btn-primary`: Akzent-Button auf `--accent-primary`. - `.input-field`: Minimal gerundetes (`2px`) Eingabefeld für Eigenschaften/Optionen. - `.tab-btn` / `.tab-btn-active`: Eckige, monochrome Header-Tabs. - `.badge-accent`: Kompaktes Akzent-Badge für Zähler und Tags. - **Ausnahme für Rundungen (`rounded-full`):** Nur die Schnell-Eingabe-Blase (`InstantCaptureBar`) im Header, der Profil-Avatar und Toggle-Switches sind rund. --- ## ⚙️ 2. State-Machine: Quick Dump, Direkt-Zuordnung & Triage ``` [ HEADER QUICK-CAPTURE BAR ] │ ┌───────────────────────┼───────────────────────┐ │ Standard (Enter) │ Direkt-Option gewählt │ ▼ ▼ ▼ status: 'inbox' status: 'converted' status: 'converted' (Quick Dump Deck) ├── target: 'task' ├── target: 'list_item' │ └── target: 'document' └── Broadcast via WS │ ├──► Swipe Links / "Wegwerfen" (H / ←) ──► status: 'discarded' ├──► "Später" (Leertaste) ──► ans Ende der lokalen Queue ├──► Swipe Rechts / "Als Aufgabe" (L/→)──► status: 'converted' (type: 'task') ├──► "Mit Termin" (T) ──► status: 'converted' (type: 'task', dueDate) ├──► "Als Notiz" (D) ──► status: 'converted' (type: 'document' + Doc angelegt) └──► "Auf Liste" ──► status: 'converted' (type: 'list_item' + Item angelegt) ``` ### API-Endpunkt für Capture (`POST /api/v1/inbox`) Akzeptiert neben `content`, `priority`, `source`, `dueDate` auch direkt: - `target`: `'inbox'` (Standard Quick Dump) | `'task'` | `'list_item'` | `'document'` - `targetListId`: ID der Zielliste (wenn `target === 'list_item'`) --- ## 🛡️ 3. Kritische Backend-Regeln (SQLite & HTTP) 1. **NIEMALS verschachtelte Queries bei offenem `sql.Rows`-Cursor ausführen:** - In [`internal/storage/sqlite.go`](file:///home/sandro/Dokumente/git/MindSift/internal/storage/sqlite.go) muss jede Schleife `for rows.Next()` zuerst alle Zeilen in ein Slice einlesen und sofort `_ = rows.Close()` aufrufen, **bevor** Folgeabfragen (`GetListItems`, `GetSpaceMembers`, `QueryRow` etc.) ausgeführt werden. 2. **SQLite DSN-Pragmas:** - Jede Verbindung im `sql.DB`-Pool erhält über den DSN automatisch: `?_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)&_pragma=synchronous(NORMAL)&_pragma=foreign_keys(1)` 3. **Thread-Safe Default User (`EnsureDefaultUser`):** - Durch `s.initMu.Lock()` abgesichert, damit parallele Browser-Requests beim ersten Laden niemals in einen `UNIQUE constraint`-Konflikt laufen. 4. **Kein Browser-Caching auf API & `index.html`:** - `writeJSON` und der SPA-Fallback setzen `Cache-Control: no-store, no-cache, must-revalidate`, damit Chrome und Firefox nach jedem Container-Update sofort den aktuellen Stand zeigen. --- ## 📡 4. WebSocket Realtime Protocol (Geteilte Listen) Verbindungs-URL: `ws(s):///api/v1/ws/spaces/:spaceId?token=` ### Events - `ITEM_CREATED` (auch ausgelöst, wenn ein Gedanke per Direkt-Zuordnung oder Triage auf eine Liste geschoben wird) - `ITEM_TOGGLED` - `ITEM_DELETED` - `LIST_CREATED` / `LIST_DELETED` / `LIST_CLEARED` - `USER_PRESENCE` --- ## ⌨️ 5. Tastatur-Shortcuts (Desktop) | Taste | Kontext | Aktion | | :--- | :--- | :--- | | `C` oder `/` | Überall | Fokus sofort oben in die Quick-Dump-Eingabeleiste | | `Enter` | Capture-Leiste | Sofort speichern (Quick Dump oder gewähltes Direkt-Ziel) | | `Esc` | Capture-Leiste | Eingabe leeren & Dropdown schließen | | `H` oder `←` | Triage-Deck | Aktiven Quick Dump wegwerfen (`discard`) | | `L` oder `→` | Triage-Deck | Aktiven Quick Dump sofort zur Aufgabe machen (`task`) | | `T` | Triage-Deck | Datums-Auswahl für Termin-Aufgabe öffnen | | `D` | Triage-Deck | Aktiven Quick Dump sofort in Workspace-Notiz umwandeln | | `Leertaste` | Triage-Deck | Karte überspringen („Später" – ans Ende des Stapels schieben) | --- ## 🚀 6. Gitea CI/CD & Docker Workflow - **Arbeits-Branch:** `dev` (`origin/dev`) - **Ziel-Image:** `git.dsit.me/sandrodach/mindsift:dev` - **Build-Prinzip:** Ein einziger Multi-Stage-Build ([`Dockerfile`](file:///home/sandro/Dokumente/git/MindSift/Dockerfile)), der Frontend-Typecheck, Vite-Build und Go-Unit-Tests (`go test -v ./...` inkl. [`internal/api/server_test.go`](file:///home/sandro/Dokumente/git/MindSift/internal/api/server_test.go)) direkt beim Image-Bau ausführt und bei Erfolg sofort pusht.