Files
MindSift/BRAIN.md
T
sandrodach 4ef71b61cd
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
feat: complete triage, multi-task lists, kanban, workspace wiki, and admin management
2026-10-24 22:08:43 +02:00

15 KiB
Raw Blame History

🧠 BRAIN.md — MindSift Internal Dev Cheat Sheet & Architecture Log

Zweck: Zentrales, technisch prĂ€zises Nachschlagewerk fĂŒr Entwicklung, Design-System, Datenbank-Architektur, State-Machines, Backend-APIs und aktuellen Umsetzungsstand. Wird bei jeder Änderung aktuell gehalten.


📋 0. Aktueller Projektplan & Umsetzungs-Status

Erledigte Meilensteine

  • 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.
  • 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).
  • 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.
  • Mehrere Aufgabenlisten & Kanban-Board (TasksView.tsx, models.go, sqlite.go):
    • Beliebig viele Aufgabenlisten (z.B. Privat, Arbeit, Homelab) mit eigenem Farb- und Icon-Code.
    • Teilen von Aufgabenlisten mit Teams/Spaces.
    • Umschalter zwischen kompakter Listenansicht und 3-Spalten-Kanban-Board (Zu erledigen, In Arbeit, Erledigt) mit 1-Klick-Statuswechsel, FĂ€lligkeitsdaten und Notizfeldern.
  • Benutzer- & Rollensteuerung + Admin-Panel (SettingsModal.tsx, server.go, sqlite.go):
    • Benutzerrollen: admin und member.
    • Admin-Verwaltungsbereich zur Erstellung von Accounts, Rollenwechsel, Deaktivierung und Passwort-Reset.
    • Server-weite Sharing-Isolations-Modi: open (alle finden sich), teams_only (nur innerhalb von Teams/Organisationen sichtbar) und strict_private (kein Teilen).
    • Organisationen & Teams zur Strukturierung von Benutzergruppen.
  • Workspace Markdown-Wiki mit Notion-/Word-Toolbar & Disk-Sync (WorkspaceView.tsx, sqlite.go):
    • Word-/Notion-artige Formatierungsleiste oben (Fett, Kursiv, Durchgestrichen, Code, Links, Überschriften H1-H3, Checklisten, AufzĂ€hlungen, Callouts, Markdown-Tabellen, Fortschrittsbalken).
    • Interne Wiki-Links ([[Dokumenttitel]]) mit Klick-Navigation und Auto-Erkennung.
    • Physische Speicherung auf Festplatte unter /data/workspace/<user_id>/... als Standard-.md-Dateien zur einfachen Daten-Extraktion, synchronisiert mit SQLite.
  • Webhooks, Alarm-Scheduler & Discord-Integration (SettingsModal.tsx, server.go):
    • "Webhooks & Export" aus dem Header in das Benutzereinstellungen-Modal verlagert.
    • Eigene API-Tokens mit curl-Beispielen fĂŒr Skripte und externe Alarme.
    • Hintergrund-Goroutine im Backend prĂŒft fĂ€llige Aufgaben und sendet rechtzeitig (z.B. 15, 30 oder 60 Min. vor FĂ€lligkeit) formatierte Discord-Embeds via Webhook.
    • VollstĂ€ndiger JSON-DB-Export auf Knopfdruck.
  • Cross-Browser & Performance Fixes (Chrome & Firefox):
    • SQLite Connection-Pool Deadlock durch striktes Schließen von sql.Rows vor Unterabfragen behoben.
    • Stale Token Auto-Resolution via EnsureDefaultUser().
    • Cache-Control: no-store auf allen API-Routen und index.html.
    • Optimistisches Leeren des Capture-Inputs und 8-Sekunden-Fetch-Timeout.

🎹 1. Design-System & CSS-Architektur (frontend/src/index.css)

Alle Farben, AbstĂ€nde und Radien werden zentral in frontend/src/index.css ĂŒber CSS-Variablen gesteuert:

: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. Datenbank-Architektur (SQLite Schema & Tabellen)

MindSift speichert alle Daten lokal und hochperformant in SQLite (/data/mindsift.db).

Tabellen-Übersicht

  1. users

    • id TEXT PRIMARY KEY, email TEXT UNIQUE, password_hash TEXT, display_name TEXT
    • role TEXT DEFAULT 'member' ('admin' | 'member')
    • is_active INTEGER DEFAULT 1
    • discord_webhook_url TEXT DEFAULT ''
    • notify_before_minutes INTEGER DEFAULT 15
    • created_at DATETIME, updated_at DATETIME
  2. thoughts (Quick Dumps, Triage & Aufgaben)

    • id TEXT PRIMARY KEY, user_id TEXT, content TEXT, source TEXT, priority TEXT
    • status TEXT ('inbox' | 'converted' | 'discarded')
    • converted_type TEXT ('task' | 'document' | 'list_item')
    • converted_ref_id TEXT (Referenz auf Document oder ListItem)
    • task_list_id TEXT (FK auf task_lists.id)
    • kanban_status TEXT DEFAULT 'todo' ('todo' | 'in_progress' | 'done')
    • notes TEXT DEFAULT '' (zusĂ€tzliche Aufgabenbeschreibung/Notizen)
    • due_date DATETIME (FĂ€lligkeitsdatum)
    • alarm_sent INTEGER DEFAULT 0 (Flag fĂŒr Discord-Benachrichtigung)
    • created_at DATETIME, updated_at DATETIME
  3. task_lists (Mehrere Aufgabenlisten)

    • id TEXT PRIMARY KEY, user_id TEXT, space_id TEXT (optional fĂŒr Team-Sharing)
    • name TEXT NOT NULL, color TEXT DEFAULT '#2563eb', icon TEXT DEFAULT 'list'
    • is_default INTEGER DEFAULT 0, created_at DATETIME, updated_at DATETIME
  4. organizations & teams & team_members

    • organizations: id TEXT PRIMARY KEY, name TEXT, owner_id TEXT, created_at DATETIME, updated_at DATETIME
    • teams: id TEXT PRIMARY KEY, organization_id TEXT, name TEXT, created_at DATETIME
    • team_members: team_id TEXT, user_id TEXT, role TEXT DEFAULT 'member', joined_at DATETIME, PRIMARY KEY (team_id, user_id)
  5. system_settings (Admin-Konfiguration)

    • key TEXT PRIMARY KEY, value TEXT, updated_at DATETIME
    • Wichtige SchlĂŒssel:
      • sharing_isolation_mode: 'open' | 'teams_only' | 'strict_private'
      • allow_public_registration: 'true' | 'false'
  6. documents & document_blocks (Workspace & Disk Sync)

    • documents: id TEXT PRIMARY KEY, user_id TEXT, space_id TEXT, title TEXT, folder_path TEXT DEFAULT '/', is_archived INTEGER, created_at DATETIME, updated_at DATETIME
    • document_blocks: id TEXT PRIMARY KEY, document_id TEXT, block_type TEXT (paragraph, heading1, heading2, heading3, todo, bullet, callout, code, table, progress), content TEXT, order_index INTEGER, metadata TEXT, updated_at DATETIME
  7. spaces, space_members, shared_lists, list_items, api_keys

    • Verwaltung geteilter Einkaufs-/Checklisten und privater Ingestion-Keys.

⚙ 3. 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:

  • content: Fließtext des Gedankens
  • priority: 'low' | 'medium' | 'high'
  • target: 'inbox' (Standard) | 'task' | 'list_item' | 'document'
  • taskListId: ID der Aufgabenliste (wenn target === 'task')
  • targetListId: ID der Zielliste (wenn target === 'list_item')
  • dueDate: Optionales ISO-Datum

🔔 4. Discord-Alarm-Scheduler & Webhook-Architektur

  1. Hintergrund-Ticker im Go-Backend (internal/api/server.go):

    • Ein Hintergrund-Goroutine-Ticker lĂ€uft alle 60 Sekunden.
    • Fragt GetDueTasksForAlarm() ab: Sucht nach offenen Aufgaben (status = 'converted', converted_type = 'task', kanban_status != 'done'), deren due_date in der Vorwarnzeit liegt (due_date <= now + notifyBeforeMinutes) und bei denen alarm_sent == 0 ist.
    • Sendet ein JSON-Embed an die in den Benutzer-Einstellungen hinterlegte discord_webhook_url:
      {
        "username": "MindSift Reminder",
        "embeds": [{
          "title": "⏰ Aufgabe fĂ€llig: <Titel>",
          "description": "<Notizen>",
          "color": 2450411,
          "fields": [
            {"name": "FĂ€llig am", "value": "<Datum>", "inline": true},
            {"name": "PrioritÀt", "value": "<Prio>", "inline": true}
          ]
        }]
      }
      
    • Markiert den Gedanken in SQLite mit MarkTaskAlarmSent(taskID) als benachrichtigt.
  2. Eingehende Webhooks / Private API-Tokens:

    • Erreichbar unter POST /api/v1/inbox mit Header X-API-Key: ms_....
    • Ermöglicht direkte Einbindung in Shell-Skripte, Crons oder Drittsysteme via curl.

  1. Formatierungs-Werkzeuge:
    • Markdown-Syntax wird in Echtzeit formatiert und visuell aufbereitet.
    • Buttons fĂŒr H1, H2, H3, Fett (**), Kursiv (*), Durchgestrichen (~~), Code-Blöcke (```), AufzĂ€hlungen (- ), Todos (- [ ] ), Callouts (> ), Markdown-Tabellen (| Spalte 1 | Spalte 2 |) und Fortschrittsbalken ([progress:65%]).
  2. Wiki-Links ([[Dokumenttitel]]):
    • Interne Querverweise werden als interaktive Links gerendert.
    • Ein Klick auf [[Dokumenttitel]] durchsucht die Workspace-Dokumente und öffnet das verlinkte Dokument direkt im Editor.
  3. Physische Speicherung auf Festplatte:
    • Jede Notiz wird zusĂ€tzlich zur SQLite-Tabelle als reine .md-Datei unter /data/workspace/<user_id>/<folder_path>/<slug>.md gespeichert.
    • Ermöglicht jederzeitige manuelle Datensicherung, Git-Versionierung oder Backup-Extraktion ohne Datenbank-AbhĂ€ngigkeit.

đŸ›Ąïž 6. Kritische Backend-Regeln (SQLite & HTTP)

  1. NIEMALS verschachtelte Queries bei offenem sql.Rows-Cursor ausfĂŒhren:
    • In 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)
    • MaxOpenConns(8) und MaxIdleConns(4) konfiguriert.
  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.

📡 7. WebSocket Realtime Protocol (Geteilte Listen)

Verbindungs-URL: ws(s)://<host>/api/v1/ws/spaces/:spaceId?token=<jwt>

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

⌚ 8. 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)

🚀 9. 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), der Frontend-Typecheck, Vite-Build und Go-Unit-Tests (go test -v ./... inkl. internal/api/server_test.go) direkt beim Image-Bau ausfĂŒhrt und bei Erfolg sofort pusht.