MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 8s
143 lines
9.1 KiB
Markdown
143 lines
9.1 KiB
Markdown
# 🏛️ Systemarchitektur & Technologie-Stack
|
||
|
||
Dieses Dokument beschreibt die interne Architektur von MindSift, die Interaktion zwischen den Systemkomponenten, das Concurrency- und Thread-Safety-Modell sowie die Deployment-Strategie.
|
||
|
||
---
|
||
|
||
## 🧩 1. Schichten-Architektur
|
||
|
||
MindSift ist als monolithische, hochperformante Single-Binary-Lösung konzipiert. Das Go-Backend liefert sowohl die REST- und WebSocket-Schnittstellen aus als auch die vorkompilierte React Single Page Application (SPA) als eingebettetes statisches Dateisystem (`embed.FS`).
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────┐
|
||
│ Frontend (React 18) │
|
||
│ Vite • TypeScript • Tailwind CSS • Lucide • Motion │
|
||
└───────────────────────────┬────────────────────────────┘
|
||
│ HTTPS REST / WSS WebSocket
|
||
┌───────────────────────────▼────────────────────────────┐
|
||
│ Go Chi Routing Layer │
|
||
│ CORS • RealIP • Recoverer • Auth / Role Guard │
|
||
├───────────────────────────┬────────────────────────────┤
|
||
│ Business Engine │ Gorilla WebSocket │
|
||
│ Triage • Tasks • Alarms │ Rooms • Hub • Doc-Locking │
|
||
├───────────────────────────┴────────────────────────────┤
|
||
│ Storage Abstraction │
|
||
│ sqlite.go (modernc.org/sqlite pure Go, WAL-Mode) │
|
||
└───────────────────────────┬────────────────────────────┘
|
||
│
|
||
┌─────────────┴─────────────┐
|
||
▼ ▼
|
||
/data/mindsift.db /data/workspace/
|
||
(SQLite Datenbank) (Physische .md Dateien)
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ 2. Technologie-Stack
|
||
|
||
### Backend (Go 1.23)
|
||
- **HTTP Routing:** [`github.com/go-chi/chi/v5`](https://github.com/go-chi/chi) – Minimalistischer, idiomatisch schneller Router mit Middleware-Ketten.
|
||
- **WebSocket Hub:** [`github.com/gorilla/websocket`](https://github.com/gorilla/websocket) – Verbindungs-Upgrade, Keep-Alive/Ping-Pong und Room-Multiplexing.
|
||
- **Datenbank-Treiber:** [`modernc.org/sqlite`](https://gitlab.com/cznic/sqlite) – CGO-freier, rein in Go übersetzter SQLite-Treiber für einfache plattformübergreifende Kompilierung und Containerisierung ohne GCC-Toolchain.
|
||
- **Authentifizierung:** [`github.com/golang-jwt/jwt/v5`](https://github.com/golang-jwt/jwt) (HMAC-SHA256 Token) und [`golang.org/x/crypto/bcrypt`](https://pkg.go.dev/golang.org/x/crypto/bcrypt) für Passwort-Hashing.
|
||
|
||
### Frontend (React 18 SPA)
|
||
- **Build-Tool:** [Vite 5](https://vitejs.dev/) für schnelles Hot-Module-Replacement (HMR) und optimierte Production-Bundles.
|
||
- **Sprache:** TypeScript 5 mit strikter Typisierung.
|
||
- **Design & Layout:** [Tailwind CSS 3](https://tailwindcss.com/) in Verbindung mit dem MindSift Single-File CSS Theming System.
|
||
- **Icons & Animationen:** [Lucide React](https://lucide.dev/) und [Framer Motion](https://www.framer.com/motion/) für Gesten, Karten-Swipes und Übergänge.
|
||
|
||
---
|
||
|
||
## 📁 3. Verzeichnisstruktur des Projekts
|
||
|
||
```
|
||
MindSift/
|
||
├── cmd/
|
||
│ └── server/
|
||
│ └── main.go # Einstiegspunkt: Initialisierung, Config, Store, Start
|
||
├── internal/
|
||
│ ├── api/
|
||
│ │ ├── server.go # HTTP-Routen, Handler-Methoden, Middleware
|
||
│ │ └── server_test.go # Integrationstests für alle REST- und Ingest-Routen
|
||
│ ├── auth/
|
||
│ │ ├── auth.go # JWT Validierung, Token-Erstellung, Context-Helpers
|
||
│ │ └── apikey.go # API-Key Erzeugung (mindsift_sec_...) & SHA-256 Hashing
|
||
│ ├── config/
|
||
│ │ └── config.go # Environment-Variablen (PORT, DATA_DIR, JWT_SECRET, SMTP)
|
||
│ ├── domain/
|
||
│ │ └── models.go # Go-Structs für Thought, Document, List, User, Team etc.
|
||
│ ├── storage/
|
||
│ │ ├── sqlite.go # DB-Schema, CRUD-Operationen, Queries, Migrationen
|
||
│ │ └── storage_test.go # Unit-Tests für Speicheroperationen
|
||
│ └── ws/
|
||
│ └── hub.go # WebSocket Client, Room-Management, Locking-Mechanismus
|
||
├── frontend/
|
||
│ ├── src/
|
||
│ │ ├── components/ # Wiederverwendbare UI-Elemente (Modals, Avatar, Menüs)
|
||
│ │ ├── context/ # MobileActionContext (Mobile Bottom Bar State)
|
||
│ │ ├── features/
|
||
│ │ │ ├── auth/ # SetupWizard & Login
|
||
│ │ │ ├── capture/ # InstantCaptureBar (Schnelleingabe)
|
||
│ │ │ ├── help/ # Integrierte Benutzerdokumentation
|
||
│ │ │ ├── lists/ # Geteilte Listen & Einkauf
|
||
│ │ │ ├── settings/ # Benutzer-, Admin- & Theme-Einstellungen
|
||
│ │ │ ├── teams/ # Gruppen & Mitglieder-Management
|
||
│ │ │ ├── triage/ # Triage-Deck, Aufgabenliste, Kanban & TaskModal
|
||
│ │ │ └── workspace/ # Outliner-Editor, Datei-Explorer, Wiki & Rollup
|
||
│ │ ├── lib/ # api.ts (HTTP/WS Client), types.ts, theme.ts
|
||
│ │ ├── themes/ # Eigenständige Theme CSS-Dateien (dark, light, etc.)
|
||
│ │ ├── App.tsx # Root-Komponente, Navigation, Top/Bottom Bars
|
||
│ │ └── main.tsx # React DOM Bootstrap
|
||
│ ├── package.json
|
||
│ └── vite.config.ts
|
||
├── Doku/ # Dieses technische Wiki
|
||
├── Dockerfile # Multi-Stage Build Definition
|
||
└── compose.yaml # Docker Compose Vorlage für Produktivbetrieb
|
||
```
|
||
|
||
---
|
||
|
||
## ⚡ 4. Thread-Safety & Concurrency-Modell
|
||
|
||
Da SQLite Datei-basiert arbeitet und Go standardmäßig hochgradig nebenläufig (Multi-Threaded via Goroutines) operiert, sind folgende Schutzmaßnahmen implementiert:
|
||
|
||
### 1. SQLite Pragmas & WAL-Modus
|
||
Im Storage-Layer ([`internal/storage/sqlite.go`](../internal/storage/sqlite.go)) wird die Datenbankverbindung beim Start zwingend mit folgenden DSN-Pragmas konfiguriert:
|
||
```go
|
||
dsn := filepath.Join(dataDir, "mindsift.db") +
|
||
"?_pragma=busy_timeout(10000)&" +
|
||
"_pragma=journal_mode(WAL)&" +
|
||
"_pragma=synchronous(NORMAL)&" +
|
||
"_pragma=foreign_keys(1)"
|
||
```
|
||
- **`journal_mode(WAL)`:** Write-Ahead Logging erlaubt parallele Leser (`SELECT`), während ein Schreiber (`INSERT`/`UPDATE`) aktiv ist. Leser blockieren niemals Schreiber und Schreiber blockieren niemals Leser.
|
||
- **`busy_timeout(10000)`:** Sollte ein Schreibvorgang kurzzeitig blockiert sein, wartet SQLite bis zu 10.000 ms (10 Sekunden), bevor ein `SQLITE_BUSY` Fehler geworfen wird.
|
||
- **`foreign_keys(1)`:** Erzwingt referenzielle Integrität und automatische Kaskadierungs-Löschungen (`ON DELETE CASCADE`).
|
||
|
||
### 2. Connection Pool Begrenzung
|
||
SQLite unterstützt nur einen einzigen Schreib-Thread zur gleichen Zeit:
|
||
```go
|
||
db.SetMaxOpenConns(8)
|
||
db.SetMaxIdleConns(4)
|
||
db.SetConnMaxLifetime(time.Hour)
|
||
```
|
||
|
||
### 3. Cursor-Deadlock-Vermeidung
|
||
> **Kritische Backend-Regel:** Niemals verschachtelte Abfragen bei offenem `*sql.Rows`-Cursor ausführen!
|
||
In Go hält ein offener Cursor eine Verbindung aus dem Pool besetzt. Führt der Code innerhalb von `for rows.Next()` eine weitere Abfrage auf `s.db` aus, kann der Connection-Pool bei mehreren parallelen Benutzern innerhalb von Millisekunden einfrieren.
|
||
*Pattern:* Alle Zeilen werden sofort vollständig in ein Go-Slice gelesen, `rows.Close()` wird ausgeführt, und erst danach werden verknüpfte Entitäten geladen.
|
||
|
||
---
|
||
|
||
## 🌐 5. Deployment & Container-Architektur
|
||
|
||
MindSift wird als schlanker, autarker Docker-Container ausgeliefert:
|
||
1. **Stage 1 (Frontend Build):** `node:20-alpine` kompiliert TypeScript und generiert statische Assets nach `frontend/dist/`.
|
||
2. **Stage 2 (Backend Build):** `golang:1.23-alpine` bettet `frontend/dist/` via `//go:embed` ein, führt Unit-Tests aus und kompiliert ein statisches Binary (`mindsift-server`).
|
||
3. **Stage 3 (Production Runtime):** `alpine:3.20` mit `ca-certificates` und `tzdata`. Das finale Image ist ca. 45 MB groß und benötigt keine externen Datenbankserver oder Abhängigkeiten.
|
||
|
||
Alle persistenten Daten befinden sich in einem einzigen Verzeichnis `/data`:
|
||
- `/data/mindsift.db` (SQLite Hauptdatenbank)
|
||
- `/data/workspace/` (Physische Markdown-Dateien der Workspace-Notizen)
|