Umsetzung der Ausbaustufen 2.1, 3.6, 3.8, 3.9, 4.1, 4.2, 4.4, 4.6, 5.1–5.4 (Details in AUSBAUSTUFEN.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
420 lines
30 KiB
Markdown
420 lines
30 KiB
Markdown
# Repomap — Munin
|
|
|
|
Übersicht aller Dateien und Ordner mit ihrer Aufgabe.
|
|
|
|
```
|
|
munin/
|
|
├── main.go ← Einstiegspunkt. Liest die Konfiguration, prüft die
|
|
│ Pflichtangaben (SESSION_SECRET, ADMIN_TOKEN inkl.
|
|
│ Mindestlänge), öffnet Kontroll-Datenbank und
|
|
│ Workspace-Verwaltung (legt beim ersten Start den
|
|
│ Workspace "Intern" an), setzt die
|
|
│ Bestandteile zusammen und startet den Server.
|
|
│ Enthält außerdem die Server-Timeouts (gegen
|
|
│ Slowloris), die Body-Größenlimits und die
|
|
│ täglichen Aufgaben (Protokoll aufräumen,
|
|
│ Export), die über fuerJedenWorkspace alle
|
|
│ Workspaces erreichen. Tests: main_test.go.
|
|
│
|
|
├── go.mod / go.sum ← Moduldefinition und Prüfsummen der Abhängigkeiten.
|
|
│
|
|
├── Dockerfile ← Zweistufiger Bau: Stufe 1 kompiliert mit dem
|
|
│ Go-Compiler, Stufe 2 packt nur das fertige Binary
|
|
│ in ein minimales Alpine-Abbild. Läuft als
|
|
│ gewöhnlicher Benutzer, mit Healthcheck und Volume
|
|
│ für die Datenbank.
|
|
│
|
|
├── .env.example ← Vorlage für .env, mit Erklärung jeder Variable.
|
|
├── .gitignore / .dockerignore ← Schließen Datenbank, Binary und Geheimnisse aus.
|
|
│
|
|
├── README.md ← Anleitung: Schnellstart, MCP einrichten, Werkzeuge,
|
|
│ Konfiguration, Sicherheit, Betrieb.
|
|
├── AGENTEN-GUIDE.md ← Wie man KI-Werkzeuge anbindet und anspricht,
|
|
│ damit sie den Speicher tatsächlich nutzen:
|
|
│ Projektprompt zum Übernehmen, slug-Regeln,
|
|
│ Muster für einzelne Aufgaben.
|
|
├── AUSBAUSTUFEN.md ← Was bewusst nicht gebaut wurde: Messwerte,
|
|
│ Begründung und die Auslöser, an denen man
|
|
│ merkt, dass es Zeit dafür wird.
|
|
├── REPOMAP.md ← Diese Datei.
|
|
│
|
|
├── internal/
|
|
│ │
|
|
│ ├── store/ ── Die einzige Stelle, die SQL kennt ──────────────
|
|
│ │ ├── store.go ← Öffnet eine Workspace-Datei (Open), setzt die
|
|
│ │ │ nötigen PRAGMAs (WAL, busy_timeout, foreign_keys)
|
|
│ │ │ und wendet die Migrationen an. Erklärt auch, warum
|
|
│ │ │ der Treiber modernc.org/sqlite ist: Er ist reines
|
|
│ │ │ Go und erlaubt damit ein statisches Binary.
|
|
│ │ │
|
|
│ │ ├── control.go ← Die zentrale Kontroll-Datenbank (OpenControl):
|
|
│ │ │ Workspaces anlegen, umbenennen, löschen, dazu die
|
|
│ │ │ Zuordnung Key-Prüfsumme → Workspace
|
|
│ │ │ (ResolveKeyWorkspace). Das ist der erste Schritt
|
|
│ │ │ jeder Anmeldung: Erst danach ist klar, welche
|
|
│ │ │ Workspace-Datei den Key kennt.
|
|
│ │ │
|
|
│ │ ├── models.go ← Die Datentypen (Project, APIKey, Entry, …), die
|
|
│ │ │ Fehlerwerte (ErrNotFound, ErrConflict,
|
|
│ │ │ ErrDuplicate) sowie ID- und Zeitbehandlung.
|
|
│ │ │ NewID erzeugt sortierbare IDs in Go statt per
|
|
│ │ │ AUTOINCREMENT — das hält den Umstieg auf eine
|
|
│ │ │ andere Datenbank offen.
|
|
│ │ │
|
|
│ │ ├── projects.go ← Projekte: anlegen, lesen, ändern, löschen.
|
|
│ │ │ Enthält ValidSlug und Slugify sowie
|
|
│ │ │ SetProjectWriteLimit für die eigene Obergrenze
|
|
│ │ │ eines Projekts.
|
|
│ │ │
|
|
│ │ ├── keys.go ← API-Keys. ResolveKeyHash ist der heißeste Pfad im
|
|
│ │ │ Programm (jeder MCP-Request) und deshalb ein
|
|
│ │ │ indizierter Lookup über die Prüfsumme, keine
|
|
│ │ │ Schleife. Zurückgezogene Keys gelten als nicht
|
|
│ │ │ vorhanden, der Datensatz bleibt fürs Protokoll.
|
|
│ │ │
|
|
│ │ ├── entries.go ← Einträge. PutEntry legt an ODER aktualisiert —
|
|
│ │ │ der Bezeichner entscheidet, und genau das ist der
|
|
│ │ │ Mechanismus gegen Dubletten. Enthält das
|
|
│ │ │ optimistische Sperren (ExpectedVersion) und das
|
|
│ │ │ Nachladen der Schlagworte in einer Abfrage statt
|
|
│ │ │ einer pro Eintrag. Außerdem:
|
|
│ │ │ · snapshotEntryVersion sichert vor jeder Änderung
|
|
│ │ │ die bisherige Fassung, in derselben Transaktion;
|
|
│ │ │ EntryVersions/EntryVersionByNumber lesen sie
|
|
│ │ │ · BulkUpdateTags ändert Schlagworte vieler
|
|
│ │ │ Einträge auf einmal und überspringt IDs aus
|
|
│ │ │ fremden Projekten
|
|
│ │ │ · LinkGraph liefert Knoten und Kanten für die
|
|
│ │ │ Graph-Ansicht
|
|
│ │ │ Jede lesende Abfrage trägt nichtImPapierkorb
|
|
│ │ │ (deleted_at IS NULL) — außer PutEntry, das
|
|
│ │ │ einen Eintrag im Papierkorb bewusst sieht und
|
|
│ │ │ ihn beim Überschreiben zurückholt.
|
|
│ │ │
|
|
│ │ ├── nutzung.go ← Kennzahlen der Nutzungsübersicht: UsageSummaries
|
|
│ │ │ (Schreibvorgänge der letzten 30 Tage aus dem
|
|
│ │ │ Protokoll, Bestand aus entries — für ein oder
|
|
│ │ │ alle Projekte in zwei Abfragen), dazu
|
|
│ │ │ MissingLinks, UntaggedEntries, RecentlyUsedKeys.
|
|
│ │ │ Keine eigene Zähltabelle.
|
|
│ │ │
|
|
│ │ ├── papierkorb.go ← Papierkorb: MoveEntryToTrash (statt DELETE),
|
|
│ │ │ ListTrash, RestoreFromTrash, PurgeFromTrash
|
|
│ │ │ (nur was schon im Papierkorb liegt) und
|
|
│ │ │ PurgeTrash für die tägliche Aufgabe. Die Frist
|
|
│ │ │ TrashRetention (30 Tage) steht hier, damit
|
|
│ │ │ Oberfläche und Aufräumen dieselbe Zahl nutzen.
|
|
│ │ │
|
|
│ │ ├── links.go ← Erkennt [[bezeichner]] im Inhalt und ersetzt sie
|
|
│ │ │ beim Rendern. Das ersetzt die frühere
|
|
│ │ │ Ordnerhierarchie als Struktur zwischen Einträgen.
|
|
│ │ │
|
|
│ │ ├── audit.go ← Protokoll: schreiben, lesen, aufräumen. Die
|
|
│ │ │ Aufbewahrungsfrist ist nicht nur eine Frage des
|
|
│ │ │ Plattenplatzes — das Protokoll enthält Adressen
|
|
│ │ │ und Zugangsnamen. EntryWriteDetail vermerkt bei
|
|
│ │ │ Schreibvorgängen "angelegt" oder "aktualisiert".
|
|
│ │ │
|
|
│ │ ├── migrations_control/
|
|
│ │ │ └── 001_init.sql ← Schema der Kontroll-Datenbank: workspaces und
|
|
│ │ │ key_index (Key-Prüfsumme → Workspace). Bewusst
|
|
│ │ │ dünn — Inhalte liegen nie hier.
|
|
│ │ │
|
|
│ │ └── migrations/ ← Schema jeder Workspace-Datei
|
|
│ │ ├── 001_init.sql ← Das Schema. Der Kopfkommentar nennt die Regeln
|
|
│ │ │ für portables SQL, an die sich alle weiteren
|
|
│ │ │ Migrationen halten sollen.
|
|
│ │ ├── 002_projekt_in_nebentabellen.sql
|
|
│ │ ← Führt project_id auch in entry_tags und
|
|
│ │ entry_links. Eine bewusste Redundanz gegen zwei
|
|
│ │ gemessene Bremsen: das Schlagwortmenü lief über
|
|
│ │ alle Einträge (6,7 ms bei jedem Seitenaufruf),
|
|
│ │ und bei den Rückverweisen kippte durch ein
|
|
│ │ ORDER BY die Verknüpfungsreihenfolge
|
|
│ │ (3,1 ms statt 9 µs).
|
|
│ │ ├── 003_schreibbudget_je_projekt.sql
|
|
│ │ ← Spalte write_limit_hourly an projects. Vorgabe 0
|
|
│ │ heißt "keine eigene Angabe" — dann gilt der
|
|
│ │ Standard aus WRITE_LIMIT_HOURLY. So muss die
|
|
│ │ Migration keine Daten anfassen.
|
|
│ │ ├── 004_aenderungshistorie.sql
|
|
│ │ ← Tabelle entry_versions für abgelöste Fassungen.
|
|
│ │ Wird mit dem Eintrag gelöscht (ON DELETE CASCADE).
|
|
│ │ └── 005_papierkorb.sql
|
|
│ │ ← deleted_at/deleted_by an entries und ein
|
|
│ │ Teilindex nur über den Papierkorb. Löschen setzt
|
|
│ │ nur noch die Markierung; CASCADE greift erst
|
|
│ │ beim endgültigen Löschen.
|
|
│ │
|
|
│ ├── workspace/ ── Welche Datei gehört zu welcher Abteilung? ──────
|
|
│ │ └── workspace.go ← Manager öffnet Workspace-Dateien bei Bedarf und
|
|
│ │ hält sie offen, jeweils mit eigenem Suchindex.
|
|
│ │ Datenbank und Index gehören zusammen, damit kein
|
|
│ │ Index versehentlich an der falschen Datei hängt.
|
|
│ │ Delete schließt eine Datei und entfernt sie.
|
|
│ │
|
|
│ ├── auth/ ── Wer ist das? ────────────────────────────────────
|
|
│ │ ├── doc.go ← Erklärt die beiden Wege hinein (API-Key im Header,
|
|
│ │ │ Sitzungs-Cookie im Browser) und was hier bewusst
|
|
│ │ │ NICHT liegt: die Frage, was jemand darf.
|
|
│ │ │
|
|
│ │ ├── keys.go ← Erzeugen, Prüfsumme bilden, Form prüfen. Enthält
|
|
│ │ │ die Rollen (read/write/admin) und die Begründung,
|
|
│ │ │ warum SHA-256 statt bcrypt richtig ist.
|
|
│ │ │
|
|
│ │ ├── session.go ← Signierte Sitzungs-Cookies (HMAC-SHA256). Der
|
|
│ │ │ Cookie trägt nur eine Behauptung ("ich bin Key X"),
|
|
│ │ │ nie den Key selbst.
|
|
│ │ │
|
|
│ │ ├── csrf.go ← CSRF-Tokens aus Sitzung und Geheimnis, ohne Zustand
|
|
│ │ │ auf dem Server. Der Kopfkommentar erklärt den
|
|
│ │ │ Angriff, gegen den das schützt.
|
|
│ │ │
|
|
│ │ ├── cookies.go ← Setzt HttpOnly, SameSite und Secure an einer
|
|
│ │ │ Stelle. Secure ist ohne Konfiguration an, außer
|
|
│ │ │ bei localhost — damit die lokale Entwicklung über
|
|
│ │ │ http weiter funktioniert.
|
|
│ │ │
|
|
│ │ ├── ratelimit.go ← Zwei Begrenzungen auf einem gemeinsamen
|
|
│ │ │ Fixed-Window-Zähler: RateLimiter sperrt eine
|
|
│ │ │ Adresse nach zu vielen Fehlversuchen,
|
|
│ │ │ WriteBudget deckelt die schreibenden
|
|
│ │ │ MCP-Aufrufe je Projekt und Stunde. Letzteres
|
|
│ │ │ hängt am Projekt und nicht am Key — ein
|
|
│ │ │ Key-Limit ließe sich mit einem zweiten Key
|
|
│ │ │ umgehen.
|
|
│ │ │
|
|
│ │ └── trustedproxy.go ← Entscheidet, wann X-Forwarded-For geglaubt wird:
|
|
│ │ nur bei einer über TRUSTED_PROXY hinterlegten
|
|
│ │ Absenderadresse. Ohne Konfiguration wird der
|
|
│ │ Header ignoriert — er ist frei fälschbar.
|
|
│ │
|
|
│ ├── entry/ ── Wie sieht ein Eintrag aus? ─────────────────────
|
|
│ │ ├── entry.go ← Markdown nach HTML (über internal/markdown),
|
|
│ │ │ Auflösen der [[…]]-Verweise, Textausschnitte für
|
|
│ │ │ Trefferlisten samt sicherer Hervorhebung.
|
|
│ │ │
|
|
│ │ └── diff.go ← Zeilenvergleich zweier Fassungen (DiffLines) als
|
|
│ │ LCS ohne externe Abhängigkeit. Bei sehr langen
|
|
│ │ Einträgen weicht er auf einen groben Vergleich
|
|
│ │ aus (grobDiff), damit Speicher und Rechenzeit
|
|
│ │ begrenzt bleiben.
|
|
│ │
|
|
│ ├── markdown/ ── Markdown nach HTML, eine Regel für alles ───────
|
|
│ │ └── markdown.go ← Der gemeinsame goldmark-Renderer für Einträge und
|
|
│ │ Hilfe: GFM (Tabellen, Checklisten,
|
|
│ │ Durchstreichen, automatische Links), Roh-HTML
|
|
│ │ gesperrt. Nur die Hilfe bekommt Überschrift-
|
|
│ │ Anker (RenderMitAnkern) — mit gefalteten
|
|
│ │ Umlauten über store.Slugify, damit die
|
|
│ │ "?"-Links der Oberfläche darauf zeigen können.
|
|
│ │
|
|
│ ├── export/ ── Sicherung als Markdown ─────────────────────────
|
|
│ │ └── export.go ← Schreibt jeden Workspace als Ordner
|
|
│ │ (<workspace-id>/, mit _workspace.md) und darin
|
|
│ │ jedes Projekt als Ordner voller
|
|
│ │ Markdown-Dateien, mit allen Feldern im Dateikopf.
|
|
│ │ Kennt selbst keine Datenbank: Der Aufrufer gibt
|
|
│ │ die Workspace-Datei je Lauf mit.
|
|
│ │ Gedacht als Git-fähige Sicherung: Ein Lauf ohne
|
|
│ │ inhaltliche Änderungen fasst keine Datei an und
|
|
│ │ erzeugt deshalb auch keinen Diff. Verwaiste
|
|
│ │ Dateien gelöschter Einträge werden entfernt,
|
|
│ │ fremde Dateien im Zielordner bleiben unberührt.
|
|
│ │
|
|
│ ├── search/ ── Volltextsuche ──────────────────────────────────
|
|
│ │ ├── index.go ← Invertierter Index mit BM25-Bewertung. Titel zählen
|
|
│ │ │ dreifach, Schlagworte zweifach. Enthält die
|
|
│ │ │ Präfix-Rückfallebene: Ohne sie findet "deploy"
|
|
│ │ │ den "Deployment-Prozess" nicht — bei einer
|
|
│ │ │ KI-Anfrage ein stiller Fehltreffer.
|
|
│ │ │
|
|
│ │ └── registry.go ← Ein Index je Projekt, verzögert aufgebaut. Getrennte
|
|
│ │ Indizes statt eines gemeinsamen mit Filter: So wird
|
|
│ │ die Abschottung strukturell, und die BM25-Werte
|
|
│ │ werden nicht über Projektgrenzen hinweg verzerrt.
|
|
│ │
|
|
│ ├── hilfe/ ── Eingebaute Onboarding-Hilfe ───────────────────
|
|
│ │ ├── hilfe.go ← Liste der Hilfeseiten (Reihenfolge, Titel) und
|
|
│ │ │ das Rendern mit Überschrift-Ankern. Erklärt,
|
|
│ │ │ warum die Hilfe im Binary steckt statt als
|
|
│ │ │ Einträge in der Datenbank: Sie muss zur
|
|
│ │ │ laufenden Fassung des Programms passen.
|
|
│ │ └── seiten/*.md ← Die Inhalte, je Seite eine Datei. {{SERVER}} und
|
|
│ │ {{PROJEKT}} werden beim Anzeigen ersetzt.
|
|
│ │
|
|
│ ├── web/ ── HTTP: Browser und API ──────────────────────────
|
|
│ │ ├── context.go ← Session-Typ (wer greift zu, was darf er) und die
|
|
│ │ │ Ablage im Request-Context. CanAccessProject ist
|
|
│ │ │ die Mandantentrennung der Weboberfläche.
|
|
│ │ │
|
|
│ │ ├── middleware.go ← Sitzungsprüfung (inkl. "gilt der Key noch?"),
|
|
│ │ │ CSRF, Projektauflösung aus der URL, Rollenprüfung.
|
|
│ │ │ Die Sitzung trägt die Workspace-ID signiert mit
|
|
│ │ │ (sessionFromSubject); requireWorkspace hält einen
|
|
│ │ │ Plattform-Admin ohne gewählten Workspace von den
|
|
│ │ │ Projektseiten fern.
|
|
│ │ │ Dazu die allgemeinen Schutzschichten
|
|
│ │ │ SecurityHeaders und LimitBody sowie APIAuth für
|
|
│ │ │ den MCP-Endpunkt.
|
|
│ │ │
|
|
│ │ ├── server.go ← Der Server-Typ, alle Routen und das Rendern der
|
|
│ │ │ Templates (erst in einen Puffer, dann senden —
|
|
│ │ │ sonst gäbe es bei einem Fehler eine halbe Seite
|
|
│ │ │ mit Status 200).
|
|
│ │ │
|
|
│ │ ├── handlers_auth.go ← Anmelden, Abmelden, Startseite. Der
|
|
│ │ │ Plattform-Admin ohne gewählten Workspace landet
|
|
│ │ │ auf /admin/workspaces.
|
|
│ │ ├── handlers_entries.go ← Einträge auflisten, suchen, ansehen, bearbeiten.
|
|
│ │ │ Dazu Vorschau (preview), Vorschläge für [[…]]
|
|
│ │ │ (suggest), Fassungen und Vergleich, Graph-Daten
|
|
│ │ │ und Schlagworte für viele Einträge (bulk-tags).
|
|
│ │ ├── handlers_nutzung.go ← Nutzungsseite je Projekt (/p/{projekt}/usage),
|
|
│ │ │ für jede Rolle. Die Admin-Projektliste nutzt
|
|
│ │ │ dieselben Zahlen (projectListItems).
|
|
│ │ ├── handlers_papierkorb.go
|
|
│ │ │ ← Papierkorb je Projekt: ansehen, wiederherstellen,
|
|
│ │ │ endgültig löschen, Filter nach löschendem Zugang.
|
|
│ │ │ Alles nur mit Schreibrecht, und bewusst nur hier
|
|
│ │ │ — über MCP gibt es kein Wiederherstellen.
|
|
│ │ ├── handlers_hilfe.go ← Zeigt die eingebauten Hilfeseiten unter /hilfe
|
|
│ │ │ für jede Sitzung. Setzt vorher Server-Adresse
|
|
│ │ │ und Projekt-Bezeichner in die Beispiele ein
|
|
│ │ │ (serverURL, mit geprüftem Host-Header).
|
|
│ │ ├── handlers_workspaces.go
|
|
│ │ │ ← Workspaces auflisten, anlegen, wählen, umbenennen,
|
|
│ │ │ löschen (nur Plattform-Admin). Löscht jemand den
|
|
│ │ │ Workspace der eigenen Sitzung, wird die Auswahl
|
|
│ │ │ zurückgesetzt, statt ihn auszusperren.
|
|
│ │ └── handlers_admin.go ← Projekte, Zugänge, Protokollansicht, Export. Die
|
|
│ │ Bearbeitungsseite je Projekt (Name,
|
|
│ │ Beschreibung, Schreibbudget, Löschen) liegt
|
|
│ │ hier — bewusst eine Seite je Projekt statt
|
|
│ │ eines Auswahlfelds über alle: Nur so stehen die
|
|
│ │ tatsächlichen Werte in den Feldern, und ein
|
|
│ │ Speichern ohne Änderung überschreibt nichts.
|
|
│ │
|
|
│ └── mcpserver/ ── Die Hauptschnittstelle ────────────────────────
|
|
│ ├── server.go ← Handler und Transport (Streamable HTTP), ein
|
|
│ │ MCP-Server je Projekt. Enthält den Text der
|
|
│ │ `instructions` — das wirksamste Stellrad für die
|
|
│ │ Qualität der Antworten, weil er bei jedem Client
|
|
│ │ im Kontext steht.
|
|
│ │
|
|
│ └── tools.go ← Die fünf Werkzeuge: recall, get, list, remember,
|
|
│ forget. Jedes ist eine Closure über genau ein
|
|
│ Projekt und kann strukturell nicht an ein anderes.
|
|
│
|
|
├── templates/ ← HTML der Weboberfläche. partials.html enthält die
|
|
│ gemeinsamen Blöcke "kopf" und "fuss", die jede
|
|
│ Seite einbindet — kein verschachteltes Layout.
|
|
│
|
|
├── static/
|
|
│ ├── style.css ← Das gesamte Aussehen, ohne Framework. Farben als
|
|
│ │ Variablen ganz oben, helle und dunkle Darstellung.
|
|
│ ├── confirm.js ← Bestätigungsabfrage vor dem Löschen. Liest das
|
|
│ │ Attribut data-confirm, statt onclick="" im HTML zu
|
|
│ │ verwenden — Inline-JavaScript verbietet die
|
|
│ │ Content-Security-Policy.
|
|
│ ├── preview.js ← Reiter "Schreiben"/"Vorschau" im Editor. Holt das
|
|
│ │ HTML vom Server, statt Markdown im Browser zu
|
|
│ │ rendern. Ohne JavaScript bleibt das Formular
|
|
│ │ unverändert nutzbar.
|
|
│ ├── autocomplete.js ← Vorschläge nach "[[" im Textfeld, per Tastatur
|
|
│ │ und Maus bedienbar.
|
|
│ ├── graph.js ← Selbst geschriebene Kräftesimulation und
|
|
│ │ SVG-Darstellung für die Graph-Ansicht. Texte nur
|
|
│ │ über textContent, nie innerHTML.
|
|
│ └── img/ ← Logo in mehreren Fassungen (hell, dunkel, ohne
|
|
│ Hintergrund). Die Anmeldeseite wählt je nach
|
|
│ Farbschema die passende.
|
|
│
|
|
├── scripts/
|
|
│ └── backup.sh ← Sichert control.db und jede Workspace-Datei
|
|
│ einzeln über sqlite3 .backup in einen
|
|
│ zeitgestempelten Ordner; RETENTION_DAYS räumt
|
|
│ alte Sicherungen auf.
|
|
│
|
|
└── data/ ← Daten (nicht im Repository, als Volume gemountet)
|
|
├── control.db ← Kontroll-Datenbank: Workspaces, Key-Zuordnung
|
|
└── workspaces/
|
|
└── <workspace-id>.db ← Eine Datei je Workspace
|
|
```
|
|
|
|
## Tests
|
|
|
|
Jedes Package hat seine Tests direkt daneben. Sie laufen mit `go test ./...` ohne
|
|
weitere Vorbereitung — die Datenbanktests legen jeweils eine echte SQLite-Datei
|
|
in einem Testverzeichnis an, damit auch Migrationen und Fremdschlüssel geprüft
|
|
werden.
|
|
|
|
| Datei | Schwerpunkt |
|
|
|---|---|
|
|
| `internal/auth/auth_test.go` | Signatur, Manipulation, Ablauf, CSRF, Key-Form, Rollen, Cookie-Flags, Rate-Limiting, X-Forwarded-For |
|
|
| `internal/store/nutzung_test.go` | Zählung nach Art und Weg samt Zeitfenster, Bestand ohne Papierkorb, Verweise ins Leere, aktive Zugänge |
|
|
| `internal/store/papierkorb_test.go` | **Jeder lesende Weg blendet den Papierkorb aus** (Einzelabruf, Liste mit Filtern, Suchindex/Export, Zählen, Schlagworte, Rückverweise, Graph, Sammelbearbeitung); Wiederherstellen, Zurückholen durch Überschreiben, Konflikt, endgültiges Löschen, Frist |
|
|
| `internal/store/store_test.go` | Migrationen, Slug-Prüfung, Abschottung, Dublettenvermeidung, optimistisches Sperren, Verweise, Protokoll, Änderungshistorie |
|
|
| `internal/store/control_test.go` | Kontroll-Datenbank: Standard-Workspace bleibt stabil, Auflistung, Zuordnung Key → Workspace |
|
|
| `internal/workspace/workspace_test.go` | Manager hält Dateien offen, trennt Workspaces, schließt sauber |
|
|
| `internal/entry/entry_test.go` | HTML-Escaping, Verweisauflösung, Textausschnitte, sichere Hervorhebung |
|
|
| `internal/markdown/markdown_test.go` | GFM-Erweiterungen, kein Roh-HTML und keine `javascript:`-Links, Anker nur in der Hilfe |
|
|
| `internal/entry/diff_test.go` | Zeilenvergleich, Grenzfälle, Ausweichen bei sehr langen Einträgen |
|
|
| `internal/search/search_test.go` | Bewertung, Präfix-Rückfallebene, Aktualisieren und Entfernen |
|
|
| `internal/export/export_test.go` | Dateikopf und YAML-Maskierung, Aufräumen verwaister Dateien, Stabilität über mehrere Läufe |
|
|
| `internal/web/web_test.go` | Anmeldung, zurückgezogene Keys, CSRF, **Projektabschottung**, **Workspace-Trennung**, Rollen, Header, Hilfeseiten samt eingesetzter Adresse |
|
|
| `internal/mcpserver/mcpserver_test.go` | Werkzeugbestand, `instructions`, Dublettenvermeidung, Konflikte, Rollen, **Projektabschottung** |
|
|
| `internal/hilfe/hilfe_test.go` | Seitenliste und Dateien passen zusammen, interne Links führen zu vorhandenen Seiten, kein Roh-HTML |
|
|
|
|
## Datenfluss: Agent ruft Wissen ab
|
|
|
|
```
|
|
KI-Werkzeug POST /mcp { "method": "tools/call", "params": { "name": "recall", … } }
|
|
→ web/middleware.go (SecurityHeaders, LimitBody)
|
|
→ web/middleware.go (APIAuth) Key → Prüfsumme
|
|
→ store/control.go (ResolveKeyWorkspace) → Workspace
|
|
→ workspace/workspace.go (Get) → dessen Datei und Suchindex
|
|
→ store/keys.go (ResolveKeyHash) → Projekt + Rolle
|
|
in den Context; Fehlversuche in die Sperre
|
|
→ mcpserver/server.go (ServeHTTP) Projekt aus dem Context → dessen MCP-Server
|
|
→ mcpserver/tools.go (recall)
|
|
→ search/registry.go Index dieses Projekts (beim ersten Mal
|
|
aus der Datenbank aufgebaut)
|
|
→ search/index.go (Search) BM25, bei Bedarf Präfix-Rückfallebene
|
|
→ store/entries.go (EntryBySlug) Treffer nachladen
|
|
→ entry/entry.go (Snippet) Textausschnitt je Treffer
|
|
→ JSON-Antwort mit Trefferliste und Hinweis zum weiteren Vorgehen
|
|
```
|
|
|
|
## Datenfluss: Agent legt Wissen ab
|
|
|
|
```
|
|
KI-Werkzeug POST /mcp { … "name": "remember", "arguments": { "slug": …, "content": … } }
|
|
→ web/middleware.go (APIAuth) wie oben
|
|
→ mcpserver/tools.go (remember)
|
|
→ requireWrite() Rolle read wird hier abgewiesen
|
|
→ store/entries.go (PutEntry) eine Transaktion:
|
|
· Bezeichner vorhanden? → aktualisieren
|
|
· ExpectedVersion prüfen → ggf. Konflikt
|
|
· Schlagworte und Verweise ersetzen
|
|
· Herkunft (agent) und Zugangsname setzen
|
|
→ search/registry.go (Update) Index nachziehen
|
|
→ store/audit.go (LogAudit) wer, was, wann
|
|
→ Antwort: Bezeichner, neue Fassung, angelegt oder aktualisiert
|
|
```
|
|
|
|
## Datenfluss: Mensch bearbeitet im Browser
|
|
|
|
```
|
|
Browser POST /p/plattform/e/deployment/save
|
|
→ web/middleware.go (SecurityHeaders, LimitBody)
|
|
→ web/middleware.go (requireSession) Cookie prüfen → Key aus der Datenbank
|
|
laden → gilt er noch? → CSRF-Token prüfen
|
|
→ web/middleware.go (requireProject) Projekt aus der URL; fremdes Projekt → 404
|
|
→ web/middleware.go (requireWrite) Rollenprüfung
|
|
→ web/handlers_entries.go (handleEntrySave)
|
|
→ store/entries.go (PutEntry) Herkunft: human, Autor: Key-Name
|
|
→ search/registry.go (Update)
|
|
→ store/audit.go (LogAudit)
|
|
→ Weiterleitung zur Detailansicht
|
|
```
|