MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 38s
9.4 KiB
9.4 KiB
🧠 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
- 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
devbaut und überschreibtgit.dsit.me/sandrodach/mindsift:dev.
- Alle Frontend-Checks (
- 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) infrontend/src/index.css. - Eckige Tabs, eckige Panels/Karten (
0pxRadius), 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).
- Zentrale CSS-Variablen (
- Quick Dump Notes + Triage Swipen + Direkt-Zuordnung (
InstantCaptureBar.tsx,TriageDeck.tsx,server.go):- Quick Dump (Standard): Text oben eingeben +
Enterwirft 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.
- Quick Dump (Standard): Text oben eingeben +
- Root-Cause Fixes für Browser-Hänger & Cross-Browser-Kompatibilität (Chrome & Firefox):
- SQLite Connection-Pool Deadlock behoben (
internal/storage/sqlite.go): Vorher wardb.SetMaxOpenConns(1)aktiv, währendGetAllListsForUser,GetListsForSpaceundGetSpacesForUserinnerhalb vonfor 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/inboxetc.) hingen bis zum 15-Minuten-TCP-Timeout. Jetzt werden allerowsstrikt vor jeder Unterabfrage geschlossen (rows.Close()), WAL-Pragmas +busy_timeout(10000)per DSN übergeben undMaxOpenConns(8)gesetzt. - Stale JWT User-Auflösung (
internal/api/server.go): Wenn nach einem Container-Neustart eine neue SQLite-DB initialisiert wird, löstauthMiddlewarealte Browser-Tokens automatisch aufEnsureDefaultUser()(mitsync.Mutexgegen 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-storeauf allen/api/*-Routen undindex.html. - Optimistisches Input-Clearing & Request-Timeout (
frontend/src/lib/api.ts,InstantCaptureBar.tsx): Eingabefeld leert sich sofort (<10ms) beiEnter, alle Fetch-Calls haben einen 8-Sekunden-AbortController-Timeout.
- SQLite Connection-Pool Deadlock behoben (
🎨 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 mit1px 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 (wenntarget === 'list_item')
🛡️ 3. Kritische Backend-Regeln (SQLite & HTTP)
- NIEMALS verschachtelte Queries bei offenem
sql.Rows-Cursor ausführen:- In
internal/storage/sqlite.gomuss jede Schleifefor rows.Next()zuerst alle Zeilen in ein Slice einlesen und sofort_ = rows.Close()aufrufen, bevor Folgeabfragen (GetListItems,GetSpaceMembers,QueryRowetc.) ausgeführt werden.
- In
- 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)
- Jede Verbindung im
- Thread-Safe Default User (
EnsureDefaultUser):- Durch
s.initMu.Lock()abgesichert, damit parallele Browser-Requests beim ersten Laden niemals in einenUNIQUE constraint-Konflikt laufen.
- Durch
- Kein Browser-Caching auf API &
index.html:writeJSONund der SPA-Fallback setzenCache-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)://<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_TOGGLEDITEM_DELETEDLIST_CREATED/LIST_DELETED/LIST_CLEAREDUSER_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), 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.