6.7 KiB
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 KonflikterkennungupdatedAt-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.