sandrodach b53f7c5fc9
MindSift CI & Docker Release / Lint, Build & Unit Tests (push) Successful in 2m13s
MindSift CI & Docker Release / Build & Push Docker Image (push) Successful in 1m43s
fix(frontend): add missing Check icon import in TasksView
2026-10-24 19:05:41 +02:00
2026-10-24 16:56:44 +02:00
2026-10-24 16:56:44 +02:00
2026-10-24 16:56:44 +02:00
2026-10-24 16:56:44 +02:00
2026-10-24 16:56:44 +02:00
2026-10-24 16:56:44 +02:00

🧠 MindSift

Der Kopf frei in drei Sekunden.

Build & Docker Docker Image Backend Frontend Database Styling License

MindSift verbindet den schnellsten Brain-Dump der Welt mit der Eleganz eines modernen Workspaces, spielerischer Tinder-Style-Triage und kollaborativen Echtzeit-Listen für Familien und Teams — 100 % Self-Hosted & Open Source.

Manifest • Features • Architektur • Datenbankschema • API & Webhooks • CI/CD • Deployment • Roadmap


📜 Das Manifest

Große Workspace-Tools wie Notion sind genial, wenn man am Schreibtisch sitzt und ein monatelanges Projekt plant. Aber sie scheitern im Alltag genau an einer Stelle: im echten Moment.

Wenn dir an der Supermarktkasse eine Idee kommt, du im Auto über einen Geistesblitz nachdenkst oder schnell eine Zutat aufschreiben willst, hast du keine Zeit, durch fünf verschachtelte Ordner und relationale Datenbanken zu navigieren. Du brauchst ein Tool, das in einer halben Sekunde bereitsteht, deinen Gedanken friert und dir später hilft, ihn spielerisch auszusortieren.

MindSift löst dieses Problem durch ein dreistufiges Prinzip:

  1. Erfassen: Sofortiger Brain-Dump ohne jede Reibung.
  2. Sichten (Sift): Spielerische Triage im Tinder-Style (Inbox Zero für dein Gehirn).
  3. Strukturieren & Teilen: Workspace für reifende Gedanken und geteilte Echtzeit-Listen für den Alltag.

✨ Features & Workflow

       [ 🚀 Instant Capture ]
   Handy raus • PWA • Webhook • Sprache
                  │
                  ▼
        [ 📥 Thought Inbox ]
                  │
                  ▼
      [ 🃏 Tinder-Style Triage ]
       ┌──────────┴──────────┐
       ▼                     ▼
[ 👈 Nach Links ]      [ 👉 Nach Rechts ]
  Verwerfen / Done       Behalten / Vertiefen
                         ┌───────┼───────┐
                         ▼       ▼       ▼
                       Task    Doc    Shared List
  • ⚡ Capture First (Instant Puffer): Handy raus, App antippen, Cursor steht im Feld. Text tippen oder diktieren (Web Speech API), absenden, fertig. Kein Ordner wählen, kein Tagging, kein Nachdenken. PWA-Shortcut für direkten Homescreen-Capture (< 300 ms Latenz).
  • 🃏 Triage im Tinder-Style: Abends oder am Wochenende gehst du deine unstrukturierten Gedanken durch wie ein Kartendeck:
    • Wisch nach links: Weg damit (Gedanke erledigt oder irrelevant).
    • Wisch nach rechts: Behalten, verfeinern, in eine To-Do mit Fälligkeitsdatum verwandeln oder in ein Projekt einsortieren.
  • 📝 Notion-Flair, aber ohne Ballast: Wächst ein Gedanke zum Projekt heran, wechselst du in den Workspace. Reiner, ablenkungsfreier Block-Editor mit Überschriften, Listen, Codeblöcken und Task-Elementen – ohne relationale Datenbank-Überkomplexität.
  • 🛒 Geteilte Listen & Family Spaces (Echtzeit): Einkaufslisten oder Urlaubsplaner per Link teilen. Hakst du an der Kasse die Hafermilch ab, verschwindet sie bei deinem Partner in Millisekunden dank WebSocket-Synchronisation.
  • 🤖 Webhooks & Ingestion API: Smarthome-Alarme (z. B. Home Assistant, Zigbee2MQTT), Cronjobs oder Webhooks speisen dringende Aufgaben oder Messpunkte direkt in deine Inbox ein.
  • 🛡️ 100 % Self-Hosted & Datensouveränität: Keine fremde Cloud liest mit. Ein schlanker Docker-Container, SQLite mit Write-Ahead-Log (WAL) oder PostgreSQL.

🎨 Designsystem & Ästhetik

MindSift setzt konsequent auf eine ultramoderne, dunkle Productivity-Suite-Ästhetik — fokussiert, augenschonend und schnell:

  • Dark Mode First (Deep Charcoal Canvas):
    • Hintergrund primär: #16171a
    • Oberflächen/Karten: #222428 mit feinen 1px Konturen (rgba(255, 255, 255, 0.08))
    • Elevated & Hover: #282a2f / #2b2d33
    • Primär-Brand: Electric Blue (#1d8cf8)
    • Status-Akzente: Vivid Green (#22c55e), Coral Red (#ef4444), Vivid Orange (#f97316)
  • Squircles & Solid Color Badges: Quadratisch abgerundete Icons (rounded-xl) mit satten Einzelfarben ohne grelle AI-Farbverläufe.
  • Pill-Buttons & Active Highlighting: Filter-Chips (All, Favorite) und Action-Buttons in Pillenform (rounded-full); aktive Aufgaben erhalten eine scharfe grüne Kontur (border border-[#22c55e]/70).
  • Floating Bottom Dock: Zentrale Daumenleiste mit markantem blauem + Action-Button zum blitzschnellen Gedanken-Erfassen von überall.
  • Haptik & Touch-Optimierung: Große Interaktionsradien (mind. 48px Touch-Targets), Vibrations-Feedback via Web Vibration API bei Karten-Swipes.

🏗️ Technische Architektur & Tech-Stack

Als Lead-Architektur wurde ein Single-Binary / Single-Container Paradigma gewählt. Das Go-Backend kompiliert das React-Frontend direkt in ein einziges Executable ein (embed.FS).

┌─────────────────────────────────────────────────────────────────────────┐
│                       Client (Mobile PWA / Desktop)                     │
│  React 19 • Vite • Tailwind CSS v4 • Framer Motion • Tiptap Block-Editor │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │ HTTP/2 / REST & WebSockets (WSS)
┌───────────────────────────────▼─────────────────────────────────────────┐
│                    MindSift Single Container (Go 1.24)                  │
│                                                                         │
│   ┌─────────────────────┐   ┌─────────────────┐   ┌─────────────────┐   │
│   │   Embedded Assets   │   │  Chi HTTP Mux   │   │ WebSocket Hub   │   │
│   │   (React SPA Dist)  │   │  REST / Webhook │   │ (Realtime Sync) │   │
│   └─────────────────────┘   └────────┬────────┘   └────────┬────────┘   │
│                                      │                     │            │
│                              ┌───────▼─────────────────────▼────────┐   │
│                              │       Business Service Layer         │   │
│                              │   (Capture, Triage, Docs, Lists)     │   │
│                              └──────────────────┬───────────────────┘   │
│                                                 │                       │
│                              ┌──────────────────▼───────────────────┐   │
│                              │    Data Access Layer (sqlc / WAL)    │   │
│                              └──────────────────┬───────────────────┘   │
└─────────────────────────────────────────────────┼───────────────────────┘
                                                  │
                               ┌──────────────────▼───────────────────┐
                               │   SQLite 3 (WAL Mode, zero-config)   │
                               │   *Optional: PostgreSQL Driver       │
                               └──────────────────────────────────────┘

Stack-Entscheidungen & Rationale

Schicht Technologie Begründung & Architekturentscheidung
Backend Go 1.24+ (Chi Router) Extrem geringer Speicherverbrauch (~15–25 MB RAM idle), Kaltstart in < 5 ms, überlegene Concurrency für WebSockets, erzeugt ein statisches Binary.
Frontend React 19 + TypeScript + Vite Bietet mit Framer Motion die beste Gesten- und Physik-Engine für flüssige Tinder-Swipes und mit Tiptap den industrieweit führenden blockbasierten Rich-Text-Editor.
Styling Tailwind CSS v4 Höchste Performance, null CSS-Runtime-Overhead, perfekte Abbildung des Deep Dark Themes mit Design-Tokens.
Realtime Go WebSockets (nhooyr/websocket) Schlanke, native WebSocket-Rooms für kollaborative Einkaufslisten mit Sub-10ms-Latenz und automatischem Reconnect.
Datenbank SQLite (WAL-Modus) / sqlc Standardmäßig Zero-Config mit Write-Ahead-Logging, ACID-sicher und als einzelne Datei einfachst per Backup sicherbar. Optional umschaltbar auf PostgreSQL per DATABASE_URL.
PWA / Offline Workbox / IndexedDB App startet auch im Funkloch sofort; Gedanken werden lokal vorgehalten und beim nächsten Verbindungsaufbau transparent synchronisiert.
Container Distroless / Alpine Scratch Minimalistisches Multi-Stage Dockerfile. End-Image-Größe < 35 MB. Keine Sicherheitsrisiken durch überflüssige System-Pakete.

🗄️ Datenbankschema

Das Schema ist relational strukturiert, normalisiert und auf Lese- sowie Schreibgeschwindigkeit im Sub-Millisekundenbereich optimiert.

erDiagram
    USERS ||--o{ THOUGHTS : owns
    USERS ||--o{ DOCUMENTS : authors
    USERS ||--o{ SPACE_MEMBERS : participates
    USERS ||--o{ API_KEYS : possesses
    SPACES ||--o{ SPACE_MEMBERS : contains
    SPACES ||--o{ LISTS : hosts
    LISTS ||--o{ LIST_ITEMS : contains
    DOCUMENTS ||--o{ DOCUMENT_BLOCKS : contains

    USERS {
        uuid id PK
        string email UK
        string password_hash
        string display_name
        timestamp created_at
    }

    THOUGHTS {
        uuid id PK
        uuid user_id FK
        text content
        string voice_transcript
        string status "inbox | kept | discarded | converted"
        string converted_type "task | document | list_item"
        uuid converted_ref_id
        timestamp due_date
        timestamp created_at
        timestamp triaged_at
    }

    DOCUMENTS {
        uuid id PK
        uuid user_id FK
        uuid space_id FK
        string title
        string icon
        boolean is_archived
        timestamp created_at
        timestamp updated_at
    }

    DOCUMENT_BLOCKS {
        uuid id PK
        uuid document_id FK
        string block_type "paragraph | heading | task | code"
        jsonb content
        int sort_order
        timestamp updated_at
    }

    SPACES {
        uuid id PK
        string name
        string icon
        boolean is_personal
        timestamp created_at
    }

    SPACE_MEMBERS {
        uuid space_id PK,FK
        uuid user_id PK,FK
        string role "owner | editor | viewer"
        timestamp joined_at
    }

    LISTS {
        uuid id PK
        uuid space_id FK
        string title
        string list_type "shopping | checklist"
        timestamp updated_at
    }

    LIST_ITEMS {
        uuid id PK
        uuid list_id FK
        string content
        boolean is_completed
        uuid completed_by FK
        timestamp completed_at
        int sort_order
    }

    API_KEYS {
        uuid id PK
        uuid user_id FK
        string name
        string key_hash UK
        string scopes
        timestamp last_used_at
    }

SQL DDL Definitionen (Auszug SQLite / Postgres kompatibel)

-- Aktivierung von WAL & Foreign Keys für SQLite
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;
PRAGMA busy_timeout = 5000;

-- Gedanken & Instant Inbox Puffer
CREATE TABLE IF NOT EXISTS thoughts (
    id TEXT PRIMARY KEY,
    user_id TEXT NOT NULL,
    content TEXT NOT NULL,
    status TEXT CHECK(status IN ('inbox', 'kept', 'discarded', 'converted')) DEFAULT 'inbox',
    converted_type TEXT CHECK(converted_type IN ('task', 'document', 'list_item', NULL)),
    converted_ref_id TEXT,
    due_date DATETIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    triaged_at DATETIME,
    FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);

CREATE INDEX idx_thoughts_user_status ON thoughts(user_id, status, created_at DESC);

-- Kollaborative Listen (z.B. Familie & Einkaufen)
CREATE TABLE IF NOT EXISTS list_items (
    id TEXT PRIMARY KEY,
    list_id TEXT NOT NULL,
    content TEXT NOT NULL,
    is_completed BOOLEAN NOT NULL DEFAULT 0,
    completed_by TEXT,
    sort_order INTEGER NOT NULL DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    completed_at DATETIME,
    FOREIGN KEY(list_id) REFERENCES lists(id) ON DELETE CASCADE
);

CREATE INDEX idx_list_items_sync ON list_items(list_id, is_completed, sort_order ASC);

🔌 API-Spezifikation & Webhooks

Alle Endpunkte antworten mit application/json und nutzen Standard-HTTP-Statuscodes. Die Authentifizierung erfolgt über Bearer <JWT> oder dedizierte Ingestion-Keys.

1. Instant Capture & Ingestion (Sub-Second Entry)

POST /api/v1/inbox
Authorization: Bearer <token>
Content-Type: application/json

{
  "content": "Zündkerzen für den Rasenmäher bestellen #garage",
  "due_date": "2026-10-25T18:00:00Z" // Optional
}

Response (201 Created - < 30ms):

{
  "id": "th_9f8a3c21",
  "status": "inbox",
  "created_at": "2026-10-24T16:25:00Z"
}

2. Smarthome & Externe Webhook Ingestion

Für Home Assistant, Node-RED, n8n oder Shell-Skripte:

POST /api/v1/webhooks/ingest?token=mindsift_sec_789xyz
Content-Type: application/json

{
  "title": "Kellerfeuchtigkeit über 70%",
  "priority": "urgent",
  "tags": ["smarthome", "keller"]
}

3. Triage & Tinder-Style Swipe Deck

  • Gedanken-Deck laden: GET /api/v1/triage/deck?limit=20
  • Gedanke wischen (Swipe Action):
PATCH /api/v1/triage/th_9f8a3c21
Authorization: Bearer <token>
Content-Type: application/json

{
  "action": "keep", // oder "discard"
  "convert_to": "task", // optional: "task" | "document" | "list_item"
  "target_list_id": "lst_shopping_123", // wenn convert_to = "list_item"
  "due_date": "2026-10-28T09:00:00Z"
}

4. Realtime WebSocket Protocol (Kollaborative Listen)

Client verbindet sich zu wss://mindsift.local/api/v1/ws/spaces/:space_id.

  • Event: Item hinzugefügt/aktualisiert
{
  "event": "ITEM_UPDATED",
  "payload": {
    "list_id": "lst_shopping_123",
    "item_id": "itm_456",
    "content": "Hafermilch (Barista)",
    "is_completed": true,
    "user_name": "Sandro"
  }
}

🚀 Gitea CI/CD Pipeline

Das Projekt ist für den Betrieb mit Gitea Actions optimiert. Bei jedem Push auf main oder einem Release-Tag baut die Pipeline automatisch ein Multi-Arch-Docker-Image (linux/amd64, linux/arm64) und schiebt es in die Gitea Container Registry.

Workflow-Datei: .gitea/workflows/build-and-publish.yaml

name: MindSift Multi-Arch Docker Build

on:
  push:
    branches:
      - main
    tags:
      - 'v*'
  pull_request:
    branches:
      - main

jobs:
  test:
    name: Lint & Unit Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.24'
          cache: true

      - name: Run Backend Tests
        run: |
          go vet ./...
          go test -v -race ./...

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json

      - name: Run Frontend Tests
        run: |
          cd frontend
          npm ci
          npm run lint
          npm run test:run

  build-docker:
    name: Build & Push Docker Image
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set up QEMU (Multi-Arch)
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Gitea Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ gitea.server_url }}
          username: ${{ gitea.actor }}
          password: ${{ secrets.GITEA_TOKEN }}

      - name: Extract Metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ gitea.server_url }}/${{ gitea.repository }}
          tags: |
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
            type=semver,pattern={{version}}

      - name: Build and Push
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Multi-Stage Dockerfile (Dockerfile)

# Stage 1: Frontend Build
FROM node:22-alpine AS frontend-builder
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build

# Stage 2: Go Backend Build
FROM golang:1.24-alpine AS backend-builder
WORKDIR /app
RUN apk add --no-cache build-base git
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Kopiere gebaute Frontend Assets in das embed.FS-Verzeichnis
COPY --from=frontend-builder /app/frontend/dist ./server/dist
RUN CGO_ENABLED=1 GOOS=linux go build -ldflags="-s -w -extldflags '-static'" -o mindsift ./cmd/server

# Stage 3: Minimal Production Image
FROM alpine:3.21
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=backend-builder /app/mindsift /app/mindsift

ENV PORT=8080
ENV DATA_DIR=/data
VOLUME ["/data"]

EXPOSE 8080
USER 1000:1000
ENTRYPOINT ["/app/mindsift"]

🐳 Deployment & Schnellstart

1. Schnellstart mit Docker Compose (Empfohlen)

Erstelle eine docker-compose.yml:

services:
  mindsift:
    image: gitea.your-domain.com/user/mindsift:latest
    container_name: mindsift
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./data:/data
    environment:
      - PORT=8080
      - DATA_DIR=/data
      - JWT_SECRET=change_this_to_a_secure_random_key_min_32_chars
      - BASE_URL=https://mindsift.local
      - LOG_LEVEL=info

Starte den Service:

docker compose up -d

Die Weboberfläche steht sofort unter http://localhost:8080 bereit.

2. Standalone Docker Run

docker run -d \
  --name mindsift \
  --restart unless-stopped \
  -p 8080:8080 \
  -v $(pwd)/mindsift-data:/data \
  -e JWT_SECRET="dein-super-sicheres-geheimnis" \
  gitea.your-domain.com/user/mindsift:latest

Umgebungsvariablen

Variable Standardwert Beschreibung
PORT 8080 Interner HTTP/WebSocket Port
DATA_DIR /data Verzeichnis für SQLite DB, Uploads und Cache
DATABASE_URL sqlite:///data/mindsift.db Optional: PostgreSQL DSN (postgres://user:pass@host:5432/db)
JWT_SECRET Pflichtfeld Secret für Authentifizierungs-Tokens (mind. 32 Zeichen)
BASE_URL http://localhost:8080 Externe URL für Einladungslinks und Webhooks
ALLOW_REGISTRATION true Erstregistrierung erlauben (false nach Admin-Erstellung)

🗺️ Schrittweiser Phasenplan

Phase 1: Foundation ────► Phase 2: Triage Deck ────► Phase 3: Workspace
   (Go + PWA + DB)           (Framer Physics)          (Tiptap Blocks)
                                                            │
Phase 6: Hardening  ◄──── Phase 5: Webhooks    ◄──── Phase 4: Realtime
  (CI/CD + Release)         (Smarthome Ingest)         (Family Lists)

Phase 1: Core Foundation & Instant Capture (Sprint 1)

  • Repository-Initialisierung & Architektur-Design
  • Go Backend-Grundgerüst (Chi Router, Konfigurations-Management, Healthcheck)
  • SQLite Storage-Layer mit WAL-Modus und automatischer Migration
  • JWT-Authentifizierung & User-Management
  • Mobile-First PWA Setup (Vite, React, Tailwind CSS, Deep Dark Theme)
  • Instant-Capture-Interface: Autofokus-Eingabemaske, Sprachaufnahme (Web Speech API), Latenz < 300 ms

Phase 2: Tinder-Style Triage & Task Engine (Sprint 2)

  • Interaktives Swipe-Deck mit Framer Motion (Gesten, Rotation, elastische Rückfederung)
  • Triage-Status-Engine (inbox -> kept / discarded / converted)
  • Quick-Convert: Wisch nach rechts transformiert Gedanken direkt in Aufgaben mit Due-Date, Projekt-Notizen oder Listen-Einträge
  • Tastatur-Shortcuts für Power-User am Desktop (H/L oder Pfeiltasten, C// für Capture)
  • Haptisches Feedback auf Mobilgeräten (Web Vibration API)

Phase 3: Notion-Style Workspace (Sprint 3)

  • Block-Editor (Headings, Task-Checkboxes, Code-Blöcke, Callouts, Listen)
  • Dokumenten-Verwaltung für vertiefte Gedanken inkl. Pinning & Icon-Picker
  • Tagging & Volltextsuche über Gedanken und Dokumente
  • Markdown Export (.md)

Phase 4: Realtime Spaces & Family Sync (Sprint 4)

  • Multi-User Space-Architektur (Familien- und Team-Räume mit Invite-Codes)
  • Go WebSocket Hub mit Raum-Multiplexing
  • Echtzeit-Einkaufslisten: Sofortige Synchronisation von Checked-States über alle Endgeräte
  • Optimistische UI-Updates für verzögerungsfreies Offline-/Online-Erlebnis

Phase 5: Smarthome Webhooks & External Ecosystem (Sprint 5)

  • Ingestion-API mit API-Token-Management (mindsift_sec_...)
  • Webhook-Endpunkte für Home Assistant, Zigbee2MQTT, n8n und Cronjobs
  • Interaktiver Live-Webhook-Simulator in der UI
  • Backup- und Export-Endpunkt (kompletter JSON-Export)

Phase 6: Production Hardening, CI/CD & v1.0 (Sprint 6)

  • Gitea Actions Multi-Arch Workflow (amd64, arm64)
  • Single-Container Packaging (embed.FS) & Multi-Stage Dockerfile
  • Automatisierte Backend-Unit-Tests (internal/storage/sqlite_test.go)
  • End-to-End Tests (Playwright) auf Ziel-Cluster
  • Erstellung der offiziellen Dokumentation & v1.0 Release-Bereitschaft

🔒 Sicherheit & Datenschutz

  • Zero Tracking: Keine Analytics, keine externen CDNs, keine Telemetrie.
  • Content Security Policy (CSP): Strikte Header; alle Assets und Fonts werden lokal ausgeliefert.
  • Sichere Passwörter: Argon2id Passwort-Hashing nach OWASP-Empfehlung.
  • Isolierte Container: Der Container läuft standardmäßig unter einer Non-Root-UID (1000:1000).

📄 Lizenz

Dieses Projekt ist lizenziert unter der MIT-Lizenz – siehe LICENSE für Details.


Designed with ❤️ for clarity, speed and digital sovereignty.
S
Description
No description provided
Readme
4.1 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 66.2%
Go 31.5%
CSS 1.6%
JavaScript 0.2%
Dockerfile 0.2%
Other 0.3%