Add a Prompts library alongside Links, bump to v2.0.0

New /prompts section extends the existing database (new Prompt model,
same SQLite file) and mirrors the Links experience: add a prompt, get
it auto-categorized and tagged by AI, filter by category, full-text
search, sort, edit, or have the AI re-categorize it. A header nav
switch ("Links" / "Prompts") toggles between the two collections; the
shared topbar/menu markup was factored into _topbar.html and
_topbar_actions.html so both pages (and settings) stay in sync.

Each prompt card has a dedicated copy-to-clipboard icon next to
edit/delete, so a stored prompt can be reused immediately. Copying
uses the raw markdown source (not the rendered HTML) so structure
survives when pasted into another AI tool. The copy handler tries the
async Clipboard API first and falls back to a hidden-textarea +
execCommand('copy') for plain-http/non-secure contexts, with clear
success/failure icon feedback either way.

Prompt content supports Markdown and is rendered server-side
(app/mdrender.py) for the card preview. Since this is user-supplied
HTML-adjacent content, rendering goes through two defenses: the raw
text is escaped (only '<' and '&', not '>', so blockquotes keep
working) before conversion so no raw tag can survive, and the
resulting HTML is passed through bleach with a tag/attribute/protocol
allowlist so Markdown-generated links can't carry a javascript: URL.
Verified against raw <script>, <img onerror>, and javascript: link
payloads. The edit form always shows the raw Markdown source, never
the rendered HTML.

Also bumps the default APP_VERSION (shown in the footer) from 1.0.0
to 2.0.0 to mark this feature addition.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-07-30 14:45:30 +02:00
parent 7262aee63d
commit 78c95b522d
18 changed files with 785 additions and 77 deletions

View File

@@ -1,24 +1,40 @@
# LinkVault
KI-gestützte Link-Sammlung: Links einfügen → automatisch laden, **zusammenfassen**,
in **Kategorien / Hersteller** einsortieren und schnell **wiederfinden**.
KI-gestützte Sammlung für **Links** und **Prompts**: eingeben → automatisch
**kategorisieren**, in **Kategorien / Hersteller / Tags** einsortieren und
schnell **wiederfinden**. Beide Sammlungen laufen in derselben App und
Datenbank, per Menü umschaltbar.
## Funktionen
- 🔗 **Link hinzufügen** Seite wird geladen und der Textinhalt extrahiert.
- 🤖 **Automatische KI-Analyse** (OpenAI) Titel, Zusammenfassung, Kategorie,
Hersteller/Quelle und Tags werden erzeugt. Bestehende Kategorien werden
wiederverwendet, damit die Sammlung konsistent bleibt.
-**Bearbeiten** Titel, Zusammenfassung, Kategorie, Hersteller und Tags
lassen sich jederzeit manuell anpassen. Alternativ kann die KI den Link
**neu beschreiben**: die Seite wird erneut geladen und alle Felder werden
neu erzeugt.
- 🗂️ **Filtern** nach Kategorie und Hersteller über die Seitenleiste.
- 🔍 **Suche** klassische Textsuche und optionale **semantische KI-Suche**
(findet auch sinnverwandte Treffer via Embeddings).
- **Prompt hinzufügen** eigener Bereich für KI-Prompts, per Kopf-Menü
zwischen „Links" und „Prompts" umschaltbar. Prompts werden ebenfalls
automatisch kategorisiert und getaggt, lassen sich per Kategorie/Volltext
durchsuchen und mit einem Klick in die Zwischenablage kopieren. Der
Prompt-Text unterstützt **Markdown** (Überschriften, Listen, Fett/Kursiv,
Codeblöcke, Zitate) in der Karten-Vorschau wird das gerendert, beim
Kopieren landet der rohe Markdown-Text (für Struktur in der Ziel-KI) in
der Zwischenablage.
- 🤖 **Automatische KI-Analyse** (OpenAI) Titel, Zusammenfassung/Kategorie
und Tags werden erzeugt. Bestehende Kategorien werden wiederverwendet,
damit die Sammlung konsistent bleibt.
-**Bearbeiten** alle Felder lassen sich jederzeit manuell anpassen.
Alternativ kann die KI Links/Prompts **neu beschreiben bzw. neu
kategorisieren** lassen.
- 🗂️ **Filtern** nach Kategorie (Links zusätzlich nach Hersteller) über die
Seitenleiste.
- 🔍 **Suche** klassische Textsuche, bei Links zusätzlich optionale
**semantische KI-Suche** (findet auch sinnverwandte Treffer via
Embeddings).
- ↕️ **Sortieren** nach Datum (neueste/älteste zuerst) oder Name (AZ / ZA).
- 🕓 **Hinzufügedatum** wird pro Link angezeigt.
- 👥 **Mehrbenutzer** Registrierung/Login, jeder Nutzer sieht nur seine Links.
- 🔖 **Merkliste** Links lassen sich zur späteren Durchsicht markieren.
- 🕓 **Hinzufügedatum** wird pro Eintrag angezeigt.
- 📤 **Export/Import** (Einstellungen) Links als CSV oder SQL-Dump
exportieren, SQL-Dump auch wieder importieren.
- 🌗 **Dark/Light-Modus** über den Umschalter im Kopfbereich.
- 👥 **Mehrbenutzer** Registrierung/Login, jeder Nutzer sieht nur seine
eigenen Links und Prompts.
Die Fußzeile zeigt Autor, Version und den Hostnamen des Servers. Die Version
lässt sich über `APP_VERSION` in der `.env` setzen.
@@ -59,14 +75,16 @@ uvicorn app.main:app --reload --port 8000
```
app/
main.py FastAPI-App, Routen, Auth-Sessions
main.py FastAPI-App, Routen (Links & Prompts), Auth-Sessions
config.py Konfiguration aus .env
database.py SQLAlchemy Engine/Session
models.py User- und Link-Modelle
models.py User-, Link- und Prompt-Modelle
security.py Passwort-Hashing (bcrypt)
scraper.py Seiteninhalt laden & extrahieren
ai.py OpenAI: Kategorisierung, Zusammenfassung, Embeddings
search.py Semantische Suche (Kosinus-Ähnlichkeit)
scraper.py Seiteninhalt laden & extrahieren (nur Links)
ai.py OpenAI: Kategorisierung (Links & Prompts), Embeddings
search.py Semantische Suche (Kosinus-Ähnlichkeit, nur Links)
backup.py CSV-/SQL-Export und sicherer SQL-Import (nur Links)
mdrender.py Sicheres Markdown-Rendering für Prompt-Inhalte
templates/ Jinja2 + HTMX Oberfläche
```