38 KiB
38 KiB
📋 MindSift – Projekt-TODOs
Zweck & Kontext:
Diese Datei enthält strukturierte, technische Arbeitsaufträge und Feature-Spezifikationen für ausführende Entwickler- und Agenten-KIs.
Sie wird fortlaufend gepflegt, priorisiert und mit konkreten Implementierungsdetails angereichert.
📱 Frontend – Mobile Version
Aufgaben, UI/UX und Touch-Optimierungen für Smartphones & Tablets.
🖥️ Frontend – Desktop Version
UI/UX, Tastatur-Shortcuts, Layouts und Ansichten für Desktop-Browser.
⚙️ Backend & Schnittstellen
Go-Services, SQLite-Persistenz, REST/WebSocket-Endpunkte und Hintergrundjobs.
Allgemein / Core
Mobile-spezifisch
- (Aktuell keine offenen Aufgaben)
Desktop-spezifisch
- (Aktuell keine offenen Aufgaben)
💡 Konzept, UX & Planung
Architektur, UI-Guidelines und systemübergreifende Entscheidungen.
- Anmeldung per OpenID Connect (zurückgestellt, aktuell kein Bedarf) – Login über Gitea, Authentik, Google & Co. Ausgearbeitet in Doku/plans/registrierung-und-login.md, Abschnitt 4.
📋 Organisation & Dokumentation
Tickets, Dokumentation, Release-Vorbereitungen und DevOps/Deployment.
📦 Verschiedenes / Backlog
Unsortierte Notizen, vage Ideen und Sonstiges.
✅ Erledigt
Abgeschlossene Aufgaben und Features mit Referenz.
- Theme-Manager in den Benutzereinstellungen (Upload & CSS-Editor im WordPress-Stil) (Commit
bf0d68e)- Theme-Upload (
.css-Dateien), Copy-Paste von CSS, Vorlagen-Download/Kopieren, dynamische Live-Injection via<style id="mindsift-custom-theme">und Einbindung in die Theme-Galerie.
- Theme-Upload (
- Persistenz für benutzerdefinierte Themes in SQLite & API-Endpunkte (Commit
bf0d68e)- SQLite-Tabelle
user_themesund REST-Endpunkte (GET / POST / DELETE /api/v1/themes) für persistente Custom-Themes pro Benutzer.
- SQLite-Tabelle
- Admin-Einstellungen: Checkboxen für SMTP durch Toggle-Switches ersetzen (Commit
ce321ce)- SMTP-Haken sind Toggle-Switches (
ToggleSwitch), neuer Schalter „Zertifikatsprüfung deaktivieren“.
- SMTP-Haken sind Toggle-Switches (
- SMTP-Client & E-Mail-Alarme härten (Fix:
451 4.3.2 Internal server error) (Commitce321ce)- Expliziter SMTP-Ablauf mit Fehlerangabe pro Schritt (
smtp_step), EHLO mit Absender-Domain, nackte Adresse im Umschlag,Date/Message-ID, kodierter Betreff; Tests gegen Fake-SMTP-Server.
- Expliziter SMTP-Ablauf mit Fehlerangabe pro Schritt (
- Option zur Deaktivierung der TLS-Zertifikatsprüfung für SMTP (
smtpSkipVerify) (Commitce321ce)SMTP_SKIP_VERIFYin Config, Systemeinstellungen und Admin-UI; gilt für Port 465 und STARTTLS.
- Zentrale
CountBadge-Komponente & einheitliches Theming schaffen (Commita62b204)CountBadge(accent/muted, inline/corner, 99+) für Navigation, Tabs, Admin und mobiles Menü;badge-countentfernt; Vorlage leitet Akzent-Töne aus der Akzentfarbe ab.
- Aufgaben-Counter im mobilen Listen-Menü für „Alle Aufgaben" ergänzen (Commit
a62b204)- „Alle Aufgaben“ zeigt im mobilen Menü die Zahl offener Aufgaben (inkl. geteilter Listen).
- Aufgaben-Counter im Tab „Alle Aufgaben" anzeigen (Commit
a62b204)- Zähler am Tab; Backend zählt offene Aufgaben jetzt wie die Ansicht „Alle Aufgaben“ (auch fremde Aufgaben in geteilten Listen).
- Badge-Positionierung in Tabs an Titelleiste/App-Icons angleichen (Top-Right) (Commit
a62b204)- Zähler sitzen oben rechts an den Tabs der Aufgabenlisten und Listen.
- Impressum- & Datenschutz-Links im Login- und Einstellungs-Footer (mit Auto-Hide) (Commit
d6c70d7)- Links unter der Anmelde-/Einrichtungsbox und im Footer der Kontoeinstellungen (
LegalLinks): URL im neuen Tab, Markdown im Lesefenster, unsichtbar ohne Konfiguration.
- Links unter der Anmelde-/Einrichtungsbox und im Footer der Kontoeinstellungen (
- Konfigurierbare Rechtstexte (Impressum & Datenschutz via ENV) (Commit
d6c70d7)LEGAL_IMPRINT_/PRIVACY_URLund…_CONTENT(auch…_CONTENT_FILE), nurhttp(s)-URLs;legalin/auth/status, öffentlichGET /api/v1/legal/{imprint|privacy}.
- „Über MindSift"-Bereich mit Versionsinfo & GitHub-Link (Commit
d6c70d7)- Fenster „Über MindSift“ (Version, Lizenz, Philosophie, Repository-Link) aus Kontoeinstellungen und Hilfe; Link/Lizenz als Konstanten in
AboutModal.tsx(Repo zeigt auf git.dsit.me, Lizenz noch nicht festgelegt).
- Fenster „Über MindSift“ (Version, Lizenz, Philosophie, Repository-Link) aus Kontoeinstellungen und Hilfe; Link/Lizenz als Konstanten in
- Markdown-Tree-Export als direktes Streaming-ZIP (Obsidian-kompatibel) (Commit
e509f68)GET /api/v1/export/markdownstreamt die ZIP ohne Temp-Dateien: Ordnerstruktur wie im Workspace (inkl. geteilter), YAML-Frontmatter, Obsidian-taugliches Markdown,Aufgaben/im Tasks-Plugin-Format,Listen/.
- Globale Schnellsuche & Spotlight-Palette (
Cmd+K/Ctrl+K) (Commit71fa53e)- Gemini; gemergt in
a044620, geprüft (Zugriff, Cmd+K, Enter öffnet). Markierungsfarbe ina62b189ans Theme angepasst.
- Gemini; gemergt in
- Volltextsuche auf SQLite FTS5 (Full-Text Search) umstellen (Commit
71fa53e)- Gemini; FTS5 mit Triggern, Backfill, BM25, Snippets, Zugriffsprüfung je Typ; gemergt in
a044620.
- Gemini; FTS5 mit Triggern, Backfill, BM25, Snippets, Zugriffsprüfung je Typ; gemergt in
- Vollständige Emoji-Bibliothek für Notizen-Header einbinden (Commit
633bd6f)- Gemini;
emoji-picker-react4.12.0, lazy geladen; gemergt ina044620.
- Gemini;
- Emoji-Modal für Notiz-Icon responsiv & tastatur-optimiert umbauen (Commit
633bd6f)- Gemini; mobiles Bottom-Sheet mit Autofokus und großen Touch-Zielen; gemergt in
a044620.
- Gemini; mobiles Bottom-Sheet mit Autofokus und großen Touch-Zielen; gemergt in
- Demo-Modus: Automatischer Reset der Datenbank bei jedem Serverstart (Commit
9c6598c)- Gemini; Reset nur bei aktivem Demo-Modus (getestet), nutzt die gemeinsame Drop-Funktion; gemergt in
a044620.
- Gemini; Reset nur bei aktivem Demo-Modus (getestet), nutzt die gemeinsame Drop-Funktion; gemergt in
- SMTP:
AUTH LOGIN-Fallback & alternative SASL-Authentifizierung implementieren (Commitd8a16c6)AUTH LOGINdirekt, wenn nur LOGIN angeboten wird; nach abgelehntem PLAIN neue Verbindung mit LOGIN (net/smtp schließt nach gescheitertem AUTH). Scheitern beide mit 451, nennt die Meldung beide Versuche und verweist auf das SASL-Backend des Mailservers. Tests mit Fake-Server.
- Markdown-Tree-Import aus ZIP (Obsidian-Vault-Support) (Commit
1601a6a)- Zwei Wege:
POST /import/mindsift(JSON-Backup oder MindSift-Archiv, Rundreise inkl. Aufgaben/Listen/Triage) undPOST /import/obsidian(Vault in eigenen Ordner, Checkboxen bleiben, Tags → #Hashtags). Vorschau mit?preview=1, Grenzen gegen ZIP-Bomben und..-Pfade, Tests.
- Zwei Wege:
- UI für Obsidian- / Markdown-Tree Backup-Export und ZIP-Import integrieren (Commit
1601a6a)- Export-Button (
e509f68) und zwei Import-Karten „MindSift-Daten“ / „Obsidian-Vault“ mit Drag & Drop, Vorschau, Bestätigen und Ergebnis (inkl. übersprungener Dateien).
- Export-Button (
- Mobile Unterstützung für Backup-Download & ZIP-Import (Commit
1601a6a)- Download hängt den Link ins Dokument und gibt die URL verzögert frei (mobil getestet); Datei-Buttons mit 44 px Touch-Höhe,
accept=".json,.zip"; Import mobil im Browser geprüft.
- Download hängt den Link ins Dokument und gibt die URL verzögert frei (mobil getestet); Datei-Buttons mit 44 px Touch-Höhe,
- PWA Splash-Screen & Ladebildschirm: Vollflächig Blau mit zentriertem Logo (Commit
9bc8716)- Manifest mit kurzem Namen und
#2563eb; blauer HTML-Platzhalter mit Logo in#rootbis React startet (ohne JS geprüft);theme-colorstartet blau und folgt danach dem Theme. iOS-Startbilder (apple-touch-startup-image) gibt es weiterhin nicht.
- Manifest mit kurzem Namen und
- Eingabefeld für API-Key-Namen auf mobilen Geräten vergrößern (Commit
0e9fd1b)- Feld und Button mobil 44 px, Schrift 16 px; Ursache war
flex-1im untereinander gestapelten Layout, das die Höhe auf den Inhalt schrumpfte.
- Feld und Button mobil 44 px, Schrift 16 px; Ursache war
- Admin-Settings: SMTP-Port-Eingabe reparieren & Typen-Mismatch beheben („Ungültiges JSON“) (Commit
a3a7094)- Port als Text (nur Ziffern) im Formular, lässt sich leeren; Server akzeptiert Zahl oder Text (
SystemSettings.UnmarshalJSON), getestet.
- Port als Text (nur Ziffern) im Formular, lässt sich leeren; Server akzeptiert Zahl oder Text (
- MindSift-Backup-Import: Modus-Auswahl „Hinzufügen“ vs. „Wiederherstellen (Alles überschreiben)“ (Commit
0e9fd1b)- „Hinzufügen“ / „Wiederherstellen“ mit Warnung und Pflicht-Haken;
?mode=restorelöscht die eigenen Daten erst nach vollständiger Prüfung der Datei, in einer Transaktion.
- „Hinzufügen“ / „Wiederherstellen“ mit Warnung und Pflicht-Haken;
- Gefahrenzone in Benutzereinstellungen: „Alle Daten löschen“ & „Konto löschen“ (Commit
0e9fd1b)- „Daten löschen“ und „Konto löschen“ im Bereich Profil & Sicherheit, beide mit Passwort; Konto-Button für den letzten Admin deaktiviert mit Hinweis; nach Kontolöschung Abmeldung zur Login-Seite.
- Selbstbedienung: Daten löschen & Konto löschen (inkl. Schutz für letzten Admin) (Commit
0e9fd1b)DELETE /user/data,DELETE /user/account(Passwort nötig, 403 für letzten Admin);PurgeUserDatain einer Transaktion, Aufgaben anderer in eigenen geteilten Listen bleiben deren Aufgaben; auch Admin-Löschung räumt jetzt vollständig auf.
- UI für wiederkehrende Aufgaben (Auswahl & Icon) (Commit
588c679)- Auswahl im Detail-Fenster (Keine / 🔁 Täglich / Wöchentlich / Monatlich / Jährlich) mit Hinweis; dezentes Wiederholungs-Symbol an Zeilen und Kanban-Karten.
- Wiederkehrende Aufgaben: Automatische Folge-Aufgabe bei Erledigung erzeugen (Commit
588c679)- Spalte
recurrence; Abhaken auf allen Wegen (Detail, Liste, Kanban, Notiz-Checkbox) erzeugt die Nachfolgerin mit kopierten Feldern, zurückgesetzten Unteraufgaben und fortgeschriebenem Datum (Monatsende abgefangen), live perTASK_CREATED; höchstens eine Nachfolgerin pro Aufgabe; Export/Import behalten die Regel.
- Spalte
- Mobile Eingabe für Fälligkeits-Uhrzeit optimieren (Commit
344f5e4)- Datum- und Uhrzeitfeld nebeneinander, mobil 44 px hoch mit nativen Pickern; „✕ Uhrzeit“ in der Schnellwahl macht die Aufgabe wieder ganztägig, ✕ entfernt die Fälligkeit.
- Fälligkeiten mit Uhrzeit im Task-Detail-Modal & Aufgabenansichten unterstützen (Commit
344f5e4)- Format
YYYY-MM-DDTHH:MM(API nimmt auch Leerzeichen/Sekunden an); Anzeige „Heute, 14:30“, „Morgen“, „Fr., 06.11.“; Überfälliges minutengenau rot; Gruppieren/Sortieren nach lokalem Tag und Uhrzeit (vorher UTC-Datum). Schnellwahl behält die Uhrzeit, Wiederholungen auch, Markdown-Export/-Import ebenso.
- Format
- Alarm-System härten:
alarm_sentzurücksetzen & Fälligkeiten mit Uhrzeit auswerten (Commit344f5e4)- Alarm zur Uhrzeit (ganztägig 9:00) minus Vorlaufzeit, Zeitzone
TZ(Standard Europe/Berlin, tzdata eingebettet); neue Fälligkeit oder Wiederöffnen (Detail, Kanban, Notiz-Checkbox, Triage) setztalarm_sentzurück; Folgeaufgaben starten mit 0. Mails zeigen „30.10.2026, 14:30 Uhr“. Offen in FLAW-12: Backoff bei Fehlern.
- Alarm zur Uhrzeit (ganztägig 9:00) minus Vorlaufzeit, Zeitzone
- Sicherheitslücke FLAW-04: Fest eincodiertes Fallback-
JWT_SECRETabsichern (Commit4cdbcbd)- Ohne
JWT_SECREToder mit bekanntem Platzhalter erzeugt der Server einen Zufallswert und speichert ihn alsjwt.secret(0600) im Datenverzeichnis.
- Ohne
- Sicherheitslücke FLAW-05: SSRF-Schutz für Webhook- und Discord-Alarm-URLs (Commit
62463bc)- https-Pflicht, Discord nur discord.com/api/webhooks/, eigener Resolver beim Verbinden (localhost/Link-Local/Metadaten immer gesperrt), Heimnetz und http nur mit Admin-Schalter „Alarm-Webhooks ins lokale Netz erlauben“, keine Proxys, max. 3 Weiterleitungen.
- Papierkorb für Notizen: Soft-Delete, Wiederherstellung & endgültiges Löschen (Commit
f69f74f)is_archived+archived_at/archived_by; Löschen (auch ganzer Ordner) verschiebt in den Papierkorb; raus aus Baum, Suche, Export, Statistik und für alle Empfänger unsichtbar; EndpunkteGET/DELETE /documents/trash,POST /documents/{id}/restore,DELETE /documents/{id}/permanent; Wiederherstellen legt fehlende Ordner neu an.
- Papierkorb-Ansicht & Wiederherstellung im Workspace (Notizen) (Commit
f69f74f)- Eintrag mit Zähler unten in der Ordnerleiste; Liste mit Ordner und Löschzeitpunkt, „Wiederherstellen“, „Endgültig löschen“ und „Papierkorb leeren“ jeweils mit zweitem Tipp; Notiz im Papierkorb schreibgeschützt mit Hinweisleiste und „Wiederherstellen“.
- Papierkorb für Notizen im mobilen Workspace integrieren (Commit
f69f74f)- Menüpunkt „Papierkorb“ mit Zähler im mobilen Menü und in der Ordnerliste; mobile Ansicht mit 44-px-Buttons und Zurück-Pfeil.
- Backlink-Index & Abfrage für Notizen („What links here“) (Commit
677fe0f)GET /documents/{id}/backlinks: Notizen mit[[Titel]](auch|Alias,#Abschnitt, Groß/klein egal), nur sichtbare, ohne Papierkorb und die Notiz selbst; bis zu 5 Fundstellen pro Notiz plusmore.
- Wiki-Style Backlink-Bereich („What links here“) am Notiz-Ende (Commit
677fe0f)- Einklappbarer Bereich „Verlinkt auf diese Notiz (n)“ am Notiz-Ende mit Icon, Titel, Ordner und hervorgehobenem Link im Bullet; Klick springt direkt zum Bullet; bei 0 ausgeblendet.
- Passwort-Reset per E-Mail: Token-Generierung, Mailversand & Session-Invalidierung (Commit
5e20710)- Tabelle
password_reset_tokens(nur SHA-256), Link 1 h und einmal gültig, höchstens alle 2 Min. pro Konto; neutrale Antwort, Versand im Hintergrund; Link nur ausBASE_URL; neues Passwort entwertet alle Links und beendet alle Sitzungen. Nur aktiv mit SMTP + gesetzterBASE_URL, nicht im Demo-Modus.
- Tabelle
- Passwort-Zurücksetzen-Flow im Login-Screen („Passwort vergessen?“) (Commit
5e20710)- „Passwort vergessen?“ am Passwortfeld (nur wenn verfügbar), Formular mit neutraler Bestätigung;
?resetToken=öffnet „Neues Passwort festlegen“ (mit Wiederholung), Token verschwindet sofort aus der Adresszeile; danach Hinweis zur Anmeldung, bei abgelaufenem Link „Neuen Link anfordern“.
- „Passwort vergessen?“ am Passwortfeld (nur wenn verfügbar), Formular mit neutraler Bestätigung;
- PWA Offline-Fähigkeit & App-Shell-Caching (Service Worker & Sync-Queue) (Commit
7bba174)- Service Worker: Seiten Network-First mit gecachter index.html, Bundles Cache-First, Icons/Manifest SWR, Cache-Versionen; GET-Antworten pro Benutzer in IndexedDB (App startet offline angemeldet); Outbox für erfasste Gedanken und abgehakte Aufgaben/Listeneinträge, gesendet bei
online, Start und alle 30 s; Banner „Offline · n Änderungen warten“. Im Browser mit Flugmodus geprüft.
- Service Worker: Seiten Network-First mit gecachter index.html, Bundles Cache-First, Icons/Manifest SWR, Cache-Versionen; GET-Antworten pro Benutzer in IndexedDB (App startet offline angemeldet); Outbox für erfasste Gedanken und abgehakte Aufgaben/Listeneinträge, gesendet bei
- Refactoring FLAW-20: Monolithische Go-Dateien (
server.go&sqlite.go) domänenspezifisch aufteilen (Commit74c394e)- Reine Verschiebung per AST-Werkzeug:
storage→ users, apikeys, thoughts (inkl. Alarme), tasklists, documents, folders, tags, lists, teams, system;api→ handlers_auth/account/thoughts/documents/folders/lists/tasklists/teams/admin/integrations, realtime.go, alarms.go. sqlite.go 637, server.go 460 Zeilen; alle Tests grün.
- Reine Verschiebung per AST-Werkzeug:
- Passwortregeln im Frontend härten (Mindestens 8 Zeichen & Validierungshinweise) (Commit
b5f926b)- Gemeinsame Prüfung
lib/password.tsin Setup, Registrierung/Einladung, Reset, Profil und Admin (Anlage + Reset) mit eigener Meldung „Das Passwort muss mindestens 8 Zeichen lang sein“ statt Browser-Popup; Platzhalter angepasst.
- Gemeinsame Prüfung
- Sicherheitslücke FLAW-09: Passwort-Mindestlänge auf 8 Zeichen anheben & zentral validieren (Commit
b5f926b)auth.ValidatePassword(≥ 8 Zeichen, nicht nur Leerzeichen, ≤ 72 Bytes) in allen sechs Pfaden; bestehende kürzere Passwörter funktionieren beim Login weiter. Nebenbei: Profil/Admin-Reset kürzen das Passwort nicht mehr (Leerzeichen am Rand machten den Login unmöglich). Offen in FLAW-09: Rate-Limit.
- Alarm-Logik härten (FLAW-12): Fehlversuche begrenzen (Max. 3 Versuche bei Ausfall aller Kanäle) (Commit
d198281)- Spalte
alarm_failures; nach 3 Durchläufen ohne zustellenden Kanal wird der Alarm aufgegeben (Warnung im Log); Erfolg, neue Fälligkeit oder Wiederöffnen setzen zurück. FLAW-12 damit vollständig behoben.
- Spalte
- Such-Button in der Desktop-Titelleiste als runder Icon-Button (Lupe im Kreis) (Commit
6d720c0)- Runder Icon-Button nur mit Lupe, Tastenkürzel im Tooltip.
- Header-Navigation: Workspace-Bubble entfernen & Listen-Bubble ergänzen (Commit
c4fc455)- Neues Feld
listItemsOpenCount(offene Einträge aller eigenen, direkt und per Gruppe geteilten Listen, mit Test); Akzent-Zähler an Listen in Header und mobiler Leiste, Workspace ohne Zähler; Stats aktualisieren sich bei Listen-Events und nach Löschen.
- Neues Feld
- Workspace-Tabs: Einheitliche
CountBadge-Bubbles für To-Dos und Hashtags (Notizen ohne Bubble) (Commit4bf060b)- To-Dos und Hashtags mit
CountBadgeauf dem Label, Notizen ohne Zähler.
- To-Dos und Hashtags mit
- Workspace: Lokale Notizen-Suche entfernen bzw. auf globale Spotlight-Suche umstellen (Commit
e7851f1)- Lokaler Filter entfernt; an seiner Stelle ein Button „Notizen durchsuchen… ⌘K“ (mobil 44 px), der die globale Volltextsuche öffnet.
- Tab-Badges optimieren: Positionierung um ca. 4px nach unten und 4px nach rechts korrigieren (Commit
6d6a35d)- Alle Tab-Zähler
-top-0.5 -right-2mitpr-3am Label (Header, Aufgabenlisten, Listen, Workspace); geprüft in Dark, Light und mobil; ui-patterns.md angepasst.
- Alle Tab-Zähler
- Such-Icon in der Titelleiste: Vollständig kreisrundes Styling (
rounded-full) sicherstellen (Commitafd3b03)- Regel
.bg-panel.border.rounded-full/.bg-canvas.border.rounded-fullin index.css: ein explizitesrounded-fullgewinnt jetzt in allen Themes gegen den Theme-Radius (betrifft auch andere runde Buttons/Avatare).
- Regel
- Demo-Modus: Automatischer 20-Minuten-Reset-Ticker & Reset-Event (Commit
6b9eb62)DEMO_RESET_MINUTES(Standard 20, 0 = aus); feste IDs der Demo-Konten, damit Sitzungen den Reset überleben; laufende Anfragen sperren den Reset (Streams ausgenommen);DEMO_RESETan alle Verbindungen;/auth/statusliefertdemoNextResetunddemoResetInSeconds.
- Demo-Modus: Live-Countdown-Timer & Reset-Banner in der Titelleiste (Commit
6b9eb62)- „✨ Demo · Reset in MM:SS“ statt der Versionsnummer (Desktop und mobil, Tooltip); nach dem Reset Cache geleert, Ansichten neu geladen, Hinweis „Demo-Instanz wurde zurückgesetzt“; ohne Event fragt die App nach Ablauf selbst nach. Live mit 1-Minuten-Reset geprüft.
- Rate-Limiting & temporäre Kontosperre bei Login-Fehlversuchen (FLAW-09 Abschluss) (Commit
11c14fa)- Sperre nach Fehlversuchen: Konto + Adresse 3, Konto 20, Adresse 30, je 15 Min., 429 mit Retry-After; so kann ein Angreifer den Admin nicht von außen aussperren. Erfolg bzw. Passwort-Reset heben die Sperre auf. Client-IP nur von vertrauenswürdigen Proxys (
TRUSTED_PROXIES, Standard private Netze,all= altes Verhalten);LOGIN_PROTECTION=falseschaltet alles ab.
- Sperre nach Fehlversuchen: Konto + Adresse 3, Konto 20, Adresse 30, je 15 Min., 429 mit Retry-After; so kann ein Angreifer den Admin nicht von außen aussperren. Erfolg bzw. Passwort-Reset heben die Sperre auf. Client-IP nur von vertrauenswürdigen Proxys (
- API-Key Scopes einschränken & Webhook-Ingest für Triage, Aufgaben und Listeneinträge (Commit
5c711c2)- Scopes
webhook:triage|task|list(Standard Triage, alte Keys → Triage); Ingest mittargettask (optionaltaskListId) undlist_item(listId, nur mit Schreibrecht), 403 ohne Scope; Keys öffnen keine Live-Streams mehr. Nebenbei FLAW-27 behoben (3900c61): Listeneinträge waren ohne Rechteprüfung änderbar.
- Scopes
- API-Key Scopes im Ecosystem-Tab (Auswahl bei Erstellung & Badge-Anzeige) (Commit
5c711c2)- Die sichtbare Key-Verwaltung lag in den Kontoeinstellungen,
EcosystemViewwar toter Code und ist entfernt; neuesApiKeysPanelmit Scope-Auswahl (mind. einer), Badges je Key, Simulator für Inbox/Aufgabe/Listeneintrag und Beispielen mitX-API-Key-Header.
- Die sichtbare Key-Verwaltung lag in den Kontoeinstellungen,
- Automatische Server- & Benutzer-Backups (Backlog / Später geplant) (Commit
c97765e, 64e077d)- Admin: Schalter, Uhrzeit, Aufbewahrung (Standard 03:00, 3 Tage), Liste, Download, „Jetzt sichern“; täglich DB-Abzug (
VACUUM INTO, gzip) und ein ZIP je Benutzer unterbackups/, verpasste Läufe werden nachgeholt. Benutzer: eigene Server-Backups herunterladen oder einspielen (ersetzen/hinzufügen, nach Bereichen Notizen/Aufgaben/Listen/Inbox/Themes); Import mit derselben Bereichsauswahl; Themes jetzt in Export/Import.
- Admin: Schalter, Uhrzeit, Aufbewahrung (Standard 03:00, 3 Tage), Liste, Download, „Jetzt sichern“; täglich DB-Abzug (
- Quick-Add FAB: Hold-to-Record Sprachaufnahme mit Swipe-to-Cancel (Commit
eabb018, 3739872)- Von Gemini umgesetzt (HoldToRecordFab: Tippen öffnet wie bisher, Halten nimmt per Spracherkennung auf und speichert in die Inbox, nach oben ziehen bricht ab, Rückfall ohne Spracherkennung, Tests). Nachgebessert: Bedienung per Tastatur/Screenreader, Erfolgsmeldung erst nach dem Speichern, Randfarbe im Abbruch-Zustand.
- Sicherheit S1: Sichere Links & Sicherheits-Header (FLAW-28, FLAW-29) (Commit
b2ecda9)- Links nur
http/https/mailto(safeHref); CSP,X-Frame-Options,nosniff,Referrer-Policy,Permissions-Policy; Inline-Scripts der Startseite in Dateien verschoben.
- Links nur
- Sicherheit S2: Serverseitige Sitzungen & aktuelles Passwort (FLAW-30, FLAW-31) (Commit
1af3a6e)- Tabelle
sessions(ersetztrevoked_tokens), gleitend 30 Tage, Token-Erneuerung überX-Session-Token; Geräteliste mit Einzel-Abmelden im Profil; Passwort/E-Mail nur mit aktuellem Passwort, Hinweismail an alte Adresse. Upgrade meldet alle einmal ab.
- Tabelle
- Sicherheit S3: Längere IDs, Einladungscodes, Rate-Limits (FLAW-32, FLAW-39, FLAW-40) (Commit
3709282)- IDs 96 Bit, Codes
INV-XXXXX-…mit 100 Bit; Registrierung 20 und „Passwort vergessen“ 10 Anfragen pro Adresse in 15 Min.; Einladung wird vor dem Konto atomar beansprucht.
- IDs 96 Bit, Codes
- Sicherheit S4: Demo, SMTP-Passwort, Limits, Backups, Downloads (FLAW-33 bis FLAW-38) (Commit
9d96981)- Demo verschickt nichts und schützt die gemeinsamen Konten (403 „In der Demo deaktiviert“, Hinweise in der UI); SMTP-Passwort nie an den Browser;
?token=nur API-Keys; 2-MB-Körperlimit; Konto löschen entfernt Server-Backups; 30 Min. für große Downloads/Importe.
- Demo verschickt nichts und schützt die gemeinsamen Konten (403 „In der Demo deaktiviert“, Hinweise in der UI); SMTP-Passwort nie an den Browser;
- Triage: Listenauswahl überspringen, wenn es nur eine beschreibbare Liste gibt (Commit
3a27a37, gemergt inef16778)- Von Gemini umgesetzt (Desktop-Button „Auf ‹Liste›“, mobiles Aktions-Sheet, Warteschlange, Schnellerfassung; nur lesbar geteilte Listen ausgeblendet; Tests). Nachgebessert:
useMemofür die Listenfilterung in der Schnellerfassung. Release v0.6.0.
- Von Gemini umgesetzt (Desktop-Button „Auf ‹Liste›“, mobiles Aktions-Sheet, Warteschlange, Schnellerfassung; nur lesbar geteilte Listen ausgeblendet; Tests). Nachgebessert:
- Serverseitige Whisper-Anbindung (ENV-Konfiguration,
/api/v1/voice/transcribe, Compose-Dienst) (Commit7801cd1)- Abweichend vom ursprünglichen Entwurf nur per ENV (
STT_URL,STT_MODEL,STT_LANGUAGE,STT_API_KEY,STT_DISABLED, SchutzwerteSTT_MAX_SECONDS,STT_MAX_UPLOAD_MB,STT_MAX_PARALLEL,STT_PER_USER_PER_HOUR,STT_TIMEOUT_SECONDS); URL gesetzt = Server-Modus, Demo immer Browser. Admin zeigt nur eine Statuskarte mit Testaufnahme. Compose-Profilwhisper(speaches 0.8.3-cpu, Modelle in./whisper, UID 1000); MindSift stößt den Modell-Download selbst an. Echt getestet mit speaches (tiny/small/large-v3-turbo).
- Abweichend vom ursprünglichen Entwurf nur per ENV (
- Spracheingabe im Frontend auf den Server-Modus umstellen (V2) (Commit
7fa21e4)- Gemeinsamer Hook
useVoiceInput+VoiceWavefür Quick-Dump-Leiste, mobiles Erfassen-Sheet und Halte-Knopf; Server-Modus mit MediaRecorder, echten Pegel-Wellen und „Wird erkannt…“, Browser-Modus wie bisher, Mikrofon ausgeblendet beioff/ohne Unterstützung. Mit speaches im Browser geprüft (Desktop, Handy halten, Handy-Sheet).
- Gemeinsamer Hook
- Workspace-Sidebar: Cleanes Datei-Explorer-Layout ohne Sektions-Überschriften (Commit
9f3c78d, gemergt a9d0e49)- Von Gemini 3.8 umgesetzt: keine Überschriften mehr, angeheftete Notizen oben (mit kleinem Pin, Trenner), darunter Ordner und Notizen der Hauptebene; angeheftete Root-Notizen nicht doppelt; Tests.
- Workspace
/code-Block: Sprachauswahl & Live-Syntax-Highlighting im VSCodium / VS-Code-Stil (Commitff53f06, gemergt 9124809, Fix cc68d3f)- Von Gemini 4 umgesetzt: CodeBlockEditor mit Sprachauswahl (~50 Sprachen, nachgeladen), Live-Highlighting als Overlay, Kopieren/Als Text, Tab/Shift+Tab,
/code yamlund ```yaml; Farben als Theme-Variablen (Dark+/Light+) in allen Themes. Nachgebessert: Fokus blieb nach der Umwandlung nicht im Block (Tippen löste App-Kürzel aus).
- Von Gemini 4 umgesetzt: CodeBlockEditor mit Sprachauswahl (~50 Sprachen, nachgeladen), Live-Highlighting als Overlay, Kopieren/Als Text, Tab/Shift+Tab,
- Docker-Setup vereinfachen: Whisper-Service auskommentieren statt
COMPOSE_PROFILES=whisper(Commite385a44)- Profil entfernt; whisper-Block in docker-compose.yml auskommentiert mit Schritt-für-Schritt-Anleitung darüber (Rauten entfernen, STT_URL setzen, Ordner für UID 1000 anlegen); eingeschaltet als gültiges YAML geprüft. README, Architektur-Doku und CHANGELOG angepasst.
- Docker-Umgebung: Erklärungskommentare der Variablen von
docker-compose.ymlnach.env.exampleverschieben (Commite385a44)- .env.example komplett auf Deutsch kommentiert (Funktion, Standard, Einheiten, Auswahl), nach Themen gegliedert; docker-compose.yml nur noch Zuordnungen mit Verweis oben auf .env/.env.example. Nebenbei: TZ, TRUSTED_PROXIES, LOGIN_PROTECTION, DEMO_RESET_MINUTES, LEGAL_*_CONTENT wurden vorher gar nicht durchgereicht.
- Medien in Notizen: Ablage im Backend (M1) (Commit
177fa49)- Tabelle
media, Dateien indata/media/<docId>/; Upload mit Schreibrecht, Abruf mit Leserecht (auch kopierte Blöcke), Format am Inhalt erkannt (kein SVG), externe Bilder per SSRF-geschütztem Kopieren; Verweis im Blockinhalt (media:<id>), daher keine Änderung am Sync-Modell; Aufräumen nach 24 h ohne Verweis; GrenzenMEDIA_*.
- Tabelle
/bild(M2) (Commite8fa14a)- Nur im leeren Punkt; Auswahl inline (Datei, Kamera, Drag & Drop, Strg+V, Link), Esc bricht ab; Browser verkleinert auf 2048 px und speichert WebP (EXIF/GPS entfällt); Vollbild und Beschriftung.
/audio(M3) (Commit3f5e3b2)- Bereit-Bubble mit grünem Mikrofon, Aufnahme rot mit Live-Wellen links und Zeit, danach Inline-Player; Datei-Upload; WebM-Dauer-Fix; „Transkribieren“ mit eigener Spracherkennung.
/diktat(M4) (Commit3f2bc96)- Startet sofort, vollflächiger Wellen-Button mit halbtransparentem „Stopp“, Text landet als normaler Text im Punkt; nur angeboten, wenn Spracheingabe verfügbar.
- Medien in Backup, Export und Import (M6) (Commit
1f63e08)- Backup-ZIP mit
media/, Markdown-Archiv mitattachments/(relative Einbettung), Rück-Import mit neuen IDs; Obsidian-Import übernimmt eingebettete Bilder/Audio, ungenutzte Dateien als übersprungen gemeldet.
- Backup-ZIP mit
- Workspace Notizen-Editor: Mobiles Padding reduzieren & horizontales Ausweichen bei tiefen Einrückungen (Commit
83408d1)- Rand mobil pl-2/pr-1, Einrückung per CSS-Variable 14 px (ab sm 22 px), Zeilen-Mindestbreite 14rem mobil mit seitlichem Scrollen des Inhalts; zusätzlich Zoom-Knopf mobil ausgeblendet (Tipp auf den Punkt zoomt) und Löschen nur in der aktiven Zeile. Gemessen: schmalste Textzeile 128 → 244 px (Demo-Notiz), bei 16 Ebenen ≥ 174 px.
- Slash-Befehle vereinheitlichen:
/imagestatt/bild, knappe Texte & Layout-Fix im Menü (Commit1632dd2)- /image statt /bild (Aliase bild, foto; auch sprachnotiz, dictate), kurze Texte, Menü w-72, Label nowrap, Beschreibung truncate rechtsbündig. /diktat bleibt deutsch wie im ursprünglichen Auftrag.
- Admin-Einstellungen: E-Mail-Absendername (
SMTP_FROM_NAME) konfigurierbar machen & Vorbelegung (Commit56c1fa0)- Feld „Absender-Name (SMTP_FROM_NAME)“ mit Platzhalter MindSift und Hinweis; Platzhalter der Absenderadresse auf reine Adresse geändert.
- E-Mail-Absendername unterstützen (
SMTP_FROM_NAME& Default „MindSift“) (Commit56c1fa0)- SMTP_FROM_NAME (Standard MindSift) in Config, system_settings (smtp_from_name), Compose und .env.example; reine Adresse bekommt den Namen im From-Header, ein Name in SMTP_FROM hat Vorrang, MAIL FROM bleibt die reine Adresse; Test mit Umlauten.
- Link-Vorschau über Punkten mit Web-Adresse (M5) (Commit
4c26eb2)- Server holt https-Seiten SSRF-geschützt, liest og:/twitter:-Tags, Titel, Beschreibung, Icon, Bild; Cache 7 Tage in
link_previews; kompakte Karte über dem Punkt, ✕ macht[Titel](url)daraus (synchronisiert), globaler Schalter unter Darstellung; in der Demo aus. Echt getestet mit Wikipedia und go.dev (Handy und Desktop).
- Server holt https-Seiten SSRF-geschützt, liest og:/twitter:-Tags, Titel, Beschreibung, Icon, Bild; Cache 7 Tage in
- Outliner: Bulletpoint (inkl. Unterbaum) in eigenständige Notiz umwandeln (Commit
4d1b37c)- Knopf am Punkt (Desktop) und /extract bzw. /notiz; serverseitig über das Operationsprotokoll (offene Editoren folgen live); Titel ohne Hashtags (bleiben am Link), eindeutig mit (2); gleicher Ordner; Freigaben übernommen, fremder Besitzer bekommt Schreibrecht; Hinweis mit „Öffnen“.
- Notizen zusammenführen (Merge Documents, z. B. per Drag & Drop in der Sidebar) (Commit
4d1b37c)- Drag & Drop Notiz auf Notiz in der Sidebar (Hervorhebung) oder Knopf im Notizkopf mit Suche; Bestätigungsdialog; Quelle (muss eigen sein) als h2-Abschnitt mit Unterpunkten angehängt, Quelle in den Papierkorb; Toast mit vollständigem Rückgängig (Abschnitt weg, Quelle zurück). Medien bleiben erreichbar.
- Link-Vorschau nur bei
/linkim leeren Bulletpoint & Slash-Menü Schließen-Verhalten reparieren (Commit446f8e4)- Gemini 4: Karte nur bei Punkt = genau eine https-Adresse (bzw. /link in leerem Punkt); Slash-Menü nur am Anfang/nach Leerzeichen, Esc/Backspace schließen.
- Workspace Outliner: Enter-Sperre am letzten leeren Bulletpoint entfernen (Commit
446f8e4)- Gemini 4: Sperre entfernt, Enter am Ende legt neuen Punkt an.
- Slash-Befehls-Menü (
/): Ausgewähltes Element bei Pfeiltastennavigation automatisch ins Sichtfeld scrollen (Commit446f8e4)- Gemini 4: aktiver Eintrag scrollt per scrollIntoView mit.
/diktat: Live-Mitschreiben & kein vorzeitiger Abbruch bei Sprechpausen (Commit6795edb)- Gemini 4: Option live in useVoiceInput; Browser-Neustart bei Pausen, Server-Modus in Stücken (eigener Recorder je Abschnitt), mitwachsender Text und Zeit.
/extractRace-Condition & Konflikt hinter Proxys/Polling beheben (Lokale Link-Ersetzung) (Commit362dd3b)- Umbau: Server legt nur die Notiz an und liefert den Link, der Editor ersetzt den Ast selbst über die Sync-Engine (keine Konflikte, sofort sichtbar, auch bei Polling).
- Workspace-Sidebar: Ausgelagerte Notiz (
/extract) sofort ohne Tab-Wechsel in der Dateiliste anzeigen (Commit362dd3b)- onDocCreated/onDocRemoved vom Editor an WorkspaceView, Ordner wird aufgeklappt.
- Rückgängig-Funktion (Strg+Z / Undo) für ausgelagerte Notizen (
/extract) (Commit362dd3b)- Strg+Z der Engine holt den Ast zurück, POST /documents/{id}/extract/undo legt die neue Notiz in den Papierkorb; Toast mit Öffnen und Rückgängig.
- Workspace Header & Aktionen aufräumen: Undo/Redo-Buttons, Drei-Punkte-Menü & Status-Pills nach oben in die Tab-Leiste (Commit
5f27e7c)- Gemini 4: Status-Pillen in der Tab-Leiste, Undo/Redo-Knöpfe, Drei-Punkte-Menü (Anheften, Zusammenführen, Export, Löschen).
- Benutzer-Einstellungen: Granulare Benachrichtigungen & Kanal-Routing (E-Mail & Discord) (Commit
d2afcf4, a69bcba)- Gemini 4 Oberfläche (Matrix, Tageszusammenfassung, Beobachten-Knopf), Claude Backend (Routing, Bündelung 5 Min., Watcher, Pause, eigene Änderungen); Gruppen-Freigaben in der Tageszusammenfassung (
6b3c32a). Release v0.8.0.
- Gemini 4 Oberfläche (Matrix, Tageszusammenfassung, Beobachten-Knopf), Claude Backend (Routing, Bündelung 5 Min., Watcher, Pause, eigene Änderungen); Gruppen-Freigaben in der Tageszusammenfassung (
- HTML-E-Mail-Templates mit Branding & Watcher-Benachrichtigungen für E-Mail & Discord (Commit
a69bcba)- multipart/alternative mit schlichtem HTML (inline Styles, keine externen Ressourcen), Discord als ein Embed; gebündelte Nachrichten und Tageszusammenfassung.
- Code-Blöcke im Workspace (
CodeBlockEditor): Zeilennummern links anzeigen (Commit1d68638)- Zeilennummernspalte mit synchronem Scrollen, horizontaler Bildlauf statt Umbruch (v0.9.0).
- Outliner: Standard-Formatierungs-Shortcuts (Strg+B, Strg+I, Strg+K, etc.) für Textauswahl unterstützen (Commit
a317ce0)- Strg/Cmd+B, +I (umschaltend), +K (Link bzw. Link-Dialog); nicht in Code-Blöcken und schreibgeschützten Notizen (v0.9.0).
- Workspace: Doppelten Scrollbalken (Outer Window & Inner Editor) beheben (Commit
6c154af)- Workspace füllt das Fenster (100dvh, Flex), nur die Notiz scrollt; am Handy kein getrenntes Scrollen mehr (seitlicher Bildlauf-Bereich behält seine Höhe).
- Workspace: Drag & Drop-Zustand beim Abbruch bereinigen (Fix für dauerhaft sichtbares „Auf Hauptebene verschieben“) (Commit
6c154af)- Globaler dragend-Listener räumt alle Zieh-Zustände auf.
- Workspace: Sidebar-Toggle-Button bei eingeklappter Leiste dezent stylen (nur Icon in Akzentfarbe) (Commit
6c154af)- Rahmen neutral, nur das Symbol in Akzentfarbe.
- Build & Versionierung:
-dev-Suffix strikt aufmindsift:devbeschränken (Commit6c154af)- main-Builds bekommen v als APP_VERSION, Tags den Tag, alles andere -dev.
- Eigener (ausgehender) Webhook ist nicht mehr einstellbar (Commit
261579f)- Dritter Kanal „Webhook“ in der Matrix und der Tageszusammenfassung, JSON-Digest (event: digest).
- ⏸ Zurückgestellt: Workspace: „Heute“-Button für tägliche Notizen (Daily Notes / Logseq- & Obsidian-Workflow) (Commit
9008d7c)- Als Journal umgesetzt: eine Notiz pro Tag, endlos untereinander, Kalender in der Seitenleiste, Teilen des sichtbaren Tags, pro Gerät abschaltbar.
- Outliner: Nummerierte Listen (
/number) & Markdown-Einfügen (Absätze, Nummern) (Commit2bfe74e)- 1./a./i. nach Verschachtelung, Enter setzt fort, leerer Punkt beendet; Einfügen: Leerzeile trennt Absätze, Einzelabsatz ging verloren (behoben).
- Outliner: Block-Typ-Rückumwandlung in Standardtext (
/text, Menü & Undo-Sicherheit) (Commitfd72500)- /text (p, paragraph, bullet, standard), Aufgaben-Menü und Aktionsblase wandeln zurück; Trennlinie per Backspace/Entf (v0.10.0).
- Outliner: Slash-Command Menü bei Klick ins Leere / Blur schließen & Trigger-Kontext anpassen (Commit
fd72500)- Erkennung an der Cursorposition, kontextabhängige Befehle, schließt bei Klick daneben und Blur (v0.10.0).
- Outliner: Hässlichen Zeilenumbruch durch TODO-3-Punkte-Menü & Badges beheben (Commit
fd72500)- Badges und Menü aus dem Fließtext gelöst (v0.10.0).
- Outliner: Aktions-Buttons (Zoom, Auslagern, Löschen) als schwebendes Overlay statt Flex-Breitenverengung (Commit
fd72500)- Schwebende Blase, Textbreite bleibt gleich (v0.10.0).
- Outliner: Schriftgrößen für H1, H2 und H3 deutlich anheben (H1 auf Titel-Niveau) (Commit
fd72500)- H1 xl/2xl, H2 lg/xl, H3 base; Notiztitel dünn und größer (v0.10.0).
- Design: Zähler-Badges (
CountBadge) & Slash-Command-Auswahl mit reduzierter Deckkraft (Opacity 0.6) stylen (Commit1753208)- Akzent-Badge über accent-dim mit Rand, Muted über panel-elevated; Slash-Auswahl dezent (v0.10.0).
- Quick Dump / Instant-Capture: Unnötiges Scrolling deaktivieren, Platzhaltertext kürzen & Absende-Pfeil nach unten umdrehen (Commit
1753208)- Kurzer Platzhalter, kein Scrollen einzeilig, Pfeil nach unten (v0.10.0).
- Triage-Deck: Mobile Schnellaktions-Buttons (Entfernen, Aufgabe, Liste, Notiz) unter der Karte einblenden (Commit
1753208)- Leiste Wegwerfen/Liste/Notiz/Aufgabe unter der Karte (v0.10.0).
- Workspace: „Neuer Ordner“-Modal zentriert unter dem Mauszeiger öffnen (Oberkante mittig) (Commit
1753208)- FormSheet mittig unter dem Klick mit Rand-Schutz (v0.10.0).
- Light Theme: Hintergrundfarben in Notizen korrigieren (Sidebar grau, Editor weiß) (Commit
2542e0e)- Editor weiß, Ordnerleiste grau über --bg-editor/--bg-sidebar (v0.10.0).
- PWA Web Share Target: Text, Links und Bilder aus Smartphone-Apps direkt in den MindSift-Posteingang teilen (Commit
86d2cd0)- Teilen-Ziel im Manifest, Service Worker legt geteilte Inhalte ab, Import in den Posteingang; Bilder als Hinweistext (Gemini).
- Outliner: Deep-Linking & Verlinkung einzelner Bulletpoints (Block-Referenzen) (Commit
1a49e6b)- Notiz#^id, kopieren an jedem Punkt, Auswahl im Link-Dialog, Sprung mit Hervorhebung, Hinweis wenn der Punkt fehlt.
- Workspace: Sidebar-Kopfzeile aufräumen (Überschrift entfernen, Suche & Aktions-Buttons in eine Zeile) (Commit
d408e7d)- Überschrift entfernt, Suche + neuer Ordner + neue Notiz in einer Zeile.
- Workspace: Ablenkungsfreier Fokus-Modus (Zen-Modus) mit Auto-Hide-Header (Commit
226c863)- Strg+Umschalt+F / Menü, Lesebreite, Kopfleiste am oberen Rand, Esc beendet.
- Workspace: Notiz-Aktionsleiste in die obere Tab-Leiste integrieren, Editor-Headerleiste komplett entfernen & Statusanzeigen vereinheitlichen (Commit
d408e7d)- Desktop: Aktionen per Portal in der Workspace-Leiste, feste Reihenfolge, Speicherstatus nur als Symbol; Handy: Titel erst nach Wegscrollen.
- Workspace Journal: Umschaltbares Schließen (Toggle), prominentes Auffahr-Panel & Zustandskonsistenz (Commit
375dda9)- Panel mit Rahmen, zweiter Klick schließt, Zustand bleibt über Tab-Wechsel.
- Outliner: Hierarchisches Einrücken nach Überschriften & Erkennung von Markdown-Listen (
*,-,1.) (Commit375dda9)- Einfügen und Import verschachteln Abschnitte unter Überschriften, Enter an Überschrift legt Unterpunkt an, - / * / + als Kürzel.
- Globaler App-Footer mit Versionsnummer, „Über MindSift“, Rechtstexten & Custom-Link (inkl. Demo-Modus) (Commit
c181ffe)- Footer am Desktop, Über-Dialog, LEGAL_CUSTOM_LINK_* (Gemini).
- Web Push-Benachrichtigungen bei Fälligkeiten über Service Worker & VAPID (Browser & Handy) (Commit
38b8c92)- Push als Kanal in der Matrix und Tageszusammenfassung, VAPID automatisch, Gerät pro Browser ein-/ausschalten, Test; Verschlüsselung per Test geprüft.
- CI/CD & Pipeline: Dreifachen Build & redundante Testläufe bei Release-Merge/Tags optimieren (Commit
141f87f)- Tests einmal pro Code-Stand, Release-Tag taggt latest um; Zuordnung als Image-Label statt Zusatz-Tags.