# Ka-Note — Entitäten & Datenmodell ## Hierarchie ``` Kontext (AgendaContext) z.B. "JF Team Sysadmins", "Project TISAX" └─ Thema (Topic) z.B. "TISAX: Sperren Produktionsrechner" └─ Eintrag (HistoryEntry) z.B. "Hr. Müller angerufen. Server down." └─ Bewertung (Rating) z.B. STEFE gibt 3/4 ``` --- ## Entitäten im Detail ### 1. Kontext (AgendaContext) Oberster Container. Gruppiert Themen nach Anlass. | Feld | Beschreibung | |------|-------------| | `id` | UUID (Sonderfall: `"daily-log"` ist hartkodiert) | | `name` | Anzeigename | | `type` | `meeting` · `project` · `person` | | `sortOrder` | Reihenfolge in der Sidebar | | `meta` | Typ-abhängig: ProjectMeta oder PersonMeta | | `archivedAt` | Archiviert (soft) | **Drei Typen:** | Typ | Zweck | Meta-Felder | |-----|-------|-------------| | `meeting` | Regelmeetings, Daily Log | — | | `project` | Projektbezogene Themen | status, owner, links | | `person` | Personenbezogene Themen | fullName, email, phone, duSince | **Sonder-Kontext:** `daily-log` — immer vorhanden, Standard-Inbox, immer Meeting-Modus. --- ### 2. Thema (Topic) Ein Diskussionspunkt / Agenda-Item / Aufgabenblock innerhalb eines Kontexts. **Bündelt mehrere Einträge (Notizen).** | Feld | Beschreibung | |------|-------------| | `id` | UUID | | `contextId` | Verweis auf übergeordneten Kontext | | `title` | Titel des Themas | | `status` | `active` · `snoozed` · `done` | | `snoozeUntil` | Datum, ab dem snoozed-Thema wieder erscheint | | `sortOrder` | Reihenfolge innerhalb des Kontexts | | `isNew` | Zeigt grünes "NEU"-Badge bis erster Eintrag erstellt | **Status-Bedeutung:** | Status | Bedeutung | |--------|-----------| | `active` | Offen, wird angezeigt | | `snoozed` | Versteckt bis `snoozeUntil`-Datum | | `done` | Erledigt / archiviert | **Sonder-Themen (automatisch, versteckt):** - `daily-log-journal` — Journal-Einträge im Daily Log - `{contextId}-notes` — Freie Notizen je Projekt/Person --- ### 3. Eintrag (HistoryEntry) Eine einzelne, datierte Notiz innerhalb eines Themas. Markdown-formatiert. | Feld | Beschreibung | |------|-------------| | `id` | UUID | | `topicId` | Verweis auf übergeordnetes Thema | | `date` | Datum (YYYY-MM-DD) | | `text` | Markdown-Inhalt mit Inline-Tags | | `sortOrder` | Reihenfolge (neueste oben) | | `linkedContextId` | Optionaler Verweis auf anderen Kontext | | `doneAt` | Erledigt-Zeitstempel (toggle) | **Inline-Tags im Text:** | Syntax | Zweck | Beispiel | |--------|-------|---------| | `-> NAME` | Zuweisung an Person | `-> STEFE` | | `@P:PROJEKT` | Projekt-Referenz | `@P:TISAX` | | `@NAME` | Person erwähnen | `@CHFI` | --- ### 4. Bewertung (Rating) Bewertung eines Eintrags durch eine Person (1–4 Skala). | Feld | Beschreibung | |------|-------------| | `id` | UUID | | `topicId` | Verweis auf Thema | | `historyEntryId` | Verweis auf bewerteten Eintrag | | `personName` | Name des Bewertenden | | `value` | `1` · `2` · `3` · `4` | --- ## Zusammenfassung: "Thema anlegen" vs. "Eintrag hinzufügen" | Aktion | Erzeugt | Was passiert | |--------|---------|-------------| | **Thema anlegen** | Topic | Neuer Diskussionspunkt/Block. Kann danach beliebig viele Einträge enthalten. Erscheint mit "NEU"-Badge. | | **Eintrag hinzufügen** | HistoryEntry | Einzelne datierte Notiz innerhalb eines bestehenden Themas. Markdown mit Inline-Tags. | **Kurz:** Ein Thema ist der Ordner, ein Eintrag ist das Blatt darin. --- ## Querschnittliche Konzepte ### Soft-Delete Nichts wird hart gelöscht. Stattdessen wird `deletedAt` gesetzt. Ermöglicht Wiederherstellung und Sync. ### Basis-Felder (SyncEntity) Jede Entität hat: `id`, `updatedAt`, `deletedAt`, `version`. ### Session-State (nicht persistiert) - `processedInCurrentSession` — Thema wurde in laufender Sitzung besprochen (sessionStorage, verschwindet bei Tab-Schließung) - `isCollapsed` — UI-only, ob Thema-Karte eingeklappt ist (nur im Svelte-Store) ### Modi - **Prep-Modus** — Vorbereitung: Themen anlegen, Einträge schreiben - **Meeting-Modus** — Durchführung: Themen als besprochen markieren, aufteilen in "Aktuell" / "Bereits besprochen" --- ## Datenspeicherung ### Client: IndexedDB via Dexie.js Alle Daten liegen **lokal im Browser** in einer IndexedDB-Datenbank. | Eigenschaft | Wert | |-------------|------| | DB-Name | `ka-note` | | Library | Dexie.js v4 | | Schema-Version | 5 | | Schema-Datei | `client/src/lib/db/schema.ts` | **Tabellen & Indizes:** | Tabelle | Indizes | Zweck | |---------|---------|-------| | `contexts` | `id, type, sortOrder, deletedAt, archivedAt` | Kontexte | | `topics` | `id, contextId, status, sortOrder, deletedAt` | Themen | | `historyEntries` | `id, topicId, date, sortOrder, deletedAt, linkedContextId, doneAt` | Einträge | | `ratings` | `id, topicId, historyEntryId, personName, deletedAt` | Bewertungen | | `syncMeta` | `id, entityType, entityId, synced` | Sync-Status (0=unsynced, 1=synced) | | `imageBlobs` | `id, createdAt` | Bilder als Binärdaten in IndexedDB | **Reaktive Abfragen:** Svelte-Stores nutzen Dexie `liveQuery` (`client/src/lib/stores/agenda.ts`) — UI aktualisiert sich automatisch bei DB-Änderungen. **CRUD-Schicht:** `client/src/lib/db/repositories.ts` — alle Lese-/Schreiboperationen. **Seed-Daten:** `client/src/lib/db/seed.ts` — Beispieldaten beim ersten Start. ### Server: SQLite via Hono | Eigenschaft | Wert | |-------------|------| | Framework | Hono v4 + @hono/node-server | | Datenbank | SQLite | | DB-Dateipfad (Docker) | `/data/ka-note.db` | | Env-Variable | `DATABASE_PATH` | | Port | 3001 | **Aktueller Stand:** Der Server stellt bisher nur einen Health-Endpoint bereit (`GET /api/health`). Drizzle ORM und Sync-Endpunkte sind noch nicht implementiert. **Docker-Volume:** Die SQLite-Datei wird über ein Docker-Volume (`server-data`) persistiert, sodass Daten Container-Neustarts überleben. ### Sync-Mechanismus (in Entwicklung) Infrastruktur vorbereitet, aber noch nicht aktiv: - **SyncMeta-Tabelle** im Client trackt pro Entität, ob sie synchronisiert ist (`synced: 0|1`) - **`version`-Feld** auf jeder Entität für Konflikterkennung - **`updatedAt`-Timestamp** (ISO 8601) für Reihenfolge - **Soft-Delete** ermöglicht sichere Sync-Abgleichung (gelöschte Einträge bleiben als Marker erhalten) ### Session-Speicher (flüchtig) | Speicher | Key | Inhalt | Lebensdauer | |----------|-----|--------|-------------| | sessionStorage | `ka-note-processed` | IDs besprochener Themen | Bis Tab geschlossen | | Svelte-Store (Memory) | — | Collapsed-Status der Themen-Karten | Bis Seite neu geladen | ### Bilder Bilder werden als Blobs direkt in IndexedDB gespeichert (Tabelle `imageBlobs`). Im Markdown-Text werden sie über `ka-img:{imageId}` referenziert. Verwaltung in `client/src/lib/db/imageStore.ts`.