Remove outdated claims (CRDT, DocRooms, presence, .md files on disk) and document the actual architecture, API, permissions and known flaws. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5.3 KiB
Architektur
Überblick
Browser (React SPA, PWA-Manifest)
│ REST /api/v1/* Authorization: Bearer <JWT | mindsift_sec_…>
│ WebSocket /api/v1/ws Fallback: SSE /api/v1/events
▼
Go-Server (chi) ── internal/api Handler, Middleware, Alarm-Ticker
│ internal/ws Hub (Räume, Benutzer-Kanäle, SSE)
│ internal/auth JWT, bcrypt, API-Key-Hash
▼ internal/config
SQLite (modernc.org/sqlite, WAL) ── internal/storage
Das Frontend liegt per go:embed im Binary (cmd/server/main.go). Unbekannte Pfade liefern index.html (SPA-Routing); index.html, sw.js und manifest.json werden mit no-store ausgeliefert.
Stack
| Schicht | Technik |
|---|---|
| Backend | Go 1.23, go-chi/chi v5, go-chi/cors, gorilla/websocket, golang-jwt/jwt v5, x/crypto/bcrypt |
| Datenbank | SQLite über modernc.org/sqlite (reines Go, kein CGO), WAL, foreign_keys=ON |
| Frontend | React 18, TypeScript, Vite 5, Tailwind 3, framer-motion (Triage-Karten), lucide-react, prismjs (Code-Blöcke) |
| Auslieferung | Mehrstufiges Dockerfile (Node 22 → Go 1.23 → Alpine 3.21), Image git.dsit.me/sandrodach/mindsift |
Verzeichnisse
| Pfad | Inhalt |
|---|---|
cmd/server/ |
main.go, eingebettetes dist/ |
internal/api/ |
server.go (Routen, Handler, Alarm-Ticker, SMTP/Discord/Webhook-Versand) |
internal/storage/ |
sqlite.go (Schema, Migrationen, gesamte Datenlogik) |
internal/domain/ |
Strukturen (models.go), ID-Erzeugung, Tag-Extraktion |
internal/ws/ |
hub.go |
internal/auth/ |
Tokens und Passwörter |
internal/config/ |
Umgebungsvariablen |
frontend/src/features/ |
triage, workspace, lists, teams, settings, capture, auth, help |
frontend/src/lib/ |
api.ts (REST-Client, Transport-Umschaltung WS/SSE), types.ts, markdown.tsx, theme.ts |
frontend/src/themes/ |
CSS pro Theme |
Start und Laufzeit
config.Load()liest die Umgebung (siehe unten).storage.NewStore()öffnet SQLite (busy_timeout, WAL, max. 8 Verbindungen) und führtmigrate()aus.- SMTP-Werte aus der Umgebung werden in
system_settingsübernommen, sofern dort noch nichts steht. - Mit Demo-Flag legt
EnsureDemoAccountsdie Kontenadmin/adminunduser/useran. api.NewServerstartet den Alarm-Ticker (jede Minute) und baut den Router. Server-Timeouts: Lesen 15 s, Schreiben 30 s, Leerlauf 60 s. Beim Beenden wird sauber heruntergefahren.
Konfiguration
| Variable | Standard | Bedeutung |
|---|---|---|
PORT |
8080 |
HTTP-Port |
DATA_DIR |
./data (Container: /data) |
Verzeichnis der Datenbank |
DATABASE_URL |
leer | sqlite:///pfad/datei.db oder Pfad; ohne Angabe DATA_DIR/mindsift.db. Postgres-URLs werden nicht unterstützt (siehe Hinweis) |
JWT_SECRET |
festes Fallback (unsicher!) | Signaturschlüssel der Tokens; unbedingt setzen, siehe FLAW-04 |
BASE_URL |
http://localhost:<PORT> |
Basis-URL der Instanz |
ALLOW_REGISTRATION |
false |
Startwert; die Einstellung im Admin-UI (system_settings) hat Vorrang |
LOG_LEVEL / DEBUG |
info / false |
debug, info, warn, error; DEBUG=true erzwingt debug |
MINDA_DEMO (auch MINDSIFT_DEMO, DEMO_MODE) |
false |
Demo-Konten anlegen |
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM, SMTP_TLS |
leer / 587 / true |
Mailversand, auch im Admin-UI einstellbar |
Hinweis: DATABASE_URL mit postgres… führt dazu, dass der Standardpfad in DATA_DIR genutzt wird; Postgres ist nicht implementiert.
Authentifizierung
- Login mit E-Mail, Benutzername (aus dem E-Mail-Präfix) oder
login. Passwörter: bcrypt (DefaultCost). - JWT: HS256, Laufzeit 30 Tage, Claims
userId,email,displayName,tokenVersion,jti. Gültig nur, wenn Token nicht inrevoked_tokenssteht, das Konto aktiv ist undtokenVersionmitusers.token_versionübereinstimmt.token_versionwird bei Passwortänderung, Rollenwechsel, Deaktivierung und „Alle Sitzungen beenden“ erhöht. - Logout schreibt den Token-Hash in
revoked_tokens. - API-Keys:
mindsift_sec_<hex>, gespeichert als SHA-256, nur das Präfix bleibt sichtbar. Der Key gilt als Bearer-Token oder inX-API-Keyund authentifiziert als Besitzer (FLAW-07). - Registrierung: nur mit Einladungscode oder wenn
allow_registrationaktiv ist. Das erste Konto entsteht über/auth/setupund wird Administrator.
Hintergrundjob: Alarme
startAlarmTicker prüft jede Minute alle offenen, noch nicht gemeldeten Aufgaben mit Fälligkeit. Ist due_date <= heute (Serverzeit), sendet er über die Kanäle des Benutzers (email, discord, webhook) und setzt alarm_sent, sobald mindestens ein Kanal erfolgreich war. Details und Einschränkungen: modules/tasks.md, FLAW-12.
Build
Stage 1 node:22-alpine npm ci && npm run build → frontend/dist
Stage 2 golang:1.23 go vet, go test, go build → /app/mindsift (dist wird eingebettet)
Stage 3 alpine:3.21 nur Binary, ca-certificates, tzdata
Die Tests laufen beim Image-Build (go test -v ./...); ein Fehler bricht den Build ab. Frontend-Tests existieren nicht (FLAW-19).