diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index f221edd..7b683cc 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -28,11 +28,12 @@ 14. [Cronjob-System](#cronjob-system) 15. [Krea-Bildgenerierung](#krea-bildgenerierung) 16. [Auth & Multi-User](#auth--multi-user) -17. [Workspace & File-Explorer](#workspace--file-explorer) -18. [Windows Desktop App](#windows-desktop-app) -19. [Deployment](#deployment) -20. [Konfiguration](#konfiguration) -21. [Datenbank-Migrationen](#datenbank-migrationen) +17. [Nachrichten teilen (Shared Messages)](#nachrichten-teilen-shared-messages) +18. [Workspace & File-Explorer](#workspace--file-explorer) +19. [Windows Desktop App](#windows-desktop-app) +20. [Deployment](#deployment) +21. [Konfiguration](#konfiguration) +22. [Datenbank-Migrationen](#datenbank-migrationen) --- @@ -102,6 +103,7 @@ gott/ │ ├── ArchiveRecord.cs │ ├── CronjobRecord.cs │ ├── KreaImageRecord.cs +│ ├── SharedMessageRecord.cs # Geteilte Nachrichten (Share-Token) │ ├── ChatModels.cs # ChatMessage, ChatRequest, AttachmentInfo/Block │ └── ChatContext.cs # Runtime-Kontext für einen Chat │ @@ -131,6 +133,7 @@ gott/ │ ├── CronjobEndpoint.cs # CRUD + Toggle, Manual Run │ ├── KreaEndpoint.cs # Generate, List, File-Serve │ ├── SkillEndpoint.cs # List, Agent-Skill-Mapping, Output-Files +│ ├── SharedEndpoint.cs # Nachrichten teilen (öffentliche Links) │ ├── ProfileEndpoint.cs # Profil, Persona, Passwort │ ├── SettingsEndpoint.cs # User-Settings (JSON blob) │ ├── BackupEndpoint.cs # Backup als tar.gz Download @@ -187,7 +190,8 @@ gott/ │ │ │ ├── cronjob-page.js # Cronjob-Verwaltung │ │ │ ├── profile-page.js # Profil-Bearbeitung │ │ │ ├── settings-page.js # App-Einstellungen -│ │ │ └── login-page.js # Login-Formular +│ │ │ ├── login-page.js # Login-Formular +│ │ │ └── shared-page.js # Öffentliche geteilte Nachricht │ │ └── lib/ # Vendor-Libraries │ │ ├── marked.min.js # Markdown Parser │ │ ├── codemirror.min.js # Code Editor @@ -239,6 +243,8 @@ Chain (1) ─── (*) Message Message (1) ─── (*) Attachment Session (1) ─── (*) Cronjob User (1) ─── (*) Cronjob +User (1) ─── (*) SharedMessage +Message (1) ─── (*) SharedMessage ``` ### Tabellen @@ -255,6 +261,7 @@ User (1) ─── (*) Cronjob | `archives` | Archivierte Chain-Gruppen | | `agent_skills` | Agent ↔ Skill Zuordnung | | `cronjobs` | Geplante Tasks (cron expression, prompt) | +| `shared_messages` | Geteilte Nachrichten (Share-Token, Ablaufdatum) | | `telegram_links` | Telegram Chat ↔ Session Verknüpfung | ### Zentrale Records @@ -289,7 +296,7 @@ Die `Program.cs` ist der zentrale Einstiegspunkt und konfiguriert: 2. **Datenbank-Initialisierung** – `DatabaseService` erstellt Schema + Migrationen 3. **Default-User** – Wird automatisch angelegt falls keine User existieren 4. **Middleware** – Static Files → `AuthMiddleware` → Endpoints -5. **Endpoint-Mapping** – Alle 14 Endpoint-Gruppen registriert +5. **Endpoint-Mapping** – Alle 15 Endpoint-Gruppen registriert 6. **Server** – Kestrel auf `http://0.0.0.0:19000` Initialisierungsreihenfolge: @@ -338,6 +345,7 @@ Alle Endpoints folgen dem **Minimal API**-Pattern mit Extension Methods (`MapXxx | **Profile** | `/api/profile` | `GET`, `PUT`, `PUT password` | | **Settings** | `/api/settings` | `GET`, `PUT` | | **Backup** | `/api/backup` | `POST` (Admin only, tar.gz Download) | +| **Shared** | `/api/shared/`, `/api/messages/{id}/share` | Share erstellen, öffentlich abrufen, auflisten, löschen | | **Info** | `/api/info` | `GET` (Build-Zeitstempel) | ### Middleware @@ -348,6 +356,7 @@ Ausnahmen (kein Auth nötig): - Statische Dateien (nicht `/api/`) - `POST /api/auth/login` - `POST /api/telegram/webhook/{sessionId}` (authentifiziert via Secret-Header) +- `GET /api/shared/{token}` (öffentlicher Zugriff auf geteilte Nachrichten) Bei Erfolg werden `UserId` und `IsAdmin` in `HttpContext.Items` gesetzt. @@ -389,6 +398,7 @@ Das Frontend ist eine **Single-Page Application** ohne Build-Step, komplett in V | `#/profile` | `profile-page.js` | Profil | | `#/settings` | `settings-page.js` | App-Einstellungen | | `#/login` | `login-page.js` | Login | +| `#/shared/{token}` | `shared-page.js` | Öffentliche geteilte Nachricht (kein Auth) | ### Kern-Module @@ -757,6 +767,48 @@ Jeder User hat eine optionale **Persona** – ein Freitext der beschreibt wer er --- +## Nachrichten teilen (Shared Messages) + +Einzelne Nachrichten oder ganze Threads können als **öffentliche Links** geteilt werden – ohne Login aufrufbar. + +### Datenmodell + +**Tabelle `shared_messages`:** +| Spalte | Typ | Beschreibung | +|------------------|---------|-------------------------------------------| +| `id` | INTEGER | Primary Key | +| `share_token` | TEXT | UUID – öffentlicher Zugangsschlüssel | +| `message_id` | INTEGER | FK auf `messages.id` | +| `user_id` | INTEGER | Wer hat geteilt | +| `include_context`| INTEGER | 0 = Einzelnachricht, 1 = Thread bis dahin | +| `created_at` | TEXT | Erstellzeitpunkt | +| `expires_at` | TEXT | Optional: Ablaufdatum | + +### API-Endpunkte (`SharedEndpoint.cs`) + +| Methode | Route | Auth | Beschreibung | +|----------|--------------------------------|------|---------------------------------------| +| `POST` | `/api/messages/{id}/share` | ✅ | Share erstellen (Body: `{includeContext}`) | +| `GET` | `/api/shared/{token}` | ❌ | Öffentlich: Geteilte Nachricht abrufen | +| `GET` | `/api/shared` | ✅ | Eigene Shares auflisten | +| `DELETE` | `/api/shared/{token}` | ✅ | Share-Link widerrufen | + +### Frontend-Flow + +1. **Share-Button** (🔗) erscheint an jeder Nachricht im Chat (neben Reply, Delete, Mark) +2. Klick öffnet **Kontext-Menü**: "Einzelne Nachricht" oder "Thread teilen" +3. `POST /api/messages/{id}/share` → Token zurück → URL in Zwischenablage kopiert +4. **Toast**: "Link kopiert!" + +### Öffentliche Ansicht (`#/shared/{token}`) + +- Route `#/shared/{token}` → `shared-page.js` +- **Kein Auth nötig** – Auth-Bypass in `app.js` + `AuthMiddleware` +- Minimales Layout: Header ("// gott · Geteilte Nachricht"), Nachrichten mit Markdown-Rendering +- Zwei Modi: `single` (eine Nachricht) oder `context` (Thread mit User/Assistant-Wechsel) + +--- + ## Workspace & File-Explorer ### Workspace diff --git a/ARCHITECTURE_QUICK.md b/ARCHITECTURE_QUICK.md index b0fa745..c9cb54f 100644 --- a/ARCHITECTURE_QUICK.md +++ b/ARCHITECTURE_QUICK.md @@ -46,6 +46,7 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At Agent *──* Skill (via agent_skills) Session 1──* Cronjob Session 1──* Archive + User 1──* SharedMessage ──1 Message ``` | Tabelle | Zweck | @@ -60,6 +61,7 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At | `archives` | Archivierte Chain-Gruppen | | `cronjobs` | Geplante Tasks (Cron-Expression + Prompt) | | `agent_skills` | N:M Agent ↔ Skill | +| `shared_messages` | Geteilte Nachrichten (öffentliche Links via Share-Token) | | `telegram_links` | Telegram Chat-ID ↔ Session | --- @@ -81,6 +83,7 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At | Profile | `/api/profile` | GET, PUT, password | | Settings | `/api/settings` | GET, PUT (JSON blob) | | Backup | `/api/backup` | POST → tar.gz download (Admin) | +| Shared | `/api/shared/`, `/api/messages/{id}/share` | Share erstellen, öffentlich abrufen, löschen | | Info | `/api/info` | GET → Build-Zeitstempel | --- @@ -177,6 +180,7 @@ User-Input → POST /api/chat (SSE) | `#/profile` | `profile-page.js` | Profil | | `#/settings` | `settings-page.js` | Einstellungen | | `#/login` | `login-page.js` | Login | +| `#/shared/{token}` | `shared-page.js` | Geteilte Nachricht (öffentlich, kein Auth) | --- @@ -184,7 +188,7 @@ User-Input → POST /api/chat (SSE) 1. `POST /api/auth/login` → Token generiert, als `gott_token` HttpOnly Cookie gesetzt 2. Jeder `/api/`-Request → `AuthMiddleware` prüft Cookie → setzt `UserId` + `IsAdmin` -3. Ausnahmen: Login + Telegram-Webhook brauchen kein Auth +3. Ausnahmen: Login, Telegram-Webhook und `GET /api/shared/{token}` brauchen kein Auth --- diff --git a/TODO.md b/TODO.md index 75af2cb..ebabcbf 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,8 @@ - [x] Weiteres Modell hinzufügen: "Haiku 4.5" - [x] Weitere Tools: Glob? Search? Todo List? - [x] Settings in Datenbank speichern (users table) anstelle von localStorage -- [ ] Einzelne Nachicht als Link teilen +- [x] Einzelne Nachicht als Link teilen +- [ ] Geteilite Links verwalten (löschen) ## Bugs - [x] Wenn gerade gestreamt wird und man refreshed die Seite, dann verliert das Frontend den Status "Streaming..." und ich kann eine Nachricht schreiben, obwohl das nicht möglich sein sollte