docs: update database schema, websocket protocol, workspace outliner spec, flaws backlog, and readme to match current architecture
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 8s

This commit is contained in:
sandrodach committed 2026-10-26 22:41:50 +01:00
1 parent 634195b629
commit 1776e87029
5 files changed
+160 -124

No files matched your search

+34 -23
View File
@@ -27,7 +27,9 @@ erDiagram
lists ||--o{ list_items : "enthält"
lists ||--o{ list_shares : "wird geteilt mit"
documents ||--o{ document_blocks : "besteht aus"
documents ||--o{ blocks : "besteht aus"
documents ||--o{ block_tags : "indiziert"
blocks ||--o{ block_tags : "verknüpft"
documents ||--o{ doc_shares : "geteilt mit Benutzern"
documents ||--o{ doc_team_shares : "geteilt mit Teams"
documents ||--o{ doc_user_folders : "eigene Platzierung"
@@ -207,45 +209,54 @@ CREATE TABLE IF NOT EXISTS task_list_shares (
### 2.4 Workspace: Dokumente, Blöcke & Geteilte Ordner
#### `documents` & `document_blocks` (Database-First Outliner)
Dokumente werden als Kopfdatensatz in `documents` gespeichert, während der Inhalt als feingranulare Blöcke in `document_blocks` verwaltet wird. MindSift speichert alle Notizen zu 100% in SQLite (keine physischen `.md`-Dateien auf Festplatte).
#### `documents`, `blocks` & `block_tags` (Database-First Outliner Schema)
Dokumente werden als Kopfdatensatz in `documents` gespeichert, während der Inhalt als feingranulare Blöcke in `blocks` verwaltet wird. Hashtags (#tags) werden per Regex analysiert und in `block_tags` abgelegt. MindSift speichert alle Notizen zu 100% in SQLite (keine physischen `.md`-Dateien auf Festplatte).
```sql
CREATE TABLE IF NOT EXISTS documents (
id TEXT PRIMARY KEY, -- Präfix "doc_..."
user_id TEXT NOT NULL, -- Eigentümer
title TEXT NOT NULL, -- Dokumenttitel
user_id TEXT NOT NULL DEFAULT '', -- Eigentümer (usr_...)
space_id TEXT DEFAULT '',
title TEXT NOT NULL DEFAULT '', -- Dokumenttitel
folder_id TEXT NOT NULL DEFAULT '', -- Ordner-Zuordnung
markdown_cache TEXT NOT NULL DEFAULT '', -- Kompiliertes Standard-Markdown (automatischer Cache)
icon TEXT NOT NULL DEFAULT '📄', -- Emoji-Icon
content TEXT NOT NULL DEFAULT '', -- Plaintext / Text-Repräsentation (Cache)
blocks_json TEXT NOT NULL DEFAULT '[]', -- Legacy JSON-Cache
content TEXT NOT NULL DEFAULT '', -- Plaintext / Text-Repräsentation
blocks_json TEXT NOT NULL DEFAULT '[]', -- Legacy/Zusatz-Cache
tags TEXT NOT NULL DEFAULT '[]', -- JSON Array von Tags
folder_path TEXT NOT NULL DEFAULT '', -- Relativer Ordnerpfad des Eigentümers
shared_folder_id TEXT NOT NULL DEFAULT '', -- ID aus workspace_shared_folders (wenn in geteiltem Ordner)
sub_folder_path TEXT NOT NULL DEFAULT '', -- Relativer Unterordnerpfad innerhalb des geteilten Ordners
is_pinned INTEGER NOT NULL DEFAULT 0, -- Globaler Pin
is_archived INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_documents_user ON documents(user_id, is_archived, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_documents_shared_folder ON documents(shared_folder_id);
CREATE TABLE IF NOT EXISTS document_blocks (
id TEXT PRIMARY KEY, -- Präfix "blk_..."
doc_id TEXT NOT NULL,
sort_order REAL NOT NULL DEFAULT 0, -- Fließkommazahl für konfliktfreies Einfügen
type TEXT NOT NULL DEFAULT 'bullet', -- 'bullet', 'todo', 'h1', 'h2', 'h3', 'code', 'quote', 'callout', 'divider'
CREATE TABLE IF NOT EXISTS blocks (
id TEXT PRIMARY KEY, -- Block-ID (z.B. "blk_..." oder "docId-b0")
document_id TEXT NOT NULL, -- Zugehöriges Dokument (doc_...)
content TEXT NOT NULL DEFAULT '', -- Textinhalt des Blocks
level INTEGER NOT NULL DEFAULT 0, -- Hierarchieebene (0 = Root, 1 = Kind...)
level INT NOT NULL DEFAULT 0, -- Hierarchieebene (0 = Root, 1 = Kind...)
position REAL NOT NULL DEFAULT 0, -- Fließkommazahl für konfliktfreies Einfügen/Sortieren
type TEXT NOT NULL DEFAULT 'bullet', -- 'bullet', 'todo', 'h1', 'h2', 'h3', 'code', 'quote', 'callout', 'divider'
checked INTEGER NOT NULL DEFAULT 0, -- Für Checklisten (0 = offen, 1 = abgehakt)
collapsed INTEGER NOT NULL DEFAULT 0, -- Für eingeklappte Unterbäume
collapsed INTEGER NOT NULL DEFAULT 0, -- Für eingeklappte Unterbäume (1 = zugeklappt)
lang TEXT NOT NULL DEFAULT '', -- Programmiersprache für Codeblöcke
updated_at TEXT NOT NULL,
updated_by TEXT NOT NULL DEFAULT '',
FOREIGN KEY(doc_id) REFERENCES documents(id) ON DELETE CASCADE
FOREIGN KEY(document_id) REFERENCES documents(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_document_blocks_doc_order ON document_blocks(doc_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_blocks_doc_pos ON blocks(document_id, position ASC);
CREATE TABLE IF NOT EXISTS block_tags (
tag TEXT NOT NULL, -- Hashtag (z.B. "meeting", ohne führendes '#')
document_id TEXT NOT NULL, -- Zugehöriges Dokument
block_id TEXT NOT NULL, -- Zugehöriger Block
PRIMARY KEY(tag, block_id),
FOREIGN KEY(document_id) REFERENCES documents(id) ON DELETE CASCADE,
FOREIGN KEY(block_id) REFERENCES blocks(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_block_tags_tag ON block_tags(tag);
CREATE INDEX IF NOT EXISTS idx_block_tags_doc ON block_tags(document_id);
```
#### Entkoppelte Ordner-Freigabe (`workspace_shared_folders` & `workspace_folder_mounts`)