diff --git a/artifacts/toolrate/src/i18n/locales/de.json b/artifacts/toolrate/src/i18n/locales/de.json
index 43e1d99..3601692 100644
--- a/artifacts/toolrate/src/i18n/locales/de.json
+++ b/artifacts/toolrate/src/i18n/locales/de.json
@@ -69,7 +69,7 @@
},
"home": {
"welcome": "Willkommen bei toolr",
- "tagline": "Die Community-Plattform, auf der Ingenieure die Tools, die sie täglich nutzen, ehrlich bewerten.",
+ "tagline": "Bewerte dein Tool.",
"totalTools": "Tools gesamt",
"totalRatings": "Bewertungen gesamt",
"avgRating": "Ø Bewertung",
@@ -189,7 +189,7 @@
"nameOptional": "Name (optional)",
"nameLabel": "Name",
"anonymousPlaceholder": "Anonym",
- "anonymousEngineer": "Anonymer Ingenieur",
+ "anonymousEngineer": "Anonymer Benutzer",
"beFirstToReview": "Sei der Erste, der seine Gedanken zu diesem Tool teilt.",
"shareExperience": "Teile deine Erfahrung mit {{name}}",
"score": "Punktestand",
diff --git a/artifacts/toolrate/src/i18n/locales/en.json b/artifacts/toolrate/src/i18n/locales/en.json
index 7e3ad1f..c67dfd4 100644
--- a/artifacts/toolrate/src/i18n/locales/en.json
+++ b/artifacts/toolrate/src/i18n/locales/en.json
@@ -69,7 +69,7 @@
},
"home": {
"welcome": "Welcome to toolr",
- "tagline": "The community hub where engineers honestly rate the tools they use daily.",
+ "tagline": "Rate your Tool.",
"totalTools": "Total Tools",
"totalRatings": "Total Ratings",
"avgRating": "Avg Rating",
@@ -189,7 +189,7 @@
"nameOptional": "Name (Optional)",
"nameLabel": "Name",
"anonymousPlaceholder": "Anonymous",
- "anonymousEngineer": "Anonymous Engineer",
+ "anonymousEngineer": "Anonymous User",
"beFirstToReview": "Be the first to share your thoughts on this tool.",
"shareExperience": "Share your experience with {{name}}",
"score": "Score",
diff --git a/artifacts/toolrate/src/pages/docs.tsx b/artifacts/toolrate/src/pages/docs.tsx
index e5cca3a..1786d29 100644
--- a/artifacts/toolrate/src/pages/docs.tsx
+++ b/artifacts/toolrate/src/pages/docs.tsx
@@ -740,7 +740,7 @@ function ReleasesView({ versions }: { versions: ReleaseDoc[] }) {
function ReleaseNoteView({ version, doc }: { version: string; doc: ReleaseDoc | null }) {
const locale = useDocsLocale();
- const file = doc ? `releases/${localizedFile(doc.file, doc.fileEn, locale)}` : `releases/${version}.md`;
+ const file = doc ? `releases/${localizedFile(doc.file, doc.fileEn, locale)}` : `releases/${version}.de.md`;
return (
diff --git a/docs/examples/import-tools.yaml b/docs/examples/import-tools.yaml
new file mode 100644
index 0000000..8a5fe9e
--- /dev/null
+++ b/docs/examples/import-tools.yaml
@@ -0,0 +1,295 @@
+# Beispiel-YAML zum Import in den Admin-Bereich (Tab „Tools" -> Importieren).
+# Erwartetes Format pro Eintrag:
+# name (Pflicht)
+# description, category, websiteUrl, iconUrl (optional)
+# features, tags (Listen oder | -getrennte Strings)
+# Das Format wird automatisch erkannt; bei CSV den Trenner wählen.
+# Fehlerhafte Zeilen werden übersprungen und mit Zeilennummer aufgelistet.
+
+- name: Slack
+ description: Team-Kommunikation mit Channels, Direktnachrichten und App-Integrationen
+ category: Kommunikation
+ websiteUrl: https://slack.com
+ features:
+ - Channels
+ - Videoanrufe
+ - App-Integrationen
+ tags:
+ - communication
+ - teamwork
+
+- name: Microsoft Teams
+ description: Chat, Besprechungen, Dateien und Zusammenarbeit in einer Plattform
+ category: Kommunikation
+ websiteUrl: https://www.microsoft.com/de-de/microsoft-365/microsoft-teams
+ features:
+ - Videokonferenzen
+ - Teamkanäle
+ - Office-Integration
+ tags:
+ - communication
+ - meetings
+
+- name: Zoom
+ description: Videokonferenzen und Webinare für Teams und externe Partner
+ category: Kommunikation
+ websiteUrl: https://zoom.us
+ features:
+ - Videokonferenzen
+ - Webinare
+ - Bildschirmfreigabe
+ tags:
+ - video
+ - meetings
+
+- name: Jira
+ description: Agile Projekt- und Issue-Verfolgung für Entwicklung und Betrieb
+ category: Projektmanagement
+ websiteUrl: https://www.atlassian.com/software/jira
+ features:
+ - Backlog
+ - Sprints
+ - Kanban-Boards
+ tags:
+ - agile
+ - project-management
+
+- name: Confluence
+ description: Kollaborative Wissensdatenbank und Dokumentation für Teams
+ category: Projektmanagement
+ websiteUrl: https://www.atlassian.com/software/confluence
+ features:
+ - Wikis
+ - Seitenbausteine
+ - Berechtigungen
+ tags:
+ - documentation
+ - knowledge-base
+
+- name: GitLab
+ description: DevOps-Plattform mit Git-Repositorys, CI/CD und Code-Review
+ category: Entwicklung
+ websiteUrl: https://about.gitlab.com
+ features:
+ - Git-Repositorys
+ - CI/CD
+ - Merge Requests
+ tags:
+ - devops
+ - git
+
+- name: GitHub
+ description: Versionsverwaltung, Code-Review und Collaboration auf Git-Basis
+ category: Entwicklung
+ websiteUrl: https://github.com
+ features:
+ - Repositories
+ - Pull Requests
+ - Actions
+ tags:
+ - git
+ - collaboration
+
+- name: Jenkins
+ description: Automatisierte Build- und Deploy-Pipelines für Softwareprojekte
+ category: CI/CD
+ websiteUrl: https://www.jenkins.io
+ features:
+ - Pipelines
+ - Plugins
+ - Job-Automatisierung
+ tags:
+ - ci
+ - cd
+
+- name: Docker
+ description: Container-Plattform zum Paketieren und Ausführen von Anwendungen
+ category: Entwicklung
+ websiteUrl: https://www.docker.com
+ features:
+ - Container
+ - Images
+ - Compose
+ tags:
+ - containers
+ - virtualization
+
+- name: Grafana
+ description: Observability- und Dashboard-Plattform für Metriken, Logs und Alerts
+ category: Monitoring
+ websiteUrl: https://grafana.com
+ features:
+ - Dashboards
+ - Alerts
+ - Datenquellen
+ tags:
+ - observability
+ - monitoring
+
+- name: Prometheus
+ description: Open-Source-Systeme zur Zeitreihen-Metrikerfassung und -Auswertung
+ category: Monitoring
+ websiteUrl: https://prometheus.io
+ features:
+ - Metriken
+ - Alerting
+ - Time-Series-Datenbank
+ tags:
+ - monitoring
+ - metrics
+
+- name: Datadog
+ description: Cloud-basierte Observability für Infrastruktur, APM und Logs
+ category: Monitoring
+ websiteUrl: https://www.datadoghq.com
+ features:
+ - Infrastruktur-Monitoring
+ - APM
+ - Log-Management
+ tags:
+ - observability
+ - saas
+
+- name: PagerDuty
+ description: Incident-Management und On-Call-Benachrichtigungen für Teams
+ category: Betrieb
+ websiteUrl: https://www.pagerduty.com
+ features:
+ - Alerting
+ - On-Call-Pläne
+ - Incident-Response
+ tags:
+ - incident-management
+ - on-call
+
+- name: Sentry
+ description: Fehlerüberwachung und Performance-Monitoring für Anwendungen
+ category: Monitoring
+ websiteUrl: https://sentry.io
+ features:
+ - Error-Tracking
+ - Releases
+ - Performance
+ tags:
+ - error-monitoring
+ - debugging
+
+- name: Terraform
+ description: Infrastructure-as-Code zur deklarativen Bereitstellung von Ressourcen
+ category: Infrastruktur
+ websiteUrl: https://www.terraform.io
+ features:
+ - Modules
+ - State-Management
+ - Provider
+ tags:
+ - iac
+ - infrastructure
+
+- name: Ansible
+ description: Agentenlose Automatisierung für Konfiguration, Deploy und Orchestrierung
+ category: Infrastruktur
+ websiteUrl: https://www.ansible.com
+ features:
+ - Playbooks
+ - Inventories
+ - Modules
+ tags:
+ - automation
+ - configuration
+
+- name: Elasticsearch
+ description: Verteilter Such- und Analytics-Server für Logs, Metriken und Daten
+ category: Datenbank
+ websiteUrl: https://www.elastic.co
+ features:
+ - Volltextsuche
+ - Aggregationen
+ - Skalierung
+ tags:
+ - search
+ - analytics
+
+- name: Kubernetes
+ description: Container-Orchestrierung für Deployment, Skalierung und Betrieb
+ category: Infrastruktur
+ websiteUrl: https://kubernetes.io
+ features:
+ - Pods
+ - Services
+ - Autoskalierung
+ tags:
+ - containers
+ - orchestration
+
+- name: Sonarqube
+ description: Statische Code-Analyse und Qualitätsmessung für Softwareprojekte
+ category: Entwicklung
+ websiteUrl: https://www.sonarsource.com/products/sonarqube
+ features:
+ - Code-Qualität
+ - Security-Scans
+ - Quality Gates
+ tags:
+ - code-quality
+ - static-analysis
+
+- name: Power BI
+ description: Business-Intelligence-Tool für Dashboards, Berichte und Datenanalyse
+ category: Analytics
+ websiteUrl: https://powerbi.microsoft.com
+ features:
+ - Dashboards
+ - Berichte
+ - Datenmodelle
+ tags:
+ - bi
+ - analytics
+
+- name: Google Workspace
+ description: Produktivitäts-Suite mit E-Mail, Docs, Drive und Meet
+ category: Produktivität
+ websiteUrl: https://workspace.google.com
+ features:
+ - Gmail
+ - Google Docs
+ - Google Drive
+ tags:
+ - suite
+ - productivity
+
+- name: Microsoft 365
+ description: Office-Anwendungen, E-Mail und Cloud-Dienste für Unternehmen
+ category: Produktivität
+ websiteUrl: https://www.microsoft.com/microsoft-365
+ features:
+ - Word
+ - Excel
+ - Outlook
+ tags:
+ - suite
+ - productivity
+
+- name: Slack Enterprise Grid
+ description: Slack-Verwaltung für große Organisationen mit erweiterten Sicherheitsfunktionen
+ category: Kommunikation
+ websiteUrl: https://slack.com
+ features:
+ - Enterprise-Admin
+ - Compliance
+ - Multi-Workspace
+ tags:
+ - communication
+ - enterprise
+
+- name: Atlassian Rovo
+ description: KI-Assistent für Suche und Zusammenarbeit über Atlassian-Produkte
+ category: Projektmanagement
+ websiteUrl: https://www.atlassian.com/software/rovo
+ features:
+ - KI-Suche
+ - Agenten
+ - Integrationen
+ tags:
+ - ai
+ - search
\ No newline at end of file
diff --git a/docs/handbook/administration.md b/docs/handbook/administration.de.md
similarity index 96%
rename from docs/handbook/administration.md
rename to docs/handbook/administration.de.md
index 6dffd85..dd4e3ad 100644
--- a/docs/handbook/administration.md
+++ b/docs/handbook/administration.de.md
@@ -73,6 +73,9 @@ Zentraler Zugriff auf den Tool-Katalog.
category: Monitoring
```
+ Eine umfangreichere, fertig importierbare Beispieldatei liegt unter
+ `docs/examples/import-tools.yaml` (24 gängige Enterprise-Tools).
+
Beim Import werden einzelne fehlerhafte Zeilen übersprungen und mit Zeilennummer
aufgelistet; korrekte Zeilen werden trotzdem angelegt. Jeder Import erzeugt
Audit-Log-Einträge.
diff --git a/docs/handbook/administration.en.md b/docs/handbook/administration.en.md
index 1e87800..7d49841 100644
--- a/docs/handbook/administration.en.md
+++ b/docs/handbook/administration.en.md
@@ -73,6 +73,9 @@ Central access to the tool catalog.
category: Monitoring
```
+ A larger, ready-to-import example file is located at
+ `docs/examples/import-tools.yaml` (24 common enterprise tools).
+
During import, individual faulty rows are skipped and listed with their row
number; correct rows are still created. Every import produces audit-log
entries.
diff --git a/docs/handbook/analytics.md b/docs/handbook/analytics.de.md
similarity index 100%
rename from docs/handbook/analytics.md
rename to docs/handbook/analytics.de.md
diff --git a/docs/handbook/bewerten.md b/docs/handbook/bewerten.de.md
similarity index 100%
rename from docs/handbook/bewerten.md
rename to docs/handbook/bewerten.de.md
diff --git a/docs/handbook/datenmodell.md b/docs/handbook/datenmodell.de.md
similarity index 100%
rename from docs/handbook/datenmodell.md
rename to docs/handbook/datenmodell.de.md
diff --git a/docs/handbook/getting-started.md b/docs/handbook/getting-started.de.md
similarity index 100%
rename from docs/handbook/getting-started.md
rename to docs/handbook/getting-started.de.md
diff --git a/docs/handbook/index.md b/docs/handbook/index.de.md
similarity index 95%
rename from docs/handbook/index.md
rename to docs/handbook/index.de.md
index 66a8a7d..5988ccf 100644
--- a/docs/handbook/index.md
+++ b/docs/handbook/index.de.md
@@ -6,7 +6,7 @@ order: 1
# Willkommen bei toolr
toolr ist eine Plattform zum **Entdecken, Bewerten und Vergleichen von
-Entwicklungstools**. Nutzer:innen pflegen einen gemeinsamen Katalog von Tools,
+Entwicklungstools**. Nutzer pflegen einen gemeinsamen Katalog von Tools,
vergeben Bewertungen (Nützlichkeit & Bedienbarkeit) und nutzen Statistiken, um
die richtige Wahl zu treffen.
@@ -16,7 +16,7 @@ die richtige Wahl zu treffen.
| --- | --- | --- |
| **Tools durchsuchen** | Katalog filtern, sortieren und durchsuchen | Alle |
| **Tool anlegen** | Neues Tool mit Beschreibung, Kategorie, Features & Tags eintragen | Angemeldet |
-| **Tool bearbeiten/löschen** | Eigene Tools pflegen (Ersteller:in oder Admin) | Angemeldet |
+| **Tool bearbeiten/löschen** | Eigene Tools pflegen (Ersteller oder Admin) | Angemeldet |
| **Bewerten** | Nützlichkeit & Bedienbarkeit (1–5) plus Kommentar vergeben | Angemeldet |
| **Merkliste** | Tools als Favoriten speichern | Premium |
| **Vergleichen** | Tools nebeneinander gegenüberstellen | Premium |
diff --git a/docs/handbook/konto.md b/docs/handbook/konto.de.md
similarity index 100%
rename from docs/handbook/konto.md
rename to docs/handbook/konto.de.md
diff --git a/docs/handbook/kosten.md b/docs/handbook/kosten.de.md
similarity index 100%
rename from docs/handbook/kosten.md
rename to docs/handbook/kosten.de.md
diff --git a/docs/handbook/papierkorb.md b/docs/handbook/papierkorb.de.md
similarity index 100%
rename from docs/handbook/papierkorb.md
rename to docs/handbook/papierkorb.de.md
diff --git a/docs/handbook/plaene.md b/docs/handbook/plaene.de.md
similarity index 100%
rename from docs/handbook/plaene.md
rename to docs/handbook/plaene.de.md
diff --git a/docs/handbook/redundanz.md b/docs/handbook/redundanz.de.md
similarity index 100%
rename from docs/handbook/redundanz.md
rename to docs/handbook/redundanz.de.md
diff --git a/docs/handbook/tastatur.md b/docs/handbook/tastatur.de.md
similarity index 100%
rename from docs/handbook/tastatur.md
rename to docs/handbook/tastatur.de.md
diff --git a/docs/handbook/tool-anlegen.md b/docs/handbook/tool-anlegen.de.md
similarity index 100%
rename from docs/handbook/tool-anlegen.md
rename to docs/handbook/tool-anlegen.de.md
diff --git a/docs/handbook/tool-bearbeiten.md b/docs/handbook/tool-bearbeiten.de.md
similarity index 100%
rename from docs/handbook/tool-bearbeiten.md
rename to docs/handbook/tool-bearbeiten.de.md
diff --git a/docs/handbook/tools-finden.md b/docs/handbook/tools-finden.de.md
similarity index 99%
rename from docs/handbook/tools-finden.md
rename to docs/handbook/tools-finden.de.md
index 4f1e984..214228b 100644
--- a/docs/handbook/tools-finden.md
+++ b/docs/handbook/tools-finden.de.md
@@ -47,7 +47,7 @@ Mit **Filter zurücksetzen** bzw. **Alle entfernen** räumst du sie wieder auf.
- **Ansicht wechseln:** Raster / Tabelle / Zeilen.
- **Dichte:** gemütlich / kompakt (Schieberegler).
-Deine Auswahl wird gespeichert — lokal im Browser und für angemeldete Nutzer:innen
+Deine Auswahl wird gespeichert — lokal im Browser und für angemeldete Nutzer
zusätzlich serverseitig in den Präferenzen. Ansicht, Dichte, Suche, Filter und
Sortierung werden dabei in die URL übernommen, sodass du Ergebnisse teilen
kannst.
diff --git a/docs/handbook/vergleichen.md b/docs/handbook/vergleichen.de.md
similarity index 100%
rename from docs/handbook/vergleichen.md
rename to docs/handbook/vergleichen.de.md
diff --git a/docs/handbook/watchlist.md b/docs/handbook/watchlist.de.md
similarity index 100%
rename from docs/handbook/watchlist.md
rename to docs/handbook/watchlist.de.md
diff --git a/docs/releases/v0.6.0.en.md b/docs/releases/v0.6.0.en.md
deleted file mode 100644
index 8762f32..0000000
--- a/docs/releases/v0.6.0.en.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# v0.6.0 — Release Notes
-
-**Date:** 2026-08-03 · **Tag:** [`v0.6.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.6.0)
-
-## New features
-
-- Complete modernization of all dependencies to the current major versions
- (TypeScript 7, Vite 8, React 19.2, openid-client 6, zod 4, recharts 3, react-day-picker 10).
-
-## Fixes & improvements
-
-- CI build fixed via `allowBuilds` configuration for pnpm 11
- (build scripts for esbuild & Co. are no longer blocked).
-- Image tagging simplified: only `latest` and `v*` tags, no more `nightly-*`/`sha-*` tags.
-- All dependencies pinned exactly; automatic updates via Renovate prepared
- (`renovate.json`, `docs/dependency-policy.md`).
-
-## API changes
-
-- No breaking changes to the API. openid-client internally migrated to v6
- (auth flow behaves identically).
-
-## Operations / upgrade
-
-- **Env vars:** unchanged. Node image pinned to `node:24.18.1-alpine`.
-- **Migration:** no database migration required.
-- **Breaking changes:** none.
-
-## Known limitations
-
-- `typedoc` (indirect orval dependency) shows a peer-dependency warning
- (expects TypeScript 5.x/6.x, 7.x is installed) — harmless for build and runtime.
-
-## Links
-
-- Commit: [`2f66fff`](https://git.kubebase.de/admin/tool-evaluator/commit/2f66fff)
-- Tag: [`v0.6.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.6.0)
diff --git a/docs/releases/v0.6.0.md b/docs/releases/v0.6.0.md
deleted file mode 100644
index 6e254c0..0000000
--- a/docs/releases/v0.6.0.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# v0.6.0 — Release Notes
-
-**Datum:** 2026-08-03 · **Tag:** [`v0.6.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.6.0)
-
-## Neue Features
-
-- Vollständige Modernisierung aller Abhängigkeiten auf die aktuellen Hauptversionen
- (TypeScript 7, Vite 8, React 19.2, openid-client 6, zod 4, recharts 3, react-day-picker 10).
-
-## Fixes & Verbesserungen
-
-- CI-Build durch `allowBuilds`-Konfiguration für pnpm 11 repariert
- (Build-Scripts für esbuild & Co. werden nicht mehr blockiert).
-- Image-Tagging vereinfacht: nur noch `latest` und `v*`-Tags, keine `nightly-*`/`sha-*`-Tags.
-- Alle Dependencies exakt gepinnt; automatische Updates via Renovate vorbereitet
- (`renovate.json`, `docs/dependency-policy.md`).
-
-## API-Änderungen
-
-- Keine Breaking Changes an der API. openid-client intern auf v6 migriert
- (auth-Fluss verhält sich identisch).
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert. Node-Image auf `node:24.18.1-alpine` gepinnt.
-- **Migration:** keine Datenbank-Migration erforderlich.
-- **Breaking Changes:** keine.
-
-## Bekannte Einschränkungen
-
-- `typedoc` (indirekte orval-Abhängigkeit) zeigt eine Peer-Dependency-Warnung
- (erwartet TypeScript 5.x/6.x, installiert ist 7.x) — harmlos für Build & Laufzeit.
-
-## Links
-
-- Commit: [`2f66fff`](https://git.kubebase.de/admin/tool-evaluator/commit/2f66fff)
-- Tag: [`v0.6.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.6.0)
diff --git a/docs/releases/v0.7.0.en.md b/docs/releases/v0.7.0.en.md
deleted file mode 100644
index 2348c6e..0000000
--- a/docs/releases/v0.7.0.en.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# v0.7.0 — Release Notes
-
-**Date:** 2026-08-03 · **Tag:** [`v0.7.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.7.0)
-
-## New features
-
-- Version-bound **release documentation** in the app under `/docs`
- (index + detail page per version, Markdown from `docs/releases/`).
-- Generated release template (`docs/releases/TEMPLATE.md`) and
- sync step for the frontend build.
-
-## Fixes & improvements
-
-- `tsx` bumped to 4.23.4 — last outdated dependency in the workspace
- (`pnpm outdated -r` is now empty).
-
-## API changes
-
-- No breaking changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none.
-
-## Known limitations
-
-- The documentation is currently limited to release notes; a complete
- API/field reference will follow in v0.8.0.
-
-## Links
-
-- Commit: [`520f917`](https://git.kubebase.de/admin/tool-evaluator/commit/520f917)
-- Tag: [`v0.7.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.7.0)
diff --git a/docs/releases/v0.7.0.md b/docs/releases/v0.7.0.md
deleted file mode 100644
index daf5078..0000000
--- a/docs/releases/v0.7.0.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# v0.7.0 — Release Notes
-
-**Datum:** 2026-08-03 · **Tag:** [`v0.7.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.7.0)
-
-## Neue Features
-
-- Version-gebundene **Release-Dokumentation** in der App unter `/docs`
- (Index + Detailseite je Version, Markdown aus `docs/releases/`).
-- Generiertes Release-Vorlage (`docs/releases/TEMPLATE.md`) und
- Sync-Schritt für den Frontend-Build.
-
-## Fixes & Verbesserungen
-
-- `tsx` auf 4.23.4 angehoben — letzte veraltete Abhängigkeit im Workspace
- (`pnpm outdated -r` ist jetzt leer).
-
-## API-Änderungen
-
-- Keine Breaking Changes an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine.
-
-## Bekannte Einschränkungen
-
-- Die Doku ist bisher auf Release-Notes beschränkt; eine vollständige
- API-/Feld-Referenz folgt in v0.8.0.
-
-## Links
-
-- Commit: [`520f917`](https://git.kubebase.de/admin/tool-evaluator/commit/520f917)
-- Tag: [`v0.7.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.7.0)
diff --git a/docs/releases/v0.8.0.en.md b/docs/releases/v0.8.0.en.md
deleted file mode 100644
index 671391b..0000000
--- a/docs/releases/v0.8.0.en.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# v0.8.0 — Release Notes
-
-**Date:** 2026-08-03 · **Tag:** [`v0.8.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.0)
-
-## New features
-
-- **Complete documentation site** in mkdocs look under `/docs`:
- - **Manual** with understandable explanations of all features
- (Getting started, creating a tool, evaluations, comparing, watchlist,
- analytics, administration, data model).
- - **Automatically generated reference** from `lib/api-spec/openapi.yaml`:
- all endpoints and data fields (type, required status, constraints) —
- this guarantees that *every* feature is documented.
- - **Search** across the manual, endpoints, and fields.
- - **Version dropdown**: older releases keep their full field/endpoint
- reference as a snapshot.
- - **Repo link** to the source in the top right.
-- **Help buttons (?) in forms** (NetBox style): next to each field,
- an icon jumps directly to the field description in the docs.
-
-## Fixes & improvements
-
-- Docs generator `scripts/src/generate-docs.mjs` replaces the previous
- `sync-release-docs.mjs` (OpenAPI parsing, manual, search index, snapshots).
-- Documentation for v0.7.0 backfilled.
-
-## API changes
-
-- No breaking changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none.
-
-## Known limitations
-
-- Manual & reference apply to the current version; older versions
- show their release notes and a reference snapshot, if generated at
- release time (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`6c92b63`](https://git.kubebase.de/admin/tool-evaluator/commit/6c92b63)
-- Tag: [`v0.8.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.0)
diff --git a/docs/releases/v0.8.0.md b/docs/releases/v0.8.0.md
deleted file mode 100644
index 27e90d6..0000000
--- a/docs/releases/v0.8.0.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# v0.8.0 — Release Notes
-
-**Datum:** 2026-08-03 · **Tag:** [`v0.8.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.0)
-
-## Neue Features
-
-- **Vollständige Dokumentations-Site** in mkdocs-Optik unter `/docs`:
- - **Handbuch** mit verständlichen Erklärungen zu allen Features
- (Erste Schritte, Tool anlegen, Bewertungen, Vergleichen, Merkliste,
- Analytics, Administration, Datenmodell).
- - **Automatisch generierte Referenz** aus `lib/api-spec/openapi.yaml`:
- alle Endpunkte und Datenfelder (Typ, Pflichtstatus, Constraints) —
- damit ist garantiert, dass *jedes* Feature dokumentiert ist.
- - **Suche** über Handbuch, Endpunkte und Felder.
- - **Versions-Dropdown**: ältere Releases behalten ihre vollständige
- Feld-/Endpunkt-Referenz als Snapshot.
- - **Repo-Link** oben rechts zur Quelle.
-- **Hilfe-Buttons (?) in Formularen** (NetBox-Stil): neben jedem Feld
- springt ein Icon direkt zur Feldbeschreibung in der Doku.
-
-## Fixes & Verbesserungen
-
-- Doku-Generator `scripts/src/generate-docs.mjs` ersetzt den bisherigen
- `sync-release-docs.mjs` (OpenAPI-Parsing, Handbuch, Suchindex, Snapshots).
-- Dokumentation für v0.7.0 nachgezogen.
-
-## API-Änderungen
-
-- Keine Breaking Changes an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine.
-
-## Bekannte Einschränkungen
-
-- Handbuch & Referenz gelten für die aktuelle Version; ältere Versionen
- zeigen ihre Release-Notes und einen Referenz-Snapshot, sofern beim Release
- erzeugt (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`6c92b63`](https://git.kubebase.de/admin/tool-evaluator/commit/6c92b63)
-- Tag: [`v0.8.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.0)
diff --git a/docs/releases/v0.8.0/reference.json b/docs/releases/v0.8.0/reference.json
deleted file mode 100644
index a3adfd9..0000000
--- a/docs/releases/v0.8.0/reference.json
+++ /dev/null
@@ -1,2782 +0,0 @@
-{
- "tags": [
- {
- "name": "health",
- "description": "Health operations",
- "endpoints": [
- {
- "operationId": "healthCheck",
- "method": "GET",
- "path": "/healthz",
- "summary": "Health check",
- "description": "Returns server health status",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Healthy",
- "schema": {
- "kind": "ref",
- "value": "HealthStatus"
- }
- }
- ]
- },
- {
- "operationId": "getVersion",
- "method": "GET",
- "path": "/version",
- "summary": "Build version information",
- "description": "Returns the running build version, commit SHA and build date",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Version information",
- "schema": {
- "kind": "ref",
- "value": "VersionInfo"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "tools",
- "description": "Tool management",
- "endpoints": [
- {
- "operationId": "listTools",
- "method": "GET",
- "path": "/tools",
- "summary": "List all tools",
- "description": "",
- "parameters": [
- {
- "name": "category",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "sort",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "newest, top_rated, most_reviewed, name_asc, name_desc, recently_updated"
- },
- {
- "name": "tags",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tags; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "features",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated features; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "minRating",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "number"
- },
- "description": "Minimum average combined rating (0-5)",
- "constraints": "0–5"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of tools",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- }
- ]
- },
- {
- "operationId": "createTool",
- "method": "POST",
- "path": "/tools",
- "summary": "Create a new tool",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCompareTools",
- "method": "GET",
- "path": "/compare",
- "summary": "Compare tools side by side (premium)",
- "description": "",
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "required": true,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tool ids",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tools in requested order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Authentication required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getToolRatingHistory",
- "method": "GET",
- "path": "/tools/{id}/rating-history",
- "summary": "Get a tool's rating history over time",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating history",
- "schema": {
- "kind": "array",
- "value": "RatingHistoryItem"
- }
- },
- {
- "status": "400",
- "description": "Invalid id",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getTool",
- "method": "GET",
- "path": "/tools/{id}",
- "summary": "Get a tool by ID",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tool details",
- "schema": {
- "kind": "ref",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateTool",
- "method": "PATCH",
- "path": "/tools/{id}",
- "summary": "Update a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTool",
- "method": "DELETE",
- "path": "/tools/{id}",
- "summary": "Delete a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listTrashedTools",
- "method": "GET",
- "path": "/tools/trash",
- "summary": "List trashed (soft-deleted) tools",
- "description": "",
- "parameters": [
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of trashed tools",
- "schema": {
- "kind": "array",
- "value": "Tool"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "trashTools",
- "method": "POST",
- "path": "/tools/trash",
- "summary": "Move tools to trash (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools trashed",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTrashedTools",
- "method": "DELETE",
- "path": "/tools/trash",
- "summary": "Permanently delete trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "restoreTools",
- "method": "POST",
- "path": "/tools/trash/restore",
- "summary": "Restore trashed tools",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools restored",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "emptyTrash",
- "method": "POST",
- "path": "/tools/trash/empty",
- "summary": "Permanently delete all trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Trash emptied",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCategories",
- "method": "GET",
- "path": "/categories",
- "summary": "List all distinct tool categories",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Categories list",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllFeatures",
- "method": "GET",
- "path": "/features/all",
- "summary": "List all distinct feature strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known features",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllTags",
- "method": "GET",
- "path": "/tags/all",
- "summary": "List all distinct tag strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known tags",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "ratings",
- "description": "Tool ratings",
- "endpoints": [
- {
- "operationId": "listToolRatings",
- "method": "GET",
- "path": "/tools/{id}/ratings",
- "summary": "List ratings for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Ratings list",
- "schema": {
- "kind": "array",
- "value": "Rating"
- }
- }
- ]
- },
- {
- "operationId": "createRating",
- "method": "POST",
- "path": "/tools/{id}/ratings",
- "summary": "Submit a rating for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "RatingInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created rating",
- "schema": {
- "kind": "ref",
- "value": "Rating"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "Tool not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "analytics",
- "description": "Analytics and aggregated statistics",
- "endpoints": [
- {
- "operationId": "getAnalyticsSummary",
- "method": "GET",
- "path": "/analytics/summary",
- "summary": "Overall platform statistics",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Platform-level summary stats",
- "schema": {
- "kind": "ref",
- "value": "AnalyticsSummary"
- }
- }
- ]
- },
- {
- "operationId": "getTopTools",
- "method": "GET",
- "path": "/analytics/top-tools",
- "summary": "Top-rated tools",
- "description": "",
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "metric",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "usefulness, usability, combined"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Top tools list",
- "schema": {
- "kind": "array",
- "value": "TopToolEntry"
- }
- }
- ]
- },
- {
- "operationId": "getAnalyticsByCategory",
- "method": "GET",
- "path": "/analytics/by-category",
- "summary": "Rating statistics grouped by category",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Per-category statistics",
- "schema": {
- "kind": "array",
- "value": "CategoryStats"
- }
- }
- ]
- },
- {
- "operationId": "getRatingDistribution",
- "method": "GET",
- "path": "/analytics/rating-distribution",
- "summary": "Distribution of rating scores across the platform",
- "description": "",
- "parameters": [
- {
- "name": "toolId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating score distribution",
- "schema": {
- "kind": "ref",
- "value": "RatingDistribution"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "auth",
- "description": "Authentication",
- "endpoints": [
- {
- "operationId": "getAuthMode",
- "method": "GET",
- "path": "/auth/mode",
- "summary": "Get authentication mode (oidc or local)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Auth mode",
- "schema": {
- "kind": "ref",
- "value": "AuthMode"
- }
- }
- ]
- },
- {
- "operationId": "getCsrfToken",
- "method": "GET",
- "path": "/auth/csrf",
- "summary": "Get a CSRF token for state-changing requests",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "CSRF token",
- "schema": {
- "kind": "ref",
- "value": "CsrfToken"
- }
- }
- ]
- },
- {
- "operationId": "localLogin",
- "method": "POST",
- "path": "/auth/login",
- "summary": "Local username/password login",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "LocalLoginInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Logged in successfully",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Invalid credentials",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMe",
- "method": "GET",
- "path": "/auth/me",
- "summary": "Get current authenticated user",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Current user info",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "changeMyPassword",
- "method": "POST",
- "path": "/auth/me/password",
- "summary": "Change own password (local users only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ChangePasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password changed",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Invalid input or wrong current password",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getPasswordRedirect",
- "method": "GET",
- "path": "/auth/password-redirect",
- "summary": "Get redirect URL for managing credentials in the identity provider",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Redirect URL (null in local mode)",
- "schema": {
- "kind": "ref",
- "value": "PasswordRedirect"
- }
- }
- ]
- },
- {
- "operationId": "getMePreferences",
- "method": "GET",
- "path": "/auth/me/preferences",
- "summary": "Get current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateMePreferences",
- "method": "PUT",
- "path": "/auth/me/preferences",
- "summary": "Update current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMeWatchlist",
- "method": "GET",
- "path": "/auth/me/watchlist",
- "summary": "Get current user's watchlist tools (premium)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Watchlist tools in saved order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "users",
- "description": "User management (admin only)",
- "endpoints": [
- {
- "operationId": "listUsers",
- "method": "GET",
- "path": "/users",
- "summary": "List all local users (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User list",
- "schema": {
- "kind": "array",
- "value": "User"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Forbidden",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "createUser",
- "method": "POST",
- "path": "/users",
- "summary": "Create a new local user (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserCreateInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "409",
- "description": "Username already exists",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateUser",
- "method": "PATCH",
- "path": "/users/{id}",
- "summary": "Update user role (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserRoleUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteUser",
- "method": "DELETE",
- "path": "/users/{id}",
- "summary": "Delete a user (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- }
- ]
- },
- {
- "operationId": "setUserPassword",
- "method": "PATCH",
- "path": "/users/{id}/password",
- "summary": "Set/reset a user's password (admin only, local users only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "SetPasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password updated",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "audit",
- "description": "Audit log",
- "endpoints": [
- {
- "operationId": "listAuditLogs",
- "method": "GET",
- "path": "/audit-logs",
- "summary": "List audit log entries (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "entityType",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Audit log entries",
- "schema": {
- "kind": "array",
- "value": "AuditLog"
- }
- }
- ]
- }
- ]
- }
- ],
- "schemas": [
- {
- "name": "HealthStatus",
- "description": "",
- "fields": [
- {
- "name": "status",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "VersionInfo",
- "description": "",
- "fields": [
- {
- "name": "version",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "commitSha",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "buildDate",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "trashRetentionDays",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthMode",
- "description": "",
- "fields": [
- {
- "name": "mode",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "oidc, local"
- }
- ]
- },
- {
- "name": "CsrfToken",
- "description": "",
- "fields": [
- {
- "name": "token",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "LocalLoginInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "User",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "authProvider",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "local, oidc"
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "UserCreateInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 2 chars"
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "UserRoleUpdate",
- "description": "",
- "fields": [
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "ChangePasswordInput",
- "description": "",
- "fields": [
- {
- "name": "currentPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "newPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "SetPasswordInput",
- "description": "",
- "fields": [
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "PasswordRedirect",
- "description": "",
- "fields": [
- {
- "name": "url",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuditLog",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityType",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "type": {
- "kind": "type",
- "value": "integer | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "action",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "userId",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "changes",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "Tool",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedAt",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingHistoryItem",
- "description": "",
- "fields": [
- {
- "name": "date",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "combined",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolWithStats",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolInput",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolUpdate",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TrashToolsInput",
- "description": "",
- "fields": [
- {
- "name": "ids",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 items, max 500 items"
- }
- ]
- },
- {
- "name": "Rating",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolId",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "RatingInput",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AnalyticsSummary",
- "description": "",
- "fields": [
- {
- "name": "totalTools",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "categoriesCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "mostRatedTool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TopToolEntry",
- "description": "",
- "fields": [
- {
- "name": "tool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "CategoryStats",
- "description": "",
- "fields": [
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingDistribution",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ScoreBucket",
- "description": "",
- "fields": [
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "count",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthUser",
- "description": "",
- "fields": [
- {
- "name": "sub",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "preferredUsername",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "entitlements",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "isLocal",
- "type": {
- "kind": "type",
- "value": "boolean"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "UserPreferences",
- "description": "",
- "fields": [
- {
- "name": "view",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "grid, table, rows"
- },
- {
- "name": "density",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "cozy, compact"
- },
- {
- "name": "watchlist",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ErrorResponse",
- "description": "",
- "fields": [
- {
- "name": "error",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/docs/releases/v0.8.1.en.md b/docs/releases/v0.8.1.en.md
deleted file mode 100644
index a865280..0000000
--- a/docs/releases/v0.8.1.en.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# v0.8.1 — Release Notes
-
-**Date:** 2026-08-03 · **Tag:** [`v0.8.1`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.1)
-
-## New features
-
-- **Standalone docs page**: The documentation is now available as its own,
- mkdocs-like page at `toolr.kubebase.de/docs` — without the app shell
- (own header with repo link, version dropdown, search, theme toggle
- and link back to the app).
-- **Navigation renamed**: The sidebar entry is now called **"Help"**
- and leads to the standalone docs.
-- **User guide completely revised**: 17 manual pages with
- step-by-step instructions for all features (finding tools, creating a
- tool, evaluating, watchlist, comparing, costs, analytics, plans,
- administration, redundancy, trash, keyboard shortcuts, data model).
-
-## Fixes & improvements
-
-- Reference links are now case-insensitive
- (schema/endpoint slugs such as `toolinput` and `ToolInput` both work).
-- Manual links to endpoint anchors corrected (PascalCase operation IDs).
-- Outdated, broken manual links (`vergleichen`, `watchlist` …) replaced.
-- Documentation table headers and notice texts in the docs page
- internationalized via i18n (de/en).
-
-## API changes
-
-- No changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none. The docs page is reachable under `/docs` as
- before; only the presentation is now standalone.
-
-## Known limitations
-
-- Manual & reference apply to the current version; older versions show
- their release notes and a reference snapshot, if generated at release time
- (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`fdf2d74`](https://git.kubebase.de/admin/tool-evaluator/commit/fdf2d74)
-- Tag: [`v0.8.1`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.1)
diff --git a/docs/releases/v0.8.1.md b/docs/releases/v0.8.1.md
deleted file mode 100644
index f6cab2c..0000000
--- a/docs/releases/v0.8.1.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# v0.8.1 — Release Notes
-
-**Datum:** 2026-08-03 · **Tag:** [`v0.8.1`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.1)
-
-## Neue Features
-
-- **Standalone-Doku-Seite**: Die Dokumentation steht jetzt als eigene,
- mkdocs-artige Seite unter `toolr.kubebase.de/docs` — ohne die App-Shell
- (eigene Kopfzeile mit Repo-Link, Versions-Dropdown, Suche, Theme-Umschalter
- und Link zurück zur App).
-- **Navigation umbenannt**: Der Seitenleisten-Eintrag heißt jetzt **„Hilfe"**
- und führt zur Standalone-Doku.
-- **User Guide komplett überarbeitet**: 17 Handbuch-Seiten mit
- Schritt-für-Schritt-Anleitungen für alle Funktionen (Tools finden, Tool
- anlegen, Bewerten, Merkliste, Vergleichen, Kosten, Analytics, Pläne,
- Administration, Redundanz, Papierkorb, Tastenkürzel, Datenmodell).
-
-## Fixes & Verbesserungen
-
-- Referenz-Links sind jetzt unabhängig von Groß-/Kleinschreibung
- (Schema-/Endpoint-Slugs wie `toolinput` und `ToolInput` funktionieren beide).
-- Handbuch-Links auf Endpunkt-Anker korrigiert (PascalCase-OperationIds).
-- Veraltete, kaputte Handbuch-Links (`vergleichen`, `watchlist` …) ersetzt.
-- Dokumentations-Tabellenkopfzeilen und Hinweistexte in der Doku-Seite über
- i18n internationalisiert (de/en).
-
-## API-Änderungen
-
-- Keine Änderungen an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine. Die Doku-Seite ist unter `/docs` erreichbar wie
- bisher; lediglich die Darstellung ist nun eigenständig.
-
-## Bekannte Einschränkungen
-
-- Handbuch & Referenz gelten für die aktuelle Version; ältere Versionen zeigen
- ihre Release-Notes und einen Referenz-Snapshot, sofern beim Release erzeugt
- (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`fdf2d74`](https://git.kubebase.de/admin/tool-evaluator/commit/fdf2d74)
-- Tag: [`v0.8.1`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.1)
diff --git a/docs/releases/v0.8.1/handbook/administration.en.md b/docs/releases/v0.8.1/handbook/administration.en.md
deleted file mode 100644
index 9fe7806..0000000
--- a/docs/releases/v0.8.1/handbook/administration.en.md
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# Administration
-
-The **Admin** area (`/admin`) is exclusively accessible to admins.
-Without the admin role, access is denied.
-
-> At the top right, the **Redundancy dashboard** button leads to the automatic
-> duplicate detection (see [Redundancy](/docs/handbook/redundanz)).
-
-## "Users" tab
-
-Management of local accounts.
-
-- **Add user:** username (required), password (at least 6 characters),
- email (optional), **role** (User/Admin), **plan** (Free/Premium/Enterprise).
-- **Edit user:** set role, plan and (for local accounts) a new password.
- For OIDC accounts, password management is offered in the identity provider
- (e.g. Keycloak).
-- **Delete user:** permanently removes the account (not for your own account).
-
-API reference:
-[`POST /users`](/docs/reference/endpoints/users#createUser),
-[`PATCH /users/{id}`](/docs/reference/endpoints/users#updateUser),
-[`DELETE /users/{id}`](/docs/reference/endpoints/users#deleteUser).
-
-## "Tools" tab
-
-Central access to the tool catalog.
-
-- **Search** for tools.
-- View, edit or move individual tools to the trash.
-- **Bulk action:** select multiple tools and move them to the trash
- (confirmation dialog; soft-deleted tools are removed from all public views
- and can be restored or permanently deleted).
-
-## "Audit log" tab
-
-Chronological log of all creation, change and deletion operations
-(max. 100 entries): action, entity + ID, timestamp, executing person and
-changed fields.
-
-API reference: [`GET /audit-logs`](/docs/reference/endpoints/audit#listAuditLogs).
-
-## "System" tab
-
-Version information of the running instance:
-
-- **Version** (e.g. `v0.8.1`),
-- **Commit** (7-digit SHA, linked to the repository),
-- **Build date**,
-- **Trash retention** ("N days" or "Forever").
-
-## Tool links (Admin)
-
-On the detail page of a tool you can manage **links** as an admin
-(own/"manual" as well as automatically detected ones):
-
-- **Link tool:** dialog with tool ID, **relationship type**
- (Similar / Replaces / Superseded by) and optional notes.
-- Relationship types are displayed as badges on the detail page.
-- Manual links can be removed again via the trash icon.
diff --git a/docs/releases/v0.8.1/handbook/administration.md b/docs/releases/v0.8.1/handbook/administration.md
deleted file mode 100644
index 585e0ce..0000000
--- a/docs/releases/v0.8.1/handbook/administration.md
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# Administration
-
-Der Bereich **Admin** (`/admin`) ist ausschließlich für Admins zugänglich.
-Ohne Admin-Rolle erscheint eine Zugriffsverweigerung.
-
-> Oben rechts führt die Schaltfläche **Redundanz-Dashboard** zur automatischen
-> Doppelungs-Erkennung (siehe [Redundanz](/docs/handbook/redundanz)).
-
-## Tab „Nutzer"
-
-Verwaltung der lokalen Konten.
-
-- **Nutzer hinzufügen:** Benutzername (Pflicht), Passwort (mind. 6 Zeichen),
- E-Mail (optional), **Rolle** (User/Admin), **Tarif** (Free/Premium/Enterprise).
-- **Nutzer bearbeiten:** Rolle, Tarif und (für lokale Konten) ein neues Passwort
- setzen. Für OIDC-Konten wird die Passwortverwaltung im Identitätsanbieter
- (z. B. Keycloak) angeboten.
-- **Nutzer löschen:** Entfernt das Konto endgültig (nicht für das eigene Konto).
-
-API-Referenz:
-[`POST /users`](/docs/reference/endpoints/users#createUser),
-[`PATCH /users/{id}`](/docs/reference/endpoints/users#updateUser),
-[`DELETE /users/{id}`](/docs/reference/endpoints/users#deleteUser).
-
-## Tab „Tools"
-
-Zentraler Zugriff auf den Tool-Katalog.
-
-- **Suchen** nach Tools.
-- Tools einzeln ansehen, bearbeiten oder in den Papierkorb verschieben.
-- **Massenaktion:** mehrere Tools auswählen und in den Papierkorb verschieben
- (Bestätigungsdialog; soft gelöschte Tools sind aus allen öffentlichen Ansichten
- entfernt und können wiederhergestellt oder endgültig gelöscht werden).
-
-## Tab „Audit-Log"
-
-Chronologisches Protokoll aller Anlage-, Änderungs- und Löschvorgänge
-(max. 100 Einträge): Aktion, Entität + ID, Zeitstempel, ausführende Person und
-geänderte Felder.
-
-API-Referenz: [`GET /audit-logs`](/docs/reference/endpoints/audit#listAuditLogs).
-
-## Tab „System"
-
-Versionsinformationen der laufenden Instanz:
-
-- **Version** (z. B. `v0.8.1`),
-- **Commit** (7-stelliger SHA, verlinkt zum Repository),
-- **Build-Datum**,
-- **Papierkorb-Aufbewahrung** („N Tage" oder „Für immer").
-
-## Tool-Verknüpfungen (Admin)
-
-Auf der Detailseite eines Tools kannst du als Admin **Verknüpfungen**
-(eigene/„manual" sowie automatisch erkannte) verwalten:
-
-- **Tool verknüpfen:** Dialog mit Tool-ID, **Beziehungstyp**
- (Ähnlich / Ersetzt / Abgelöst durch) und optionalen Notizen.
-- Beziehungstypen werden als Badges auf der Detailseite angezeigt.
-- Manuelle Verknüpfungen lassen sich per Papierkorb-Icon wieder entfernen.
diff --git a/docs/releases/v0.8.1/handbook/getting-started.md b/docs/releases/v0.8.1/handbook/getting-started.md
deleted file mode 100644
index 0fd7820..0000000
--- a/docs/releases/v0.8.1/handbook/getting-started.md
+++ /dev/null
@@ -1,53 +0,0 @@
-
-# Erste Schritte
-
-Diese Seite führt dich durch die wichtigsten Abläufe in toolr — vom ersten
-Besuch bis zum Anlegen und Bewerten eines Tools.
-
-## 1. Anmelden
-
-Die meisten Aktionen (Tool anlegen, bewerten, Watchlist, Vergleichen) erfordern
-ein Konto. Klicke unten links auf **Anmelden**. Je nach Konfiguration der
-Instanz hast du zwei Möglichkeiten:
-
-- **Lokale Konten:** Benutzername + Passwort. Der Zugang wird von einem Admin
- angelegt (siehe [Administration](/docs/handbook/administration)).
-- **OIDC (SSO):** Anmelden mit dem konfigurierten Identitätsanbieter (z. B.
- Keycloak).
-
-Welcher Modus aktiv ist, steht im Endpunkt
-[`GET /auth/mode`](/docs/reference/endpoints/auth#getAuthMode). Details findest
-du im Abschnitt [Anmelden & Konto](/docs/handbook/konto).
-
-## 2. Tools finden
-
-Öffne den Bereich **Tools durchsuchen**:
-
-- **Suchen** — Volltextsuche über Name & Beschreibung (Tastenkürzel `/`).
-- **Filtern** — nach Kategorie, Tags, Features und Mindestbewertung
- (`minRating`).
-- **Sortieren** — nach Aktualität, Top-Bewertung, meistbewertet, Name
- (auf-/absteigend) oder letztem Update.
-
-Alle Optionen im Detail: [Tools finden & durchsuchen](/docs/handbook/tools-finden).
-
-## 3. Tool anlegen
-
-Gehe auf **Tool hinzufügen** und fülle das Formular aus. Details zu jedem Feld
-findest du im Abschnitt [Tool anlegen](/docs/handbook/tool-anlegen) und in der
-[Feld-Referenz](/docs/reference/schemas/toolinput).
-
-## 4. Bewerten
-
-Auf der Detailseite eines Tools kannst du **Nützlichkeit** und **Bedienbarkeit**
-(jeweils 1–5) vergeben und optional einen Kommentar hinterlassen. Deine
-Bewertung fließt sofort in die Statistiken ein.
-Siehe [Bewerten](/docs/handbook/bewerten).
-
-## 5. Weiterführend
-
-- [Tools vergleichen](/docs/handbook/vergleichen)
-- [Watchlist](/docs/handbook/watchlist)
-- [Analytics](/docs/handbook/analytics)
-- [Pläne & Berechtigungen](/docs/handbook/plaene)
-- [Administration](/docs/handbook/administration)
diff --git a/docs/releases/v0.8.1/handbook/index.en.md b/docs/releases/v0.8.1/handbook/index.en.md
deleted file mode 100644
index 490c2c5..0000000
--- a/docs/releases/v0.8.1/handbook/index.en.md
+++ /dev/null
@@ -1,51 +0,0 @@
-
-# Welcome to toolr
-
-toolr is a platform for **discovering, rating and comparing development
-tools**. Users maintain a shared catalog of tools, submit ratings
-(usefulness & usability) and use statistics to make the right choice.
-
-## What can you do with toolr?
-
-| Function | Description | Visibility |
-| --- | --- | --- |
-| **Browse tools** | Filter, sort and search the catalog | Everyone |
-| **Create a tool** | Add a new tool with description, category, features & tags | Logged in |
-| **Edit/delete tools** | Maintain your own tools (creator or admin) | Logged in |
-| **Rate** | Submit usefulness & usability (1–5) plus a comment | Logged in |
-| **Watchlist** | Save tools as favorites | Premium |
-| **Compare** | View tools side by side | Premium |
-| **Record costs** | Enter license and cost models per tool | Premium |
-| **Analytics** | Statistics, top tools, distributions | Everyone |
-| **Trash** | Restore soft-deleted tools or delete them permanently | Premium |
-| **Admin** | User management, audit log, system information | Admin |
-| **Redundancy detection** | Automatic duplicate detection | Admin |
-
-## How this documentation is organized
-
-- **User Guide** (these pages): step-by-step instructions for all
- functions — from the [Getting Started](/docs/handbook/getting-started) to
- [Administration](/docs/handbook/administration).
-- **API Reference**: automatically generated from the OpenAPI specification —
- all [endpoints](/docs/reference/endpoints/tools) and
- [data fields](/docs/reference/schemas/toolinput) of the current version.
-- **Release Notes**: what is new in each [version](/docs/releases/v0.8.1).
-
-## Getting started
-
-The fastest way:
-
-1. **Sign in** — without an account you can only browse
- (see [Getting Started](/docs/handbook/getting-started#1-anmelden)).
-2. **Find tools** — search, filters and sorting in the
- [Browse tools](/docs/handbook/tools-finden) section.
-3. **Create a tool** — via "Add tool"
- ([guide](/docs/handbook/tool-anlegen)).
-4. **Rate** — on the detail page of a tool
- ([guide](/docs/handbook/bewerten)).
-
-## Contact & source code
-
-The source code is available at
-[git.kubebase.de/admin/tool-evaluator](https://git.kubebase.de/admin/tool-evaluator) —
-you can reach it at any time via the repository icon in the top right corner.
diff --git a/docs/releases/v0.8.1/handbook/konto.md b/docs/releases/v0.8.1/handbook/konto.md
deleted file mode 100644
index 40aae3d..0000000
--- a/docs/releases/v0.8.1/handbook/konto.md
+++ /dev/null
@@ -1,53 +0,0 @@
-
-# Anmelden & Konto
-
-## Anmelden
-
-Klicke unten links in der Seitenleiste auf **Anmelden**. Je nach Konfiguration
-der Instanz:
-
-- **Lokale Konten:** Benutzername und Passwort eingeben. Die Konten werden von
- einem Admin angelegt (siehe [Administration](/docs/handbook/administration)).
-- **OIDC (SSO):** Du wirst an den konfigurierten Identitätsanbieter
- weitergeleitet und meldest dich dort an.
-
-Der aktive Modus steht im Endpunkt
-[`GET /auth/mode`](/docs/reference/endpoints/auth#getAuthMode).
-
-> Die Login-Seite erreichst du direkt unter `/login`. Nach erfolgreicher
-> Anmeldung wirst du zur ursprünglich aufgerufenen Seite zurückgeleitet.
-
-## Benutzerprofil
-
-Dein Profil (Avatar, Name, E-Mail, Tarif) siehst du unten links im
-Benutzermenü. Dort stehen dir folgende Aktionen zur Verfügung:
-
-- **Watchlist** — deine gespeicherten Tools (nur mit dem entsprechenden Tarif).
-- **Papierkorb** — wiederherstellbare, gelöschte Tools (Premium/Enterprise).
-- **Passwort ändern** — für lokale Konten direkt in toolr; für OIDC-Konten wird
- die Passwortverwaltung im Identitätsanbieter angeboten.
-- **Abmelden** — beendet deine Sitzung.
-
-## Passwort ändern (lokales Konto)
-
-1. Öffne das Benutzermenü unten links.
-2. Wähle **Passwort ändern**.
-3. Gib das **aktuelle** sowie ein **neues** Passwort ein (mind. 6 Zeichen) und
- bestätige es.
-4. Speichern — das Passwort wird sofort übernommen.
-
-API-Referenz: [`POST /auth/me/password`](/docs/reference/endpoints/auth#changeMyPassword).
-
-## Anzeigeeinstellungen
-
-Über die Schaltflächen oben rechts kannst du:
-
-- **Sprache** wechseln (Deutsch / Englisch),
-- **Theme** umschalten (Hell / Dunkel / System),
-- die **Listenansicht** und **Dichte** im Bereich Tools durchsuchen anpassen
- (siehe [Tools finden & durchsuchen](/docs/handbook/tools-finden)).
-
-Deine Präferenzen (inkl. Watchlist) werden im Endpunkt
-[`GET /auth/me/preferences`](/docs/reference/endpoints/auth#getMePreferences)
-gespeichert und über [`PUT /auth/me/preferences`](/docs/reference/endpoints/auth#updateMePreferences)
-aktualisiert.
diff --git a/docs/releases/v0.8.1/handbook/plaene.en.md b/docs/releases/v0.8.1/handbook/plaene.en.md
deleted file mode 100644
index f73d6dc..0000000
--- a/docs/releases/v0.8.1/handbook/plaene.en.md
+++ /dev/null
@@ -1,41 +0,0 @@
-
-# Plans & Permissions
-
-toolr distinguishes **plans** (tier) and **roles**. Admins bypass all feature
-restrictions.
-
-## Plans
-
-| Plan | Description |
-| --- | --- |
-| **Free** | Basic functions: search, filter, view, analytics |
-| **Premium** | Additionally watchlist, compare, trash, costs |
-| **Enterprise** | All premium features + extended support |
-
-### Feature permissions
-
-Premium/Enterprise unlock the following features:
-
-| Feature | Function | Learn more |
-| --- | --- | --- |
-| `compare` | Compare tools | [Compare](/docs/handbook/vergleichen) |
-| `watchlist` | Favorites list | [Watchlist](/docs/handbook/watchlist) |
-| `trash` | Trash (soft-deleted tools) | [Trash](/docs/handbook/papierkorb) |
-| `costs` | Record cost/license models | [Recording costs](/docs/handbook/kosten) |
-
-If you are missing a feature, the app shows an **upgrade notice** with a link
-to the plan management.
-
-## Roles
-
-| Role | Permissions |
-| --- | --- |
-| **User** | Standard account: create/rate tools, edit your own tools |
-| **Admin** | All user rights + administration, audit log, redundancy, empty trash, tool links |
-
-Admins pass **all** feature checks — even without a premium plan.
-
-## Plan/role management
-
-The assignment of role and plan is managed by admins in the
-[Administration](/docs/handbook/administration) section (tab "Users").
diff --git a/docs/releases/v0.8.1/handbook/plaene.md b/docs/releases/v0.8.1/handbook/plaene.md
deleted file mode 100644
index d4546b7..0000000
--- a/docs/releases/v0.8.1/handbook/plaene.md
+++ /dev/null
@@ -1,41 +0,0 @@
-
-# Pläne & Berechtigungen
-
-toolr unterscheidet **Tarife** (Tier) und **Rollen**. Admins umgehen alle
-Feature-Beschränkungen.
-
-## Tarife
-
-| Tarif | Beschreibung |
-| --- | --- |
-| **Free** | Grundfunktionen: suchen, filtern, ansehen, Analytics |
-| **Premium** | Zusätzlich Watchlist, Vergleichen, Papierkorb, Kosten |
-| **Enterprise** | Alle Premium-Features + erweiterter Support |
-
-### Feature-Berechtigungen
-
-Premium/Enterprise schalten folgende Features frei:
-
-| Feature | Funktion | Mehr erfahren |
-| --- | --- | --- |
-| `compare` | Tools vergleichen | [Vergleichen](/docs/handbook/vergleichen) |
-| `watchlist` | Favoritenliste | [Watchlist](/docs/handbook/watchlist) |
-| `trash` | Papierkorb (soft gelöschte Tools) | [Papierkorb](/docs/handbook/papierkorb) |
-| `costs` | Kosten-/Lizenzmodelle erfassen | [Kosten erfassen](/docs/handbook/kosten) |
-
-Fehlt dir ein Feature, zeigt die App einen **Upgrade-Hinweis** mit Link zur
-Tarifverwaltung.
-
-## Rollen
-
-| Rolle | Berechtigungen |
-| --- | --- |
-| **User** | Standard-Konto: Tools anlegen/bewerten, eigene Tools bearbeiten |
-| **Admin** | Alle User-Rechte + Verwaltung, Audit-Log, Redundanz, Papierkorb leeren, Tool-Verknüpfungen |
-
-Admins passieren **alle** Feature-Checks — auch ohne Premium-Tarif.
-
-## Tarif-/Rollenverwaltung
-
-Die Zuordnung von Rolle und Tarif wird durch Admins im Bereich
-[Administration](/docs/handbook/administration) (Tab „Nutzer") verwaltet.
diff --git a/docs/releases/v0.8.1/handbook/tastatur.md b/docs/releases/v0.8.1/handbook/tastatur.md
deleted file mode 100644
index 7eb6f17..0000000
--- a/docs/releases/v0.8.1/handbook/tastatur.md
+++ /dev/null
@@ -1,36 +0,0 @@
-
-# Tastenkürzel & Kommandopalette
-
-## Kommandopalette
-
-Die Kommandopalette ist die zentrale Schnellnavigation:
-
-- Öffnen mit **`⌘K`** (macOS) bzw. **`Ctrl+K`** (Windows/Linux).
-- Alternativ über die Suchleiste oben rechts („Tools suchen… ⌘K") oder das
- Such-Icon auf Mobilgeräten.
-
-### Leerer Zustand
-
-Ohne Eingabe zeigt die Palette:
-
-- **Zuletzt angesehen** — die letzten 5 Tools, die du besucht hast.
-- **Navigation** — Tools durchsuchen, Tool hinzufügen, Analytics sowie
- (abhängig von Berechtigungen) Watchlist, Papierkorb und Admin.
-
-### Suche
-
-Tippe, um live nach Tools zu suchen (max. 10 Ergebnisse, inkl. Bewertung
-`X.X★`).
-
-## Tastenkürzel im Überblick
-
-| Kürzel | Aktion |
-| --- | --- |
-| `⌘K` / `Ctrl+K` | Kommandopalette öffnen |
-| `/` | Suche im Bereich „Tools durchsuchen" fokussieren |
-
-## Weitere Hinweise
-
-- **Zuletzt angesehen** wird lokal im Browser gespeichert (max. 5 Einträge).
-- Die Seitenleiste (linke Navigation) ist auf Desktop einklappbar; der
- Breadcrumb oben zeigt deinen aktuellen Ort.
diff --git a/docs/releases/v0.8.1/handbook/tools-finden.md b/docs/releases/v0.8.1/handbook/tools-finden.md
deleted file mode 100644
index c976515..0000000
--- a/docs/releases/v0.8.1/handbook/tools-finden.md
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# Tools finden & durchsuchen
-
-Der Bereich **Tools durchsuchen** (`/tools`) ist der Einstieg in den Katalog.
-Hier kombinierst du Suche, Filter und Sortierung, um genau die Tools zu finden,
-die dich interessieren.
-
-## Suche
-
-- Die **Suchleiste** durchsucht Name und Beschreibung (Volltext).
-- Tastenkürzel: Drücke **`/`**, um die Suche zu fokussieren.
-- Die Eingabe ist deaktiviert (Debounce), damit bei jedem Tastendruck sofort
- nachgefiltert wird.
-
-## Filtern
-
-Über die Schaltfläche **Filter** (mit Badge für die Anzahl aktiver Filter)
-öffnest du den Filter-Popover mit:
-
-- **Tags** — Auswahl über Checkboxen (scrollbare Liste).
-- **Features** — Auswahl über Checkboxen.
-- **Mindestbewertung** — Schieberegler von 0 bis 5 (Schritte von 0,5); zeigt
- z. B. „3.0+" an.
-
-Aktive Filter erscheinen als **entfernbare Chips** über der Ergebnisliste.
-Mit **Filter zurücksetzen** bzw. **Alle entfernen** räumst du sie wieder auf.
-
-## Sortieren
-
-Über das Dropdown **Sortieren** stehen folgende Optionen zur Verfügung:
-
-| Sortierung | Beschreibung |
-| --- | --- |
-| Neueste | Neue Tools zuerst |
-| Top bewertet | Nach kombinierter Bewertung |
-| Meistbewertet | Nach Anzahl der Bewertungen |
-| Name (A–Z) | Alphabetisch aufsteigend |
-| Name (Z–A) | Alphabetisch absteigend |
-| Zuletzt aktualisiert | Nach letztem Update |
-
-## Ansicht & Dichte
-
-- **Ansicht wechseln:** Raster / Tabelle / Zeilen.
-- **Dichte:** gemütlich / kompakt (Schieberegler).
-
-Deine Auswahl wird gespeichert — lokal im Browser und für angemeldete Nutzer:innen
-zusätzlich serverseitig in den Präferenzen. Ansicht, Dichte, Suche, Filter und
-Sortierung werden dabei in die URL übernommen, sodass du Ergebnisse teilen
-kannst.
-
-## Tabellenansicht
-
-In der Tabellenansicht sind die Spalten **Tool**, **Bewertung** und **Anzahl
-Bewertungen** sortierbar. Beim Überfahren einer Zeile erscheint eine Vorschau
-mit Bewertungsdetails, Tags und Mini-Balken.
-
-## Auswählen für Vergleich & Watchlist
-
-- Auf jeder Karte/Zeile findest du ein **Vergleichs-Icon**, mit dem du Tools zur
- [Vergleichsleiste](/docs/handbook/vergleichen) hinzufügst.
-- Das **Lesezeichen-Icon** speichert Tools in deiner
- [Watchlist](/docs/handbook/watchlist) (nur mit dem entsprechenden Tarif).
-
-## API
-
-Alle Such-, Filter- und Sortierparameter entsprechen den Query-Parametern von
-[`GET /tools`](/docs/reference/endpoints/tools#listTools).
diff --git a/docs/releases/v0.8.1/reference.json b/docs/releases/v0.8.1/reference.json
deleted file mode 100644
index a3adfd9..0000000
--- a/docs/releases/v0.8.1/reference.json
+++ /dev/null
@@ -1,2782 +0,0 @@
-{
- "tags": [
- {
- "name": "health",
- "description": "Health operations",
- "endpoints": [
- {
- "operationId": "healthCheck",
- "method": "GET",
- "path": "/healthz",
- "summary": "Health check",
- "description": "Returns server health status",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Healthy",
- "schema": {
- "kind": "ref",
- "value": "HealthStatus"
- }
- }
- ]
- },
- {
- "operationId": "getVersion",
- "method": "GET",
- "path": "/version",
- "summary": "Build version information",
- "description": "Returns the running build version, commit SHA and build date",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Version information",
- "schema": {
- "kind": "ref",
- "value": "VersionInfo"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "tools",
- "description": "Tool management",
- "endpoints": [
- {
- "operationId": "listTools",
- "method": "GET",
- "path": "/tools",
- "summary": "List all tools",
- "description": "",
- "parameters": [
- {
- "name": "category",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "sort",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "newest, top_rated, most_reviewed, name_asc, name_desc, recently_updated"
- },
- {
- "name": "tags",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tags; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "features",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated features; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "minRating",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "number"
- },
- "description": "Minimum average combined rating (0-5)",
- "constraints": "0–5"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of tools",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- }
- ]
- },
- {
- "operationId": "createTool",
- "method": "POST",
- "path": "/tools",
- "summary": "Create a new tool",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCompareTools",
- "method": "GET",
- "path": "/compare",
- "summary": "Compare tools side by side (premium)",
- "description": "",
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "required": true,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tool ids",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tools in requested order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Authentication required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getToolRatingHistory",
- "method": "GET",
- "path": "/tools/{id}/rating-history",
- "summary": "Get a tool's rating history over time",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating history",
- "schema": {
- "kind": "array",
- "value": "RatingHistoryItem"
- }
- },
- {
- "status": "400",
- "description": "Invalid id",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getTool",
- "method": "GET",
- "path": "/tools/{id}",
- "summary": "Get a tool by ID",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tool details",
- "schema": {
- "kind": "ref",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateTool",
- "method": "PATCH",
- "path": "/tools/{id}",
- "summary": "Update a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTool",
- "method": "DELETE",
- "path": "/tools/{id}",
- "summary": "Delete a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listTrashedTools",
- "method": "GET",
- "path": "/tools/trash",
- "summary": "List trashed (soft-deleted) tools",
- "description": "",
- "parameters": [
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of trashed tools",
- "schema": {
- "kind": "array",
- "value": "Tool"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "trashTools",
- "method": "POST",
- "path": "/tools/trash",
- "summary": "Move tools to trash (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools trashed",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTrashedTools",
- "method": "DELETE",
- "path": "/tools/trash",
- "summary": "Permanently delete trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "restoreTools",
- "method": "POST",
- "path": "/tools/trash/restore",
- "summary": "Restore trashed tools",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools restored",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "emptyTrash",
- "method": "POST",
- "path": "/tools/trash/empty",
- "summary": "Permanently delete all trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Trash emptied",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCategories",
- "method": "GET",
- "path": "/categories",
- "summary": "List all distinct tool categories",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Categories list",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllFeatures",
- "method": "GET",
- "path": "/features/all",
- "summary": "List all distinct feature strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known features",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllTags",
- "method": "GET",
- "path": "/tags/all",
- "summary": "List all distinct tag strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known tags",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "ratings",
- "description": "Tool ratings",
- "endpoints": [
- {
- "operationId": "listToolRatings",
- "method": "GET",
- "path": "/tools/{id}/ratings",
- "summary": "List ratings for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Ratings list",
- "schema": {
- "kind": "array",
- "value": "Rating"
- }
- }
- ]
- },
- {
- "operationId": "createRating",
- "method": "POST",
- "path": "/tools/{id}/ratings",
- "summary": "Submit a rating for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "RatingInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created rating",
- "schema": {
- "kind": "ref",
- "value": "Rating"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "Tool not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "analytics",
- "description": "Analytics and aggregated statistics",
- "endpoints": [
- {
- "operationId": "getAnalyticsSummary",
- "method": "GET",
- "path": "/analytics/summary",
- "summary": "Overall platform statistics",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Platform-level summary stats",
- "schema": {
- "kind": "ref",
- "value": "AnalyticsSummary"
- }
- }
- ]
- },
- {
- "operationId": "getTopTools",
- "method": "GET",
- "path": "/analytics/top-tools",
- "summary": "Top-rated tools",
- "description": "",
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "metric",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "usefulness, usability, combined"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Top tools list",
- "schema": {
- "kind": "array",
- "value": "TopToolEntry"
- }
- }
- ]
- },
- {
- "operationId": "getAnalyticsByCategory",
- "method": "GET",
- "path": "/analytics/by-category",
- "summary": "Rating statistics grouped by category",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Per-category statistics",
- "schema": {
- "kind": "array",
- "value": "CategoryStats"
- }
- }
- ]
- },
- {
- "operationId": "getRatingDistribution",
- "method": "GET",
- "path": "/analytics/rating-distribution",
- "summary": "Distribution of rating scores across the platform",
- "description": "",
- "parameters": [
- {
- "name": "toolId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating score distribution",
- "schema": {
- "kind": "ref",
- "value": "RatingDistribution"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "auth",
- "description": "Authentication",
- "endpoints": [
- {
- "operationId": "getAuthMode",
- "method": "GET",
- "path": "/auth/mode",
- "summary": "Get authentication mode (oidc or local)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Auth mode",
- "schema": {
- "kind": "ref",
- "value": "AuthMode"
- }
- }
- ]
- },
- {
- "operationId": "getCsrfToken",
- "method": "GET",
- "path": "/auth/csrf",
- "summary": "Get a CSRF token for state-changing requests",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "CSRF token",
- "schema": {
- "kind": "ref",
- "value": "CsrfToken"
- }
- }
- ]
- },
- {
- "operationId": "localLogin",
- "method": "POST",
- "path": "/auth/login",
- "summary": "Local username/password login",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "LocalLoginInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Logged in successfully",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Invalid credentials",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMe",
- "method": "GET",
- "path": "/auth/me",
- "summary": "Get current authenticated user",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Current user info",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "changeMyPassword",
- "method": "POST",
- "path": "/auth/me/password",
- "summary": "Change own password (local users only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ChangePasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password changed",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Invalid input or wrong current password",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getPasswordRedirect",
- "method": "GET",
- "path": "/auth/password-redirect",
- "summary": "Get redirect URL for managing credentials in the identity provider",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Redirect URL (null in local mode)",
- "schema": {
- "kind": "ref",
- "value": "PasswordRedirect"
- }
- }
- ]
- },
- {
- "operationId": "getMePreferences",
- "method": "GET",
- "path": "/auth/me/preferences",
- "summary": "Get current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateMePreferences",
- "method": "PUT",
- "path": "/auth/me/preferences",
- "summary": "Update current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMeWatchlist",
- "method": "GET",
- "path": "/auth/me/watchlist",
- "summary": "Get current user's watchlist tools (premium)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Watchlist tools in saved order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "users",
- "description": "User management (admin only)",
- "endpoints": [
- {
- "operationId": "listUsers",
- "method": "GET",
- "path": "/users",
- "summary": "List all local users (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User list",
- "schema": {
- "kind": "array",
- "value": "User"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Forbidden",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "createUser",
- "method": "POST",
- "path": "/users",
- "summary": "Create a new local user (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserCreateInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "409",
- "description": "Username already exists",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateUser",
- "method": "PATCH",
- "path": "/users/{id}",
- "summary": "Update user role (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserRoleUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteUser",
- "method": "DELETE",
- "path": "/users/{id}",
- "summary": "Delete a user (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- }
- ]
- },
- {
- "operationId": "setUserPassword",
- "method": "PATCH",
- "path": "/users/{id}/password",
- "summary": "Set/reset a user's password (admin only, local users only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "SetPasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password updated",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "audit",
- "description": "Audit log",
- "endpoints": [
- {
- "operationId": "listAuditLogs",
- "method": "GET",
- "path": "/audit-logs",
- "summary": "List audit log entries (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "entityType",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Audit log entries",
- "schema": {
- "kind": "array",
- "value": "AuditLog"
- }
- }
- ]
- }
- ]
- }
- ],
- "schemas": [
- {
- "name": "HealthStatus",
- "description": "",
- "fields": [
- {
- "name": "status",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "VersionInfo",
- "description": "",
- "fields": [
- {
- "name": "version",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "commitSha",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "buildDate",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "trashRetentionDays",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthMode",
- "description": "",
- "fields": [
- {
- "name": "mode",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "oidc, local"
- }
- ]
- },
- {
- "name": "CsrfToken",
- "description": "",
- "fields": [
- {
- "name": "token",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "LocalLoginInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "User",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "authProvider",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "local, oidc"
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "UserCreateInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 2 chars"
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "UserRoleUpdate",
- "description": "",
- "fields": [
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "ChangePasswordInput",
- "description": "",
- "fields": [
- {
- "name": "currentPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "newPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "SetPasswordInput",
- "description": "",
- "fields": [
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "PasswordRedirect",
- "description": "",
- "fields": [
- {
- "name": "url",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuditLog",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityType",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "type": {
- "kind": "type",
- "value": "integer | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "action",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "userId",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "changes",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "Tool",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedAt",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingHistoryItem",
- "description": "",
- "fields": [
- {
- "name": "date",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "combined",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolWithStats",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolInput",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolUpdate",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TrashToolsInput",
- "description": "",
- "fields": [
- {
- "name": "ids",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 items, max 500 items"
- }
- ]
- },
- {
- "name": "Rating",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolId",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "RatingInput",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AnalyticsSummary",
- "description": "",
- "fields": [
- {
- "name": "totalTools",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "categoriesCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "mostRatedTool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TopToolEntry",
- "description": "",
- "fields": [
- {
- "name": "tool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "CategoryStats",
- "description": "",
- "fields": [
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingDistribution",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ScoreBucket",
- "description": "",
- "fields": [
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "count",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthUser",
- "description": "",
- "fields": [
- {
- "name": "sub",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "preferredUsername",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "entitlements",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "isLocal",
- "type": {
- "kind": "type",
- "value": "boolean"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "UserPreferences",
- "description": "",
- "fields": [
- {
- "name": "view",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "grid, table, rows"
- },
- {
- "name": "density",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "cozy, compact"
- },
- {
- "name": "watchlist",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ErrorResponse",
- "description": "",
- "fields": [
- {
- "name": "error",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/docs/releases/v0.8.2.en.md b/docs/releases/v0.8.2.en.md
deleted file mode 100644
index d3b3224..0000000
--- a/docs/releases/v0.8.2.en.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# v0.8.2 — Release Notes
-
-**Date:** 2026-08-04 · **Tag:** [`v0.8.2`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.2)
-
-## Fixes & improvements
-
-- **Mobile navigation in the docs**: The left navigation bar (manual,
- endpoints, schemas) was completely hidden below `lg` (1024px).
- There is now a menu button in the header that opens a side
- navigation drawer with the same content — on small screens
- the docs remain fully navigable.
-- **Version dropdown shows the selected version**: When switching to a
- different release (`/docs/releases/vX.Y.Z`), the dropdown wrongly stayed on
- "current". The displayed version is now also derived from the releases route.
-
-## API changes
-
-- No changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none.
-
-## Known limitations
-
-- Manual & reference apply to the current version; older versions show
- their release notes and a reference snapshot, if generated at release time
- (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`33cf261`](https://git.kubebase.de/admin/tool-evaluator/commit/33cf261)
-- Tag: [`v0.8.2`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.2)
diff --git a/docs/releases/v0.8.2.md b/docs/releases/v0.8.2.md
deleted file mode 100644
index 4613159..0000000
--- a/docs/releases/v0.8.2.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# v0.8.2 — Release Notes
-
-**Datum:** 2026-08-04 · **Tag:** [`v0.8.2`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.2)
-
-## Fixes & Verbesserungen
-
-- **Mobile Navigation in der Doku**: Die linke Navigationsleiste (Handbuch,
- Endpunkte, Schemas) wurde unterhalb von `lg` (1024px) komplett ausgeblendet.
- Es gibt jetzt einen Menü-Button im Kopfbereich, der ein seitliches
- Navigations-Drawer mit demselben Inhalt öffnet — auf kleinen Bildschirmen
- bleibt die Doku voll navigierbar.
-- **Versions-Dropdown zeigt die gewählte Version an**: Beim Wechsel zu einem
- anderen Release (`/docs/releases/vX.Y.Z`) blieb das Dropdown fälschlich auf
- „aktuell". Die angezeigte Version wird jetzt auch aus der releases-Route
- abgeleitet.
-
-## API-Änderungen
-
-- Keine Änderungen an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine.
-
-## Bekannte Einschränkungen
-
-- Handbuch & Referenz gelten für die aktuelle Version; ältere Versionen zeigen
- ihre Release-Notes und einen Referenz-Snapshot, sofern beim Release erzeugt
- (`node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`).
-
-## Links
-
-- Commit: [`33cf261`](https://git.kubebase.de/admin/tool-evaluator/commit/33cf261)
-- Tag: [`v0.8.2`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.2)
diff --git a/docs/releases/v0.8.2/handbook/analytics.en.md b/docs/releases/v0.8.2/handbook/analytics.en.md
deleted file mode 100644
index 7450a33..0000000
--- a/docs/releases/v0.8.2/handbook/analytics.en.md
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# Analytics
-
-The **Analytics** area (`/analytics`) is a public dashboard with
-metrics and charts based on all tools and ratings.
-
-## Metrics (KPI cards)
-
-- **Number of tools** — how many tools are recorded in the catalog.
-- **Number of ratings** — how many ratings were submitted in total.
-- **Active categories** — how many categories exist.
-- **Average rating** — global combined value.
-
-## Charts
-
-| Chart | Content |
-| --- | --- |
-| **Top 8 tools** | Bar chart of the tools with the highest combined score (0–5) |
-| **Tools per category** | Radar chart of the number of tools per category |
-| **Score distribution** | Two horizontal bar charts (usefulness & usability) per star |
-
-The charts are interactive (tooltips on hover).
-
-## API
-
-- [`GET /analytics/summary`](/docs/reference/endpoints/analytics#getAnalyticsSummary)
-- [`GET /analytics/top-tools`](/docs/reference/endpoints/analytics#getTopTools)
-- [`GET /analytics/by-category`](/docs/reference/endpoints/analytics#getAnalyticsByCategory)
-- [`GET /analytics/rating-distribution`](/docs/reference/endpoints/analytics#getRatingDistribution)
diff --git a/docs/releases/v0.8.2/handbook/analytics.md b/docs/releases/v0.8.2/handbook/analytics.md
deleted file mode 100644
index 3cfacd8..0000000
--- a/docs/releases/v0.8.2/handbook/analytics.md
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# Analytics
-
-Der Bereich **Analytics** (`/analytics`) ist ein öffentliches Dashboard mit
-Kennzahlen und Diagrammen auf Basis aller Tools und Bewertungen.
-
-## Kennzahlen (KPI-Karten)
-
-- **Anzahl Tools** — wie viele Tools sind im Katalog erfasst.
-- **Anzahl Bewertungen** — wie viele Bewertungen wurden insgesamt abgegeben.
-- **Aktive Kategorien** — wie viele Kategorien existieren.
-- **Durchschnittliche Bewertung** — globaler kombinierter Wert.
-
-## Diagramme
-
-| Diagramm | Inhalt |
-| --- | --- |
-| **Top 8 Tools** | Balkendiagramm der Tools mit der höchsten kombinierten Punktzahl (0–5) |
-| **Tools je Kategorie** | Radar-Diagramm der Tool-Anzahl pro Kategorie |
-| **Punkteverteilung** | Zwei horizontale Balken-Diagramme (Nützlichkeit & Bedienbarkeit) pro Stern |
-
-Die Diagramme sind interaktiv (Tooltips beim Überfahren).
-
-## API
-
-- [`GET /analytics/summary`](/docs/reference/endpoints/analytics#getAnalyticsSummary)
-- [`GET /analytics/top-tools`](/docs/reference/endpoints/analytics#getTopTools)
-- [`GET /analytics/by-category`](/docs/reference/endpoints/analytics#getAnalyticsByCategory)
-- [`GET /analytics/rating-distribution`](/docs/reference/endpoints/analytics#getRatingDistribution)
diff --git a/docs/releases/v0.8.2/handbook/bewerten.en.md b/docs/releases/v0.8.2/handbook/bewerten.en.md
deleted file mode 100644
index 7ccd0c8..0000000
--- a/docs/releases/v0.8.2/handbook/bewerten.en.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-# Rating
-
-On the detail page of a tool you can share your experience. Click on
-**Submit a rating** (requires an account).
-
-## Form fields
-
-| Field | Required | Notes |
-| --- | --- | --- |
-| **Usefulness** | Yes | 1–5 stars |
-| **Usability** | Yes | 1–5 stars |
-| **Comment** | No | Free text |
-| **Name** | No | Defaults to "Anonymous" |
-
-Next to the fields, the **? icon** links directly to the associated field
-description in the [data model reference](/docs/reference/schemas/ratinginput).
-
-## What happens after submitting?
-
-- Your rating is saved immediately and appears in the **rating list** of the
- detail page.
-- The **averages** (usefulness, usability, combined) and the **score
- distribution** are updated.
-- The **statistics** in the [Analytics](/docs/handbook/analytics) section are
- recalculated.
-
-## Statistic sections on the detail page
-
-- **Rating overview:** usefulness & usability as an average with progress
- bars.
-- **Score distribution:** number of ratings per star (1★–5★).
-- **History:** line chart of combined/individual values over time
- (only visible once there are several ratings).
-
-## API
-
-- [`POST /tools/{id}/ratings`](/docs/reference/endpoints/ratings#createRating) — Submit a rating
-- [`GET /tools/{id}/ratings`](/docs/reference/endpoints/ratings#listToolRatings) — Ratings of a tool
diff --git a/docs/releases/v0.8.2/handbook/bewerten.md b/docs/releases/v0.8.2/handbook/bewerten.md
deleted file mode 100644
index b4d054e..0000000
--- a/docs/releases/v0.8.2/handbook/bewerten.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-# Bewerten
-
-Auf der Detailseite eines Tools kannst du deine Erfahrung teilen. Klicke auf
-**Bewertung abgeben** (erfordert ein Konto).
-
-## Formularfelder
-
-| Feld | Pflicht | Hinweise |
-| --- | --- | --- |
-| **Nützlichkeit** | Ja | 1–5 Sterne |
-| **Bedienbarkeit** | Ja | 1–5 Sterne |
-| **Kommentar** | Nein | Freitext |
-| **Name** | Nein | Standard „Anonym" |
-
-Neben den Feldern führt das **?‑Icon** direkt zur zugehörigen Feldbeschreibung
-in der [Datenmodell-Referenz](/docs/reference/schemas/ratinginput).
-
-## Was passiert nach dem Abgeben?
-
-- Deine Bewertung wird sofort gespeichert und erscheint in der
- **Bewertungsliste** der Detailseite.
-- Die **Durchschnittswerte** (Nützlichkeit, Bedienbarkeit, Kombiniert) und die
- **Punkteverteilung** werden aktualisiert.
-- Die **Statistiken** im Bereich [Analytics](/docs/handbook/analytics) werden
- neu berechnet.
-
-## Statistik-Bereiche auf der Detailseite
-
-- **Bewertungsübersicht:** Nützlichkeit & Bedienbarkeit als Durchschnitt mit
- Fortschrittsbalken.
-- **Punkteverteilung:** Anzahl der Bewertungen pro Stern (1★–5★).
-- **Verlauf:** Linienchart der kombinierten/Teilwerte über die Zeit
- (erst ab mehreren Bewertungen sichtbar).
-
-## API
-
-- [`POST /tools/{id}/ratings`](/docs/reference/endpoints/ratings#createRating) — Bewertung abgeben
-- [`GET /tools/{id}/ratings`](/docs/reference/endpoints/ratings#listToolRatings) — Bewertungen eines Tools
diff --git a/docs/releases/v0.8.2/handbook/datenmodell.en.md b/docs/releases/v0.8.2/handbook/datenmodell.en.md
deleted file mode 100644
index 99d602e..0000000
--- a/docs/releases/v0.8.2/handbook/datenmodell.en.md
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# Data model
-
-This chapter explains the central data objects of toolr at the application
-level. The complete, automatically generated reference of all fields,
-types and constraints can be found in the
-[API reference](/docs/reference/schemas/tool).
-
-## Tool
-
-The heart of it all: a tool recorded in the catalog.
-
-| Property | Description |
-| --- | --- |
-| `id` | Unique identifier |
-| `name` | Display name |
-| `description` | Description (what does the tool do?) |
-| `category` | Category assignment |
-| `websiteUrl` | Official website (optional) |
-| `iconUrl` | Logo/icon URL (optional) |
-| `features` | List of capabilities |
-| `tags` | List of keywords |
-| `createdAt` / `updatedAt` | Timestamps |
-| `createdBy` | Person who created it |
-| `deletedAt` / `deletedBy` | Soft deletion (trash) |
-
-Input forms use the derived schemas
-[`ToolInput`](/docs/reference/schemas/toolinput) and
-[`ToolUpdate`](/docs/reference/schemas/toolupdate).
-Aggregated views are provided by [`ToolWithStats`](/docs/reference/schemas/toolwithstats)
-(e.g. with average rating).
-
-## Rating (Bewertung)
-
-A single rating for a tool:
-
-- `usefulness` (Nützlichkeit, 1–5) and `usability` (Bedienbarkeit, 1–5)
-- optional `comment` and a display name (`reviewerName`)
-- timestamp
-
-Input schema: [`RatingInput`](/docs/reference/schemas/ratinginput).
-
-## User & Auth
-
-- [`User`](/docs/reference/schemas/user) — user account with role (User/Admin)
- and plan (Free/Premium/Enterprise).
-- [`AuthUser`](/docs/reference/schemas/authuser) — the logged-in profile
- including `entitlements` (available features).
-- [`UserPreferences`](/docs/reference/schemas/userpreferences) — view and
- density preferences as well as the `watchlist` (list of tool IDs).
-
-## Analytics
-
-The statistics endpoints provide aggregated data:
-
-- [`AnalyticsSummary`](/docs/reference/schemas/analyticssummary) — global
- metrics (number of tools/ratings, categories, average).
-- [`TopToolEntry`](/docs/reference/schemas/TopToolEntry) — an entry of the
- top tools.- [`CategoryStats`](/docs/reference/schemas/categorystats) — number of tools per
- category.
-- [`RatingDistribution`](/docs/reference/schemas/ratingdistribution) —
- score distribution (usefulness & usability).
-- [`ScoreBucket`](/docs/reference/schemas/scorebucket) — a value bucket.
-
-## Additional
-
-- [`VersionInfo`](/docs/reference/schemas/versioninfo) — version, commit SHA,
- build date and trash retention of the running instance.
-- [`AuditLog`](/docs/reference/schemas/auditlog) — a log entry
- (action, entity, timestamp, actor, changes).
diff --git a/docs/releases/v0.8.2/handbook/datenmodell.md b/docs/releases/v0.8.2/handbook/datenmodell.md
deleted file mode 100644
index 618e160..0000000
--- a/docs/releases/v0.8.2/handbook/datenmodell.md
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# Datenmodell
-
-Dieses Kapitel erklärt die zentralen Datenobjekte von toolr auf Ebene der
-Anwendung. Die vollständige, automatisch generierte Referenz aller Felder,
-Typen und Constraints findest du in der
-[API-Referenz](/docs/reference/schemas/tool).
-
-## Tool
-
-Das Herzstück: ein im Katalog erfasstes Werkzeug.
-
-| Eigenschaft | Beschreibung |
-| --- | --- |
-| `id` | Eindeutige Kennung |
-| `name` | Anzeigename |
-| `description` | Beschreibung (Was macht das Tool?) |
-| `category` | Kategorie-Zuordnung |
-| `websiteUrl` | Offizielle Website (optional) |
-| `iconUrl` | Logo-/Icon-URL (optional) |
-| `features` | Liste von Fähigkeiten |
-| `tags` | Liste von Schlagwörtern |
-| `createdAt` / `updatedAt` | Zeitstempel |
-| `createdBy` | Erstellende Person |
-| `deletedAt` / `deletedBy` | Soft-Löschung (Papierkorb) |
-
-Eingabe-Formulare verwenden die abgeleiteten Schemas
-[`ToolInput`](/docs/reference/schemas/toolinput) und
-[`ToolUpdate`](/docs/reference/schemas/toolupdate).
-Aggregierte Ansichten liefert [`ToolWithStats`](/docs/reference/schemas/toolwithstats)
-(z. B. mit Durchschnittsbewertung).
-
-## Rating (Bewertung)
-
-Eine einzelne Bewertung zu einem Tool:
-
-- `usefulness` (Nützlichkeit, 1–5) und `usability` (Bedienbarkeit, 1–5)
-- optional `comment` und ein Anzeigename (`reviewerName`)
-- Zeitstempel
-
-Eingabe-Schema: [`RatingInput`](/docs/reference/schemas/ratinginput).
-
-## User & Auth
-
-- [`User`](/docs/reference/schemas/user) — Benutzerkonto mit Rolle (User/Admin)
- und Tarif (Free/Premium/Enterprise).
-- [`AuthUser`](/docs/reference/schemas/authuser) — das angemeldete Profil
- inklusive `entitlements` (verfügbare Features).
-- [`UserPreferences`](/docs/reference/schemas/userpreferences) — Ansichts- und
- Dichte-Präferenzen sowie die `watchlist` (Liste von Tool-IDs).
-
-## Analytics
-
-Die Statistik-Endpunkte liefern aggregierte Daten:
-
-- [`AnalyticsSummary`](/docs/reference/schemas/analyticssummary) — globale
- Kennzahlen (Anzahl Tools/Bewertungen, Kategorien, Durchschnitt).
-- [`TopToolEntry`](/docs/reference/schemas/TopToolEntry) — ein Eintrag der
- Top-Tools.- [`CategoryStats`](/docs/reference/schemas/categorystats) — Tool-Anzahl je
- Kategorie.
-- [`RatingDistribution`](/docs/reference/schemas/ratingdistribution) —
- Punkteverteilung (Nützlichkeit & Bedienbarkeit).
-- [`ScoreBucket`](/docs/reference/schemas/scorebucket) — ein Werte-Bucket.
-
-## Weitere
-
-- [`VersionInfo`](/docs/reference/schemas/versioninfo) — Version, Commit-SHA,
- Build-Datum und Papierkorb-Aufbewahrung der laufenden Instanz.
-- [`AuditLog`](/docs/reference/schemas/auditlog) — ein Protokolleintrag
- (Aktion, Entität, Zeitstempel, Akteur, Änderungen).
diff --git a/docs/releases/v0.8.2/handbook/getting-started.en.md b/docs/releases/v0.8.2/handbook/getting-started.en.md
deleted file mode 100644
index 98344ef..0000000
--- a/docs/releases/v0.8.2/handbook/getting-started.en.md
+++ /dev/null
@@ -1,53 +0,0 @@
-
-# Getting Started
-
-This page guides you through the most important workflows in toolr — from your
-first visit to creating and rating a tool.
-
-## 1. Sign in
-
-Most actions (create a tool, rate, watchlist, compare) require
-an account. Click **Sign in** in the bottom left corner. Depending on the
-instance configuration you have two options:
-
-- **Local accounts:** username + password. Access is created by an admin
- (see [Administration](/docs/handbook/administration)).
-- **OIDC (SSO):** sign in with the configured identity provider (e.g.
- Keycloak).
-
-Which mode is active is shown by the
-[`GET /auth/mode`](/docs/reference/endpoints/auth#getAuthMode) endpoint. Details
-can be found in the [Sign in & account](/docs/handbook/konto) section.
-
-## 2. Find tools
-
-Open the **Browse tools** section:
-
-- **Search** — full-text search across name & description (shortcut `/`).
-- **Filter** — by category, tags, features and minimum rating
- (`minRating`).
-- **Sort** — by newest, top-rated, most rated, name
- (ascending/descending) or last update.
-
-All options in detail: [Find & browse tools](/docs/handbook/tools-finden).
-
-## 3. Create a tool
-
-Go to **Add tool** and fill in the form. Details for each field can be found
-in the [Create a tool](/docs/handbook/tool-anlegen) section and in the
-[field reference](/docs/reference/schemas/toolinput).
-
-## 4. Rate
-
-On the detail page of a tool you can submit **usefulness** and **usability**
-(1–5 each) and optionally leave a comment. Your
-rating is immediately reflected in the statistics.
-See [Rating](/docs/handbook/bewerten).
-
-## 5. Further reading
-
-- [Compare tools](/docs/handbook/vergleichen)
-- [Watchlist](/docs/handbook/watchlist)
-- [Analytics](/docs/handbook/analytics)
-- [Plans & permissions](/docs/handbook/plaene)
-- [Administration](/docs/handbook/administration)
diff --git a/docs/releases/v0.8.2/handbook/index.json b/docs/releases/v0.8.2/handbook/index.json
deleted file mode 100644
index 4dc0aa7..0000000
--- a/docs/releases/v0.8.2/handbook/index.json
+++ /dev/null
@@ -1,138 +0,0 @@
-[
- {
- "slug": "index",
- "file": "index.md",
- "title": "Überblick",
- "order": 1,
- "fileEn": "index.en.md",
- "titleEn": "Overview"
- },
- {
- "slug": "getting-started",
- "file": "getting-started.md",
- "title": "Erste Schritte",
- "order": 2,
- "fileEn": "getting-started.en.md",
- "titleEn": "Getting Started"
- },
- {
- "slug": "konto",
- "file": "konto.md",
- "title": "Anmelden & Konto",
- "order": 3,
- "fileEn": "konto.en.md",
- "titleEn": "Login & Account"
- },
- {
- "slug": "tools-finden",
- "file": "tools-finden.md",
- "title": "Tools finden & durchsuchen",
- "order": 4,
- "fileEn": "tools-finden.en.md",
- "titleEn": "Find & browse tools"
- },
- {
- "slug": "tool-anlegen",
- "file": "tool-anlegen.md",
- "title": "Tool anlegen",
- "order": 5,
- "fileEn": "tool-anlegen.en.md",
- "titleEn": "Create a tool"
- },
- {
- "slug": "tool-bearbeiten",
- "file": "tool-bearbeiten.md",
- "title": "Tool bearbeiten & löschen",
- "order": 6,
- "fileEn": "tool-bearbeiten.en.md",
- "titleEn": "Edit & delete tools"
- },
- {
- "slug": "bewerten",
- "file": "bewerten.md",
- "title": "Bewerten",
- "order": 7,
- "fileEn": "bewerten.en.md",
- "titleEn": "Rating"
- },
- {
- "slug": "watchlist",
- "file": "watchlist.md",
- "title": "Watchlist",
- "order": 8,
- "fileEn": "watchlist.en.md",
- "titleEn": "Watchlist"
- },
- {
- "slug": "vergleichen",
- "file": "vergleichen.md",
- "title": "Vergleichen",
- "order": 9,
- "fileEn": "vergleichen.en.md",
- "titleEn": "Compare"
- },
- {
- "slug": "analytics",
- "file": "analytics.md",
- "title": "Analytics",
- "order": 10,
- "fileEn": "analytics.en.md",
- "titleEn": "Analytics"
- },
- {
- "slug": "plaene",
- "file": "plaene.md",
- "title": "Pläne & Berechtigungen",
- "order": 11,
- "fileEn": "plaene.en.md",
- "titleEn": "Plans & Permissions"
- },
- {
- "slug": "kosten",
- "file": "kosten.md",
- "title": "Kosten erfassen",
- "order": 12,
- "fileEn": "kosten.en.md",
- "titleEn": "Recording Costs"
- },
- {
- "slug": "administration",
- "file": "administration.md",
- "title": "Administration",
- "order": 13,
- "fileEn": "administration.en.md",
- "titleEn": "Administration"
- },
- {
- "slug": "redundanz",
- "file": "redundanz.md",
- "title": "Redundanz-Dashboard",
- "order": 14,
- "fileEn": "redundanz.en.md",
- "titleEn": "Redundancy dashboard"
- },
- {
- "slug": "papierkorb",
- "file": "papierkorb.md",
- "title": "Papierkorb",
- "order": 15,
- "fileEn": "papierkorb.en.md",
- "titleEn": "Trash"
- },
- {
- "slug": "tastatur",
- "file": "tastatur.md",
- "title": "Tastenkürzel & Kommandopalette",
- "order": 16,
- "fileEn": "tastatur.en.md",
- "titleEn": "Keyboard shortcuts & command palette"
- },
- {
- "slug": "datenmodell",
- "file": "datenmodell.md",
- "title": "Datenmodell",
- "order": 17,
- "fileEn": "datenmodell.en.md",
- "titleEn": "Data model"
- }
-]
\ No newline at end of file
diff --git a/docs/releases/v0.8.2/handbook/index.md b/docs/releases/v0.8.2/handbook/index.md
deleted file mode 100644
index f527a6e..0000000
--- a/docs/releases/v0.8.2/handbook/index.md
+++ /dev/null
@@ -1,52 +0,0 @@
-
-# Willkommen bei toolr
-
-toolr ist eine Plattform zum **Entdecken, Bewerten und Vergleichen von
-Entwicklungstools**. Nutzer:innen pflegen einen gemeinsamen Katalog von Tools,
-vergeben Bewertungen (Nützlichkeit & Bedienbarkeit) und nutzen Statistiken, um
-die richtige Wahl zu treffen.
-
-## Was kannst du mit toolr tun?
-
-| Funktion | Beschreibung | Sichtbarkeit |
-| --- | --- | --- |
-| **Tools durchsuchen** | Katalog filtern, sortieren und durchsuchen | Alle |
-| **Tool anlegen** | Neues Tool mit Beschreibung, Kategorie, Features & Tags eintragen | Angemeldet |
-| **Tool bearbeiten/löschen** | Eigene Tools pflegen (Ersteller:in oder Admin) | Angemeldet |
-| **Bewerten** | Nützlichkeit & Bedienbarkeit (1–5) plus Kommentar vergeben | Angemeldet |
-| **Watchlist** | Tools als Favoriten speichern | Premium |
-| **Vergleichen** | Tools nebeneinander gegenüberstellen | Premium |
-| **Kosten erfassen** | Lizenz- und Kostenmodelle je Tool eintragen | Premium |
-| **Analytics** | Statistiken, Top-Tools, Verteilungen | Alle |
-| **Papierkorb** | Soft-gelöschte Tools wiederherstellen oder endgültig löschen | Premium |
-| **Admin** | Nutzerverwaltung, Audit-Log, Systeminformationen | Admin |
-| **Redundanz** | Automatische Doppelungs-Erkennung | Admin |
-
-## Wie diese Doku aufgebaut ist
-
-- **User Guide** (diese Seiten): Schritt-für-Schritt-Anleitungen für alle
- Funktionen — von den [Ersten Schritten](/docs/handbook/getting-started) bis
- zur [Administration](/docs/handbook/administration).
-- **API-Referenz**: automatisch aus der OpenAPI-Spezifikation generiert — alle
- [Endpunkte](/docs/reference/endpoints/tools) und
- [Datenfelder](/docs/reference/schemas/toolinput) der aktuellen Version.
-- **Release-Notes**: Was ist in welcher [Version](/docs/releases/v0.8.1) neu.
-
-## Der Einstieg
-
-Der schnellste Weg:
-
-1. **Anmelden** — ohne Konto kannst du nur stöbern
- (siehe [Erste Schritte](/docs/handbook/getting-started#1-anmelden)).
-2. **Tools finden** — Suche, Filter und Sortierung im Bereich
- [Tools durchsuchen](/docs/handbook/tools-finden).
-3. **Tool anlegen** — über „Tool hinzufügen"
- ([Anleitung](/docs/handbook/tool-anlegen)).
-4. **Bewerten** — auf der Detailseite eines Tools
- ([Anleitung](/docs/handbook/bewerten)).
-
-## Kontakt & Quellcode
-
-Der Quellcode liegt unter
-[git.kubebase.de/admin/tool-evaluator](https://git.kubebase.de/admin/tool-evaluator) —
-über das Repository-Icon oben rechts erreichst du ihn jederzeit.
diff --git a/docs/releases/v0.8.2/handbook/konto.en.md b/docs/releases/v0.8.2/handbook/konto.en.md
deleted file mode 100644
index 22360df..0000000
--- a/docs/releases/v0.8.2/handbook/konto.en.md
+++ /dev/null
@@ -1,52 +0,0 @@
-
-# Login & Account
-
-## Logging in
-
-Click **Login** at the bottom left of the sidebar. Depending on the
-configuration of the instance:
-
-- **Local accounts:** enter username and password. The accounts are created
- by an admin (see [Administration](/docs/handbook/administration)).
-- **OIDC (SSO):** you are redirected to the configured identity provider and
- log in there.
-
-The active mode is available at the endpoint
-[`GET /auth/mode`](/docs/reference/endpoints/auth#getAuthMode).
-
-> You can reach the login page directly at `/login`. After a successful
-> login you are redirected back to the page you originally requested.
-
-## User profile
-
-You can see your profile (avatar, name, email, plan) at the bottom left in
-the user menu. There you have the following actions available:
-
-- **Watchlist** — your saved tools (only with the corresponding plan).
-- **Trash** — restorable, deleted tools (Premium/Enterprise).
-- **Change password** — directly in toolr for local accounts; for OIDC
- accounts, password management is offered in the identity provider.
-- **Logout** — ends your session.
-
-## Changing your password (local account)
-
-1. Open the user menu at the bottom left.
-2. Select **Change password**.
-3. Enter the **current** and a **new** password (min. 6 characters) and
- confirm it.
-4. Save — the password takes effect immediately.
-
-API reference: [`POST /auth/me/password`](/docs/reference/endpoints/auth#changeMyPassword).
-
-## Display settings
-
-Using the buttons at the top right you can:
-
-- switch the **language** (German / English),
-- toggle the **theme** (Light / Dark / System),
-- adjust the **list view** and **density** in the Browse tools section
- (see [Finding & browsing tools](/docs/handbook/tools-finden)).
-
-Your preferences (incl. watchlist) are saved at the endpoint
-[`GET /auth/me/preferences`](/docs/reference/endpoints/auth#getMePreferences)
-and updated via [`PUT /auth/me/preferences`](/docs/reference/endpoints/auth#updateMePreferences).
diff --git a/docs/releases/v0.8.2/handbook/kosten.en.md b/docs/releases/v0.8.2/handbook/kosten.en.md
deleted file mode 100644
index 1cf7a3a..0000000
--- a/docs/releases/v0.8.2/handbook/kosten.en.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-# Recording Costs
-
-On the detail page of a tool you can enter cost and license models so that
-the total costs per tool become transparent.
-
-> Costs is a **premium feature** (`costs`, Premium/Enterprise). Admins always
-> have access.
-
-## Adding costs
-
-Click **Add costs** in the costs section of the detail page and fill out the
-form:
-
-| Field | Notes |
-| --- | --- |
-| **License type** | Free / Subscription / One-Time / Usage-Based |
-| **Billing period** | Only for "Subscription": Monthly / Quarterly / Annually |
-| **Costs** | Amount as a number |
-| **Currency** | EUR / USD / GBP / CHF |
-| **Notes** | Optional free text |
-
-Saving creates the entry. Each cost entry is displayed as a card with
-license badge, billing period, amount (`Amount Currency` or "Free") and
-notes.
-
-## Editing & deleting costs
-
-Hovering over a cost card shows the **Edit** (pencil) and **Delete** (trash)
-actions.
-
-## API
-
-The cost data is managed via the tool endpoints
-(see [API reference](/docs/reference/endpoints/tools)).
diff --git a/docs/releases/v0.8.2/handbook/kosten.md b/docs/releases/v0.8.2/handbook/kosten.md
deleted file mode 100644
index 8904047..0000000
--- a/docs/releases/v0.8.2/handbook/kosten.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-# Kosten erfassen
-
-Auf der Detailseite eines Tools kannst du Kosten- und Lizenzmodelle eintragen,
-damit die Gesamtkosten je Tool transparent werden.
-
-> Kosten ist ein **Premium-Feature** (`costs`, Premium/Enterprise). Admins
-> haben immer Zugriff.
-
-## Kosten hinzufügen
-
-Klicke auf **Kosten hinzufügen** im Kosten-Bereich der Detailseite und fülle
-das Formular aus:
-
-| Feld | Hinweise |
-| --- | --- |
-| **Lizenztyp** | Free / Subscription / One-Time / Usage-Based |
-| **Abrechnungszeitraum** | Nur für „Subscription": Monatlich / Quartalsweise / Jährlich |
-| **Kosten** | Betrag als Zahl |
-| **Währung** | EUR / USD / GBP / CHF |
-| **Notizen** | Optionaler Freitext |
-
-Speichern legt den Eintrag an. Jeder Kosten-Eintrag wird als Karte mit
-Lizenz-Badge, Abrechnungszeitraum, Betrag (`Betrag Währung` bzw. „Free") und
-Notizen angezeigt.
-
-## Kosten bearbeiten & löschen
-
-Beim Überfahren einer Kosten-Karte erscheinen die Aktionen **Bearbeiten**
-(Bleistift) und **Löschen** (Papierkorb).
-
-## API
-
-Die Kosten-Daten werden über die Tool-Endpunkte verwaltet
-(siehe [API-Referenz](/docs/reference/endpoints/tools)).
diff --git a/docs/releases/v0.8.2/handbook/papierkorb.en.md b/docs/releases/v0.8.2/handbook/papierkorb.en.md
deleted file mode 100644
index 7111def..0000000
--- a/docs/releases/v0.8.2/handbook/papierkorb.en.md
+++ /dev/null
@@ -1,40 +0,0 @@
-
-# Trash
-
-The **trash** (`/trash`) contains soft-deleted tools. With trash access
-they can be restored; permanent deletion is reserved for admins.
-
-> The trash is a **premium feature** (`trash`, Premium/Enterprise).
-> Admins always have access.
-
-## Access
-
-The trash can be reached via the user menu or the sidebar.
-Without the `trash` permission, a hint about changing the plan appears.
-
-## Restoring
-
-- Select one or more tools (checkboxes).
-- Click on **Restore (N)** — the tools appear again in all
- public views.
-
-> Restoring is available to anyone with trash access.
-
-## Permanently delete (admin only)
-
-- **Delete (N)** **permanently** removes the selected tools — including
- all ratings, costs and links. This cannot be undone.
-- **Empty trash** permanently removes all soft-deleted tools.
-
-## Table
-
-The trash lists: name, category, **Deleted on** (`tt.MM.jjjj HH:mm`),
-**Deleted by** as well as actions (Restore; Delete admin only). The search
-filters by name.
-
-## API
-
-- [`GET /tools/trash`](/docs/reference/endpoints/tools#listTrashedTools) — list
-- [`POST /tools/trash/restore`](/docs/reference/endpoints/tools#restoreTools) — restore
-- [`DELETE /tools/trash`](/docs/reference/endpoints/tools#deleteTrashedTools) — permanently delete (admin)
-- [`POST /tools/trash/empty`](/docs/reference/endpoints/tools#emptyTrash) — empty trash (admin)
diff --git a/docs/releases/v0.8.2/handbook/papierkorb.md b/docs/releases/v0.8.2/handbook/papierkorb.md
deleted file mode 100644
index 3179c74..0000000
--- a/docs/releases/v0.8.2/handbook/papierkorb.md
+++ /dev/null
@@ -1,41 +0,0 @@
-
-# Papierkorb
-
-Der **Papierkorb** (`/trash`) enthält soft gelöschte Tools. Mit Papierkorb-Zugang
-können sie wiederhergestellt werden; endgültiges Löschen ist Admins vorbehalten.
-
-> Der Papierkorb ist ein **Premium-Feature** (`trash`, Premium/Enterprise).
-> Admins haben immer Zugriff.
-
-## Zugang
-
-Der Papierkorb ist über das Benutzermenü oder die Seitenleiste erreichbar.
-Ohne `trash`-Berechtigung erscheint ein Hinweis auf den Tarifwechsel.
-
-## Wiederherstellen
-
-- Markiere ein oder mehrere Tools (Checkboxen).
-- Klicke auf **Wiederherstellen (N)** — die Tools erscheinen wieder in allen
- öffentlichen Ansichten.
-
-> Wiederherstellen steht jeder Person mit Papierkorb-Zugang zur Verfügung.
-
-## Endgültig löschen (nur Admin)
-
-- **Löschen (N)** entfernt die ausgewählten Tools **endgültig** — inklusive
- aller Bewertungen, Kosten und Verknüpfungen. Das kann nicht rückgängig
- gemacht werden.
-- **Papierkorb leeren** entfernt alle soft gelöschten Tools endgültig.
-
-## Tabelle
-
-Der Papierkorb listet: Name, Kategorie, **Gelöscht am** (`tt.MM.jjjj HH:mm`),
-**Gelöscht von** sowie Aktionen (Wiederherstellen; Löschen nur Admin). Die Suche
-filtert nach Namen.
-
-## API
-
-- [`GET /tools/trash`](/docs/reference/endpoints/tools#listTrashedTools) — Liste
-- [`POST /tools/trash/restore`](/docs/reference/endpoints/tools#restoreTools) — Wiederherstellen
-- [`DELETE /tools/trash`](/docs/reference/endpoints/tools#deleteTrashedTools) — Endgültig löschen (Admin)
-- [`POST /tools/trash/empty`](/docs/reference/endpoints/tools#emptyTrash) — Papierkorb leeren (Admin)
diff --git a/docs/releases/v0.8.2/handbook/redundanz.en.md b/docs/releases/v0.8.2/handbook/redundanz.en.md
deleted file mode 100644
index 27825b3..0000000
--- a/docs/releases/v0.8.2/handbook/redundanz.en.md
+++ /dev/null
@@ -1,38 +0,0 @@
-
-# Redundancy dashboard
-
-The **Redundancy dashboard** (`/admin/redundancy`) is an admin tool for
-automatic detection of duplicate or strongly overlapping tools — per
-category — including cost and rating comparison.
-
-> Access is reserved exclusively for admins (the API is
-> admin-protected).
-
-## Layout
-
-- **Per category** a group is shown: name of the category,
- number of tools and comparisons as well as the **total monthly costs**
- if applicable (e.g. `€X.XX/mo total`).
-- Each tool is displayed as a card: name, monthly costs, number of
- ratings, combined rating, license badges and number of features.
-
-## Comparisons & recommendations
-
-For each tool pair the following appears:
-
-- Tool A vs. Tool B, each with rating (`X.X ★`) and monthly costs.
-- **Overlap** in percent (progress bar in the middle).
-- A **recommendation** with confidence color:
- - **high** (green), **medium** (yellow), **low** (gray)
-- The recommended, better tool is marked with a "thumbs up" and justified.
-
-## Manual rating
-
-You can rate a pair manually: click on Tool A or Tool B to
-record which one is better. The selection is saved and the
-display is updated.
-
-## API
-
-- [`GET /api/admin/redundancy`](#) — load data (admin-protected)
-- [`POST /api/admin/redundancy/evaluate`](#) — save manual rating
diff --git a/docs/releases/v0.8.2/handbook/redundanz.md b/docs/releases/v0.8.2/handbook/redundanz.md
deleted file mode 100644
index 7521ffe..0000000
--- a/docs/releases/v0.8.2/handbook/redundanz.md
+++ /dev/null
@@ -1,38 +0,0 @@
-
-# Redundanz-Dashboard
-
-Das **Redundanz-Dashboard** (`/admin/redundancy`) ist ein Admin-Werkzeug zur
-automatischen Erkennung doppelter oder stark überlappender Tools — jeweils
-pro Kategorie — inklusive Kosten- und Bewertungsvergleich.
-
-> Der Zugriff ist ausschließlich Admins vorbehalten (die API ist
-> admin-geschützt).
-
-## Aufbau
-
-- **Pro Kategorie** wird eine Gruppe angezeigt: Name der Kategorie,
- Anzahl Tools und Vergleiche sowie ggf. die **gesamten monatlichen Kosten**
- (z. B. `€X.XX/mo gesamt`).
-- Jedes Tool wird als Karte dargestellt: Name, monatliche Kosten, Anzahl der
- Bewertungen, kombinierte Bewertung, Lizenz-Badges und Feature-Anzahl.
-
-## Vergleiche & Empfehlungen
-
-Für jedes Tool-Paar erscheint:
-
-- Tool A vs. Tool B, jeweils mit Bewertung (`X.X ★`) und monatlichen Kosten.
-- **Überlappung** in Prozent (Fortschrittsbalken in der Mitte).
-- Eine **Empfehlung** mit Konfidenz-Farbe:
- - **hoch** (grün), **mittel** (gelb), **niedrig** (grau)
-- Das empfohlene, bessere Tool wird mit „Daumen hoch" markiert und begründet.
-
-## Manuelle Bewertung
-
-Du kannst ein Paar manuell bewerten: Klicke auf Tool A oder Tool B, um
-festzuhalten, welches besser ist. Die Auswahl wird gespeichert und die
-Darstellung aktualisiert.
-
-## API
-
-- [`GET /api/admin/redundancy`](#) — Daten laden (admin-geschützt)
-- [`POST /api/admin/redundancy/evaluate`](#) — manuelle Bewertung speichern
diff --git a/docs/releases/v0.8.2/handbook/tastatur.en.md b/docs/releases/v0.8.2/handbook/tastatur.en.md
deleted file mode 100644
index 2eddf47..0000000
--- a/docs/releases/v0.8.2/handbook/tastatur.en.md
+++ /dev/null
@@ -1,36 +0,0 @@
-
-# Keyboard shortcuts & command palette
-
-## Command palette
-
-The command palette is the central quick navigation:
-
-- Open with **`⌘K`** (macOS) or **`Ctrl+K`** (Windows/Linux).
-- Alternatively via the search bar at the top right ("Search tools… ⌘K") or the
- search icon on mobile devices.
-
-### Empty state
-
-Without input, the palette shows:
-
-- **Recently viewed** — the last 5 tools you visited.
-- **Navigation** — browse tools, add tool, analytics as well as
- (depending on permissions) watchlist, trash and admin.
-
-### Search
-
-Type to search for tools live (max. 10 results, incl. rating
-`X.X★`).
-
-## Overview of keyboard shortcuts
-
-| Shortcut | Action |
-| --- | --- |
-| `⌘K` / `Ctrl+K` | Open command palette |
-| `/` | Focus search in the "Browse tools" area |
-
-## Additional notes
-
-- **Recently viewed** is stored locally in the browser (max. 5 entries).
-- The sidebar (left navigation) can be collapsed on desktop; the
- breadcrumb at the top shows your current location.
diff --git a/docs/releases/v0.8.2/handbook/tool-anlegen.en.md b/docs/releases/v0.8.2/handbook/tool-anlegen.en.md
deleted file mode 100644
index 45618cf..0000000
--- a/docs/releases/v0.8.2/handbook/tool-anlegen.en.md
+++ /dev/null
@@ -1,46 +0,0 @@
-
-# Create a tool
-
-To add a new tool to the catalog, click **Add tool**
-(`/tools/new`). Creating a tool requires an account — without being signed in
-a notice with a login button appears.
-
-## Form fields
-
-| Field | Required | Notes |
-| --- | --- | --- |
-| **Name** | Yes | At least 2 characters |
-| **Category** | Yes | Dropdown; new categories can be created directly |
-| **Website URL** | No | Valid URL (e.g. `https://...`) |
-| **Icon / Logo URL** | No | Valid URL; preview is shown live |
-| **Description** | Yes | At least 10 characters; describe what the tool does |
-| **Features** | No | Dynamic list with autocomplete (max. 6) |
-| **Tags** | No | Dynamic list with autocomplete |
-
-Next to each field, the **? icon** takes you directly to the corresponding
-field description in the [data model reference](/docs/reference/schemas/toolinput).
-
-### Category
-
-- Type to search for existing categories.
-- Select **+ Create "..."** to create a new category.
-
-### Features & tags
-
-- **Add feature** / **Add tag** appends a new row.
-- The input fields suggest existing features/tags
- (autocomplete, max. 6 suggestions).
-- Use the **×** button to remove individual rows.
-- Features and tags help with filtering and finding tools again.
-
-## Save
-
-Click **Add tool**. After successful creation you will be redirected to the
-detail page of the new tool.
-
-## API
-
-- [`POST /tools`](/docs/reference/endpoints/tools#createTool) — create a tool
-- [`GET /categories`](/docs/reference/endpoints/tools#listCategories) — categories
-- [`GET /features/all`](/docs/reference/endpoints/tools#listAllFeatures) — features
-- [`GET /tags/all`](/docs/reference/endpoints/tools#listAllTags) — tags
diff --git a/docs/releases/v0.8.2/handbook/tool-anlegen.md b/docs/releases/v0.8.2/handbook/tool-anlegen.md
deleted file mode 100644
index db93745..0000000
--- a/docs/releases/v0.8.2/handbook/tool-anlegen.md
+++ /dev/null
@@ -1,46 +0,0 @@
-
-# Tool anlegen
-
-Um ein neues Tool zum Katalog hinzuzufügen, klicke auf **Tool hinzufügen**
-(`/tools/new`). Das Anlegen erfordert ein Konto — ohne Anmeldung erscheint ein
-Hinweis mit Login-Button.
-
-## Formularfelder
-
-| Feld | Pflicht | Hinweise |
-| --- | --- | --- |
-| **Name** | Ja | Mind. 2 Zeichen |
-| **Kategorie** | Ja | Auswahlliste; neue Kategorien lassen sich direkt anlegen |
-| **Website URL** | Nein | Gültige URL (z. B. `https://...`) |
-| **Icon / Logo URL** | Nein | Gültige URL; Vorschau wird live angezeigt |
-| **Beschreibung** | Ja | Mind. 10 Zeichen; beschreibe, was das Tool tut |
-| **Features** | Nein | Dynamische Liste mit Autovervollständigung (max. 6) |
-| **Tags** | Nein | Dynamische Liste mit Autovervollständigung |
-
-Neben jedem Feld führt das **?‑Icon** direkt zur zugehörigen Feldbeschreibung
-in der [Datenmodell-Referenz](/docs/reference/schemas/toolinput).
-
-### Kategorie
-
-- Tippe, um nach bestehenden Kategorien zu suchen.
-- Wähle **+ Erstelle „..."**, um eine neue Kategorie anzulegen.
-
-### Features & Tags
-
-- **Feature hinzufügen** / **Tag hinzufügen** hängt eine neue Zeile an.
-- Die Eingabefelder schlagen bestehende Features/Tags vor
- (Autovervollständigung, max. 6 Vorschläge).
-- Mit dem **×**‑Button entfernst du einzelne Zeilen.
-- Features und Tags helfen beim Filtern und Wiederfinden.
-
-## Speichern
-
-Klicke auf **Tool hinzufügen**. Nach erfolgreicher Anlage wirst du auf die
-Detailseite des neuen Tools weitergeleitet.
-
-## API
-
-- [`POST /tools`](/docs/reference/endpoints/tools#createTool) — Tool anlegen
-- [`GET /categories`](/docs/reference/endpoints/tools#listCategories) — Kategorien
-- [`GET /features/all`](/docs/reference/endpoints/tools#listAllFeatures) — Features
-- [`GET /tags/all`](/docs/reference/endpoints/tools#listAllTags) — Tags
diff --git a/docs/releases/v0.8.2/handbook/tool-bearbeiten.en.md b/docs/releases/v0.8.2/handbook/tool-bearbeiten.en.md
deleted file mode 100644
index 9921517..0000000
--- a/docs/releases/v0.8.2/handbook/tool-bearbeiten.en.md
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# Edit & delete tools
-
-## Editing
-
-On the detail page of a tool you will find the **Edit** button
-(only for the person who created the tool, as well as for admins).
-
-The edit page (`/tools/:id/edit`) contains the same fields as when
-creating (name, category, website/icon URL, description, features, tags) —
-already filled with the current values.
-
-- **Save** applies the changes.
-- **Cancel** takes you back to the detail page.
-
-API reference: [`PATCH /tools/{id}`](/docs/reference/endpoints/tools#updateTool).
-
-## Deleting
-
-Via **Delete** on the detail page the tool is removed. The behavior
-depends on your plan:
-
-- **With trash access** (Premium/Enterprise or Admin): the tool is
- **soft deleted** — it disappears from all public views, but can
- be restored or permanently deleted in the [trash](/docs/handbook/papierkorb).
-- **Without trash access:** the tool is **permanently** deleted and cannot
- be restored.
-
-Deletion is only possible for the person who created the tool, as well as
-for admins.
-
-API reference: [`DELETE /tools/{id}`](/docs/reference/endpoints/tools#deleteTool).
diff --git a/docs/releases/v0.8.2/handbook/tool-bearbeiten.md b/docs/releases/v0.8.2/handbook/tool-bearbeiten.md
deleted file mode 100644
index 7f2fd3f..0000000
--- a/docs/releases/v0.8.2/handbook/tool-bearbeiten.md
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Tool bearbeiten & löschen
-
-## Bearbeiten
-
-Auf der Detailseite eines Tools findest du die Schaltfläche **Bearbeiten**
-(nur für die Person, die das Tool angelegt hat, sowie für Admins).
-
-Die Bearbeitungsseite (`/tools/:id/edit`) enthält dieselben Felder wie beim
-Anlegen (Name, Kategorie, Website/Icon-URL, Beschreibung, Features, Tags) —
-bereits mit den aktuellen Werten befüllt.
-
-- **Speichern** übernimmt die Änderungen.
-- **Abbrechen** führt zurück zur Detailseite.
-
-API-Referenz: [`PATCH /tools/{id}`](/docs/reference/endpoints/tools#updateTool).
-
-## Löschen
-
-Über **Löschen** auf der Detailseite wird das Tool entfernt. Das Verhalten
-hängt von deinem Tarif ab:
-
-- **Mit Papierkorb-Zugang** (Premium/Enterprise oder Admin): Das Tool wird
- **soft gelöscht** — es verschwindet aus allen öffentlichen Ansichten, kann
- aber im [Papierkorb](/docs/handbook/papierkorb) wiederhergestellt oder
- endgültig gelöscht werden.
-- **Ohne Papierkorb-Zugang:** Das Tool wird **endgültig** gelöscht und kann
- nicht wiederhergestellt werden.
-
-Die Löschung ist nur für die Person, die das Tool angelegt hat, sowie für
-Admins möglich.
-
-API-Referenz: [`DELETE /tools/{id}`](/docs/reference/endpoints/tools#deleteTool).
diff --git a/docs/releases/v0.8.2/handbook/tools-finden.en.md b/docs/releases/v0.8.2/handbook/tools-finden.en.md
deleted file mode 100644
index 6483d44..0000000
--- a/docs/releases/v0.8.2/handbook/tools-finden.en.md
+++ /dev/null
@@ -1,66 +0,0 @@
-
-# Find & browse tools
-
-The **Browse tools** section (`/tools`) is your entry point to the catalog.
-Here you combine search, filters and sorting to find exactly the tools
-you are interested in.
-
-## Search
-
-- The **search bar** searches name and description (full text).
-- Shortcut: Press **`/`** to focus the search.
-- The input is debounced so that filtering happens immediately with each
- keystroke.
-
-## Filter
-
-Via the **Filter** button (with a badge for the number of active filters)
-you open the filter popover with:
-
-- **Tags** — selection via checkboxes (scrollable list).
-- **Features** — selection via checkboxes.
-- **Minimum rating** — slider from 0 to 5 (in steps of 0.5); shows
- e.g. "3.0+".
-
-Active filters appear as **removable chips** above the result list.
-Use **Reset filters** or **Remove all** to clear them again.
-
-## Sort
-
-The **Sort** dropdown offers the following options:
-
-| Sort | Description |
-| --- | --- |
-| Newest | New tools first |
-| Top rated | By combined rating |
-| Most rated | By number of ratings |
-| Name (A–Z) | Alphabetically ascending |
-| Name (Z–A) | Alphabetically descending |
-| Last updated | By last update |
-
-## View & density
-
-- **Switch view:** grid / table / rows.
-- **Density:** comfortable / compact (slider).
-
-Your selection is saved — locally in the browser and, for logged-in users,
-additionally on the server in the preferences. View, density, search, filters
-and sorting are reflected in the URL so you can share results.
-
-## Table view
-
-In the table view the columns **Tool**, **Rating** and **Number of
-ratings** are sortable. Hovering over a row shows a preview
-with rating details, tags and mini bars.
-
-## Selecting for comparison & watchlist
-
-- On every card/row you find a **compare icon** that lets you add tools to the
- [compare bar](/docs/handbook/vergleichen).
-- The **bookmark icon** saves tools to your
- [watchlist](/docs/handbook/watchlist) (only with the corresponding plan).
-
-## API
-
-All search, filter and sort parameters correspond to the query parameters of
-[`GET /tools`](/docs/reference/endpoints/tools#listTools).
diff --git a/docs/releases/v0.8.2/handbook/vergleichen.en.md b/docs/releases/v0.8.2/handbook/vergleichen.en.md
deleted file mode 100644
index b2e0635..0000000
--- a/docs/releases/v0.8.2/handbook/vergleichen.en.md
+++ /dev/null
@@ -1,42 +0,0 @@
-
-# Compare
-
-With the compare function you can put several tools **side by side** —
-ideal for making a well-informed decision.
-
-> Comparing is a **premium feature** (Premium/Enterprise) and is always
-> available to admins.
-
-## Selecting tools
-
-1. In the **Browse tools** section, click the **compare icon** (scales) on
- each card/row.
-2. The **compare bar** appears at the bottom with the selected tools as
- chips. You can remove individual tools (×) or clear the selection.
-3. Click **Compare (N)** to go to the compare view.
-
-> Without a premium plan the button is locked (lock icon). The dialog takes
-> you to the plan switch
-> (see [Plans & permissions](/docs/handbook/plaene)).
-
-## The compare view
-
-The view shows a table with one column per tool. Rows:
-
-| Row | Content |
-| --- | --- |
-| **Rating** | Stars + value (e.g. `4.2/5`) |
-| **Usefulness** | Value (X.X/5) |
-| **Usability** | Value (X.X/5) |
-| **Number of ratings** | Count |
-| **Description** | Text |
-| **Features** | Badges |
-| **Tags** | Badges |
-| **Last updated** | Date |
-
-The **best value** per row is highlighted (with trophy icon).
-
-## API
-
-The compare view reads the data via
-[`GET /compare`](/docs/reference/endpoints/tools#listCompareTools).
diff --git a/docs/releases/v0.8.2/handbook/vergleichen.md b/docs/releases/v0.8.2/handbook/vergleichen.md
deleted file mode 100644
index ddcf0de..0000000
--- a/docs/releases/v0.8.2/handbook/vergleichen.md
+++ /dev/null
@@ -1,42 +0,0 @@
-
-# Vergleichen
-
-Mit der Vergleichsfunktion stellst du mehrere Tools **nebeneinander** gegenüber —
-ideal, um eine fundierte Entscheidung zu treffen.
-
-> Vergleichen ist ein **Premium-Feature** (Premium/Enterprise) und steht Admins
-> immer zur Verfügung.
-
-## Tools auswählen
-
-1. Im Bereich **Tools durchsuchen** klickst du auf jeder Karte/Zeile auf das
- **Vergleichs-Icon** (Waage).
-2. Unten erscheint die **Vergleichsleiste** mit den ausgewählten Tools als
- Chips. Du kannst einzelne Tools entfernen (×) oder die Auswahl leeren.
-3. Klicke auf **Vergleichen (N)**, um zur Vergleichsansicht zu gelangen.
-
-> Ohne Premium-Tarif ist der Button gesperrt (Schloss-Icon). Über den
-> Dialog gelangst du zum Tarifwechsel
-> (siehe [Pläne & Berechtigungen](/docs/handbook/plaene)).
-
-## Die Vergleichsansicht
-
-Die Ansicht zeigt eine Tabelle mit einer Spalte pro Tool. Zeilen:
-
-| Zeile | Inhalt |
-| --- | --- |
-| **Bewertung** | Sterne + Wert (z. B. `4.2/5`) |
-| **Nützlichkeit** | Wert (X.X/5) |
-| **Bedienbarkeit** | Wert (X.X/5) |
-| **Anzahl Bewertungen** | Anzahl |
-| **Beschreibung** | Text |
-| **Features** | Badges |
-| **Tags** | Badges |
-| **Zuletzt aktualisiert** | Datum |
-
-Der **beste Wert** pro Zeile wird hervorgehoben (mit Trophäen-Icon).
-
-## API
-
-Die Vergleichsansicht liest die Daten über
-[`GET /compare`](/docs/reference/endpoints/tools#listCompareTools).
diff --git a/docs/releases/v0.8.2/handbook/watchlist.en.md b/docs/releases/v0.8.2/handbook/watchlist.en.md
deleted file mode 100644
index 55da963..0000000
--- a/docs/releases/v0.8.2/handbook/watchlist.en.md
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Watchlist
-
-The **watchlist** is a personal favorites list. You can open and compare the
-tools in it at any time with a click.
-
-> The watchlist is a **premium feature** (Premium/Enterprise) and is always
-> available to admins.
-
-## Prerequisite
-
-You need a plan with the `watchlist` permission. If it is missing, a note
-about switching plans appears at the bookmark
-(see [Plans & permissions](/docs/handbook/plaene)).
-
-## Saving a tool
-
-- On every card/row in the **Browse tools** section you will find the
- **bookmark icon**.
-- A click saves the tool to your watchlist — the icon becomes filled.
-- Clicking it again removes it.
-
-## Viewing the watchlist
-
-Open the watchlist via the user menu or the sidebar. It shows all saved tools
-as cards. The filled bookmark on a card removes the tool from the list.
-
-## Where is the watchlist stored?
-
-The watchlist is a list of tool IDs in your **user preferences**. This way it
-is linked to your account across devices.
-
-API reference: [`GET /auth/me/watchlist`](/docs/reference/endpoints/auth#getMeWatchlist).
diff --git a/docs/releases/v0.8.2/handbook/watchlist.md b/docs/releases/v0.8.2/handbook/watchlist.md
deleted file mode 100644
index 783da0c..0000000
--- a/docs/releases/v0.8.2/handbook/watchlist.md
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# Watchlist
-
-Die **Watchlist** ist eine persönliche Favoritenliste. Tools darin kannst du
-jederzeit per Klick wieder aufrufen und vergleichen.
-
-> Die Watchlist ist ein **Premium-Feature** (Premium/Enterprise) und steht
-> Admins immer zur Verfügung.
-
-## Voraussetzung
-
-Du benötigst einen Tarif mit `watchlist`-Berechtigung. Fehlt diese, erscheint
-beim Lesezeichen ein Hinweis auf den Tarifwechsel
-(siehe [Pläne & Berechtigungen](/docs/handbook/plaene)).
-
-## Tool speichern
-
-- Auf jeder Karte/Zeile im Bereich **Tools durchsuchen** findest du das
- **Lesezeichen-Icon**.
-- Ein Klick speichert das Tool in deiner Watchlist — das Icon wird gefüllt.
-- Ein erneuter Klick entfernt es wieder.
-
-## Watchlist ansehen
-
-Öffne die Watchlist über das Benutzermenü oder die Seitenleiste. Sie zeigt alle
-gespeicherten Tools als Karten. Das gefüllte Lesezeichen auf einer Karte
-entfernt das Tool aus der Liste.
-
-## Wo wird die Watchlist gespeichert?
-
-Die Watchlist ist eine Liste von Tool-IDs in deinen **Benutzerpräferenzen**.
-Damit ist sie geräteübergreifend mit deinem Konto verbunden.
-
-API-Referenz: [`GET /auth/me/watchlist`](/docs/reference/endpoints/auth#getMeWatchlist).
diff --git a/docs/releases/v0.8.2/reference.json b/docs/releases/v0.8.2/reference.json
deleted file mode 100644
index a3adfd9..0000000
--- a/docs/releases/v0.8.2/reference.json
+++ /dev/null
@@ -1,2782 +0,0 @@
-{
- "tags": [
- {
- "name": "health",
- "description": "Health operations",
- "endpoints": [
- {
- "operationId": "healthCheck",
- "method": "GET",
- "path": "/healthz",
- "summary": "Health check",
- "description": "Returns server health status",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Healthy",
- "schema": {
- "kind": "ref",
- "value": "HealthStatus"
- }
- }
- ]
- },
- {
- "operationId": "getVersion",
- "method": "GET",
- "path": "/version",
- "summary": "Build version information",
- "description": "Returns the running build version, commit SHA and build date",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Version information",
- "schema": {
- "kind": "ref",
- "value": "VersionInfo"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "tools",
- "description": "Tool management",
- "endpoints": [
- {
- "operationId": "listTools",
- "method": "GET",
- "path": "/tools",
- "summary": "List all tools",
- "description": "",
- "parameters": [
- {
- "name": "category",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "sort",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "newest, top_rated, most_reviewed, name_asc, name_desc, recently_updated"
- },
- {
- "name": "tags",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tags; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "features",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated features; tool must include all of them",
- "constraints": ""
- },
- {
- "name": "minRating",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "number"
- },
- "description": "Minimum average combined rating (0-5)",
- "constraints": "0–5"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of tools",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- }
- ]
- },
- {
- "operationId": "createTool",
- "method": "POST",
- "path": "/tools",
- "summary": "Create a new tool",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCompareTools",
- "method": "GET",
- "path": "/compare",
- "summary": "Compare tools side by side (premium)",
- "description": "",
- "parameters": [
- {
- "name": "ids",
- "in": "query",
- "required": true,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "Comma-separated tool ids",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tools in requested order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Authentication required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getToolRatingHistory",
- "method": "GET",
- "path": "/tools/{id}/rating-history",
- "summary": "Get a tool's rating history over time",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating history",
- "schema": {
- "kind": "array",
- "value": "RatingHistoryItem"
- }
- },
- {
- "status": "400",
- "description": "Invalid id",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getTool",
- "method": "GET",
- "path": "/tools/{id}",
- "summary": "Get a tool by ID",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Tool details",
- "schema": {
- "kind": "ref",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateTool",
- "method": "PATCH",
- "path": "/tools/{id}",
- "summary": "Update a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ToolUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated tool",
- "schema": {
- "kind": "ref",
- "value": "Tool"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTool",
- "method": "DELETE",
- "path": "/tools/{id}",
- "summary": "Delete a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "404",
- "description": "Not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listTrashedTools",
- "method": "GET",
- "path": "/tools/trash",
- "summary": "List trashed (soft-deleted) tools",
- "description": "",
- "parameters": [
- {
- "name": "search",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "List of trashed tools",
- "schema": {
- "kind": "array",
- "value": "Tool"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "trashTools",
- "method": "POST",
- "path": "/tools/trash",
- "summary": "Move tools to trash (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools trashed",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteTrashedTools",
- "method": "DELETE",
- "path": "/tools/trash",
- "summary": "Permanently delete trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "restoreTools",
- "method": "POST",
- "path": "/tools/trash/restore",
- "summary": "Restore trashed tools",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "TrashToolsInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Tools restored",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Feature \"trash\" requires a higher tier",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "emptyTrash",
- "method": "POST",
- "path": "/tools/trash/empty",
- "summary": "Permanently delete all trashed tools (admin)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Trash emptied",
- "schema": {
- "kind": "type",
- "value": "object"
- }
- },
- {
- "status": "403",
- "description": "Admin required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "listCategories",
- "method": "GET",
- "path": "/categories",
- "summary": "List all distinct tool categories",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Categories list",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllFeatures",
- "method": "GET",
- "path": "/features/all",
- "summary": "List all distinct feature strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known features",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- },
- {
- "operationId": "listAllTags",
- "method": "GET",
- "path": "/tags/all",
- "summary": "List all distinct tag strings across all tools",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "All known tags",
- "schema": {
- "kind": "array",
- "value": "string"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "ratings",
- "description": "Tool ratings",
- "endpoints": [
- {
- "operationId": "listToolRatings",
- "method": "GET",
- "path": "/tools/{id}/ratings",
- "summary": "List ratings for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Ratings list",
- "schema": {
- "kind": "array",
- "value": "Rating"
- }
- }
- ]
- },
- {
- "operationId": "createRating",
- "method": "POST",
- "path": "/tools/{id}/ratings",
- "summary": "Submit a rating for a tool",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "RatingInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created rating",
- "schema": {
- "kind": "ref",
- "value": "Rating"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "Tool not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "analytics",
- "description": "Analytics and aggregated statistics",
- "endpoints": [
- {
- "operationId": "getAnalyticsSummary",
- "method": "GET",
- "path": "/analytics/summary",
- "summary": "Overall platform statistics",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Platform-level summary stats",
- "schema": {
- "kind": "ref",
- "value": "AnalyticsSummary"
- }
- }
- ]
- },
- {
- "operationId": "getTopTools",
- "method": "GET",
- "path": "/analytics/top-tools",
- "summary": "Top-rated tools",
- "description": "",
- "parameters": [
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "metric",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": "usefulness, usability, combined"
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Top tools list",
- "schema": {
- "kind": "array",
- "value": "TopToolEntry"
- }
- }
- ]
- },
- {
- "operationId": "getAnalyticsByCategory",
- "method": "GET",
- "path": "/analytics/by-category",
- "summary": "Rating statistics grouped by category",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Per-category statistics",
- "schema": {
- "kind": "array",
- "value": "CategoryStats"
- }
- }
- ]
- },
- {
- "operationId": "getRatingDistribution",
- "method": "GET",
- "path": "/analytics/rating-distribution",
- "summary": "Distribution of rating scores across the platform",
- "description": "",
- "parameters": [
- {
- "name": "toolId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Rating score distribution",
- "schema": {
- "kind": "ref",
- "value": "RatingDistribution"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "auth",
- "description": "Authentication",
- "endpoints": [
- {
- "operationId": "getAuthMode",
- "method": "GET",
- "path": "/auth/mode",
- "summary": "Get authentication mode (oidc or local)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Auth mode",
- "schema": {
- "kind": "ref",
- "value": "AuthMode"
- }
- }
- ]
- },
- {
- "operationId": "getCsrfToken",
- "method": "GET",
- "path": "/auth/csrf",
- "summary": "Get a CSRF token for state-changing requests",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "CSRF token",
- "schema": {
- "kind": "ref",
- "value": "CsrfToken"
- }
- }
- ]
- },
- {
- "operationId": "localLogin",
- "method": "POST",
- "path": "/auth/login",
- "summary": "Local username/password login",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "LocalLoginInput"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Logged in successfully",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Invalid credentials",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMe",
- "method": "GET",
- "path": "/auth/me",
- "summary": "Get current authenticated user",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Current user info",
- "schema": {
- "kind": "ref",
- "value": "AuthUser"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "changeMyPassword",
- "method": "POST",
- "path": "/auth/me/password",
- "summary": "Change own password (local users only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "ChangePasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password changed",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Invalid input or wrong current password",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getPasswordRedirect",
- "method": "GET",
- "path": "/auth/password-redirect",
- "summary": "Get redirect URL for managing credentials in the identity provider",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Redirect URL (null in local mode)",
- "schema": {
- "kind": "ref",
- "value": "PasswordRedirect"
- }
- }
- ]
- },
- {
- "operationId": "getMePreferences",
- "method": "GET",
- "path": "/auth/me/preferences",
- "summary": "Get current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateMePreferences",
- "method": "PUT",
- "path": "/auth/me/preferences",
- "summary": "Update current user's browse preferences",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated preferences",
- "schema": {
- "kind": "ref",
- "value": "UserPreferences"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "getMeWatchlist",
- "method": "GET",
- "path": "/auth/me/watchlist",
- "summary": "Get current user's watchlist tools (premium)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Watchlist tools in saved order",
- "schema": {
- "kind": "array",
- "value": "ToolWithStats"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Premium feature required",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "users",
- "description": "User management (admin only)",
- "endpoints": [
- {
- "operationId": "listUsers",
- "method": "GET",
- "path": "/users",
- "summary": "List all local users (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "User list",
- "schema": {
- "kind": "array",
- "value": "User"
- }
- },
- {
- "status": "401",
- "description": "Not authenticated",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "403",
- "description": "Forbidden",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "createUser",
- "method": "POST",
- "path": "/users",
- "summary": "Create a new local user (admin only)",
- "description": "",
- "parameters": [],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserCreateInput"
- }
- },
- "responses": [
- {
- "status": "201",
- "description": "Created user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "409",
- "description": "Username already exists",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "updateUser",
- "method": "PATCH",
- "path": "/users/{id}",
- "summary": "Update user role (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "UserRoleUpdate"
- }
- },
- "responses": [
- {
- "status": "200",
- "description": "Updated user",
- "schema": {
- "kind": "ref",
- "value": "User"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- },
- {
- "operationId": "deleteUser",
- "method": "DELETE",
- "path": "/users/{id}",
- "summary": "Delete a user (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "204",
- "description": "Deleted",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- }
- ]
- },
- {
- "operationId": "setUserPassword",
- "method": "PATCH",
- "path": "/users/{id}/password",
- "summary": "Set/reset a user's password (admin only, local users only)",
- "description": "",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": {
- "required": true,
- "schema": {
- "kind": "ref",
- "value": "SetPasswordInput"
- }
- },
- "responses": [
- {
- "status": "204",
- "description": "Password updated",
- "schema": {
- "kind": "type",
- "value": "any"
- }
- },
- {
- "status": "400",
- "description": "Validation error",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "404",
- "description": "User not found",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "422",
- "description": "OIDC user - password is managed by the identity provider",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- },
- {
- "status": "429",
- "description": "Too many attempts",
- "schema": {
- "kind": "ref",
- "value": "ErrorResponse"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "audit",
- "description": "Audit log",
- "endpoints": [
- {
- "operationId": "listAuditLogs",
- "method": "GET",
- "path": "/audit-logs",
- "summary": "List audit log entries (admin only)",
- "description": "",
- "parameters": [
- {
- "name": "entityType",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "string"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- },
- {
- "name": "limit",
- "in": "query",
- "required": false,
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "description": "",
- "constraints": ""
- }
- ],
- "requestBody": null,
- "responses": [
- {
- "status": "200",
- "description": "Audit log entries",
- "schema": {
- "kind": "array",
- "value": "AuditLog"
- }
- }
- ]
- }
- ]
- }
- ],
- "schemas": [
- {
- "name": "HealthStatus",
- "description": "",
- "fields": [
- {
- "name": "status",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "VersionInfo",
- "description": "",
- "fields": [
- {
- "name": "version",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "commitSha",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "buildDate",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "trashRetentionDays",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthMode",
- "description": "",
- "fields": [
- {
- "name": "mode",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "oidc, local"
- }
- ]
- },
- {
- "name": "CsrfToken",
- "description": "",
- "fields": [
- {
- "name": "token",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "LocalLoginInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "User",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "authProvider",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "local, oidc"
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "UserCreateInput",
- "description": "",
- "fields": [
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 2 chars"
- },
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "UserRoleUpdate",
- "description": "",
- "fields": [
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- }
- ]
- },
- {
- "name": "ChangePasswordInput",
- "description": "",
- "fields": [
- {
- "name": "currentPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "newPassword",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "SetPasswordInput",
- "description": "",
- "fields": [
- {
- "name": "password",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 6 chars"
- }
- ]
- },
- {
- "name": "PasswordRedirect",
- "description": "",
- "fields": [
- {
- "name": "url",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuditLog",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityType",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "entityId",
- "type": {
- "kind": "type",
- "value": "integer | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "action",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "userId",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "username",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "changes",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "Tool",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedAt",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "deletedBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingHistoryItem",
- "description": "",
- "fields": [
- {
- "name": "date",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "combined",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolWithStats",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdBy",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "updatedAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolInput",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ToolUpdate",
- "description": "",
- "fields": [
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "min 1 chars"
- },
- {
- "name": "description",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "websiteUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "iconUrl",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "features",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "tags",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TrashToolsInput",
- "description": "",
- "fields": [
- {
- "name": "ids",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "min 1 items, max 500 items"
- }
- ]
- },
- {
- "name": "Rating",
- "description": "",
- "fields": [
- {
- "name": "id",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolId",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "createdAt",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": "date-time"
- }
- ]
- },
- {
- "name": "RatingInput",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "usability",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": "1–5"
- },
- {
- "name": "comment",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "reviewerName",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AnalyticsSummary",
- "description": "",
- "fields": [
- {
- "name": "totalTools",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgCombined",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "categoriesCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "mostRatedTool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "TopToolEntry",
- "description": "",
- "fields": [
- {
- "name": "tool",
- "type": {
- "kind": "ref",
- "value": "ToolWithStats"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "number"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "ratingCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "CategoryStats",
- "description": "",
- "fields": [
- {
- "name": "category",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "toolCount",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "totalRatings",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsefulness",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "avgUsability",
- "type": {
- "kind": "type",
- "value": "number | null"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "RatingDistribution",
- "description": "",
- "fields": [
- {
- "name": "usefulness",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "usability",
- "type": {
- "kind": "array",
- "value": "ScoreBucket"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ScoreBucket",
- "description": "",
- "fields": [
- {
- "name": "score",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "count",
- "type": {
- "kind": "type",
- "value": "integer"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "AuthUser",
- "description": "",
- "fields": [
- {
- "name": "sub",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- },
- {
- "name": "email",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "name",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "preferredUsername",
- "type": {
- "kind": "type",
- "value": "string | null"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "role",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "admin, user"
- },
- {
- "name": "tier",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "free, premium, enterprise"
- },
- {
- "name": "entitlements",
- "type": {
- "kind": "array",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": ""
- },
- {
- "name": "isLocal",
- "type": {
- "kind": "type",
- "value": "boolean"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "UserPreferences",
- "description": "",
- "fields": [
- {
- "name": "view",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "grid, table, rows"
- },
- {
- "name": "density",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": false,
- "description": "",
- "constraints": "cozy, compact"
- },
- {
- "name": "watchlist",
- "type": {
- "kind": "array",
- "value": "integer"
- },
- "required": false,
- "description": "",
- "constraints": ""
- }
- ]
- },
- {
- "name": "ErrorResponse",
- "description": "",
- "fields": [
- {
- "name": "error",
- "type": {
- "kind": "type",
- "value": "string"
- },
- "required": true,
- "description": "",
- "constraints": ""
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/docs/releases/v0.8.3.en.md b/docs/releases/v0.8.3.en.md
deleted file mode 100644
index 8998402..0000000
--- a/docs/releases/v0.8.3.en.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# v0.8.3 — Release Notes
-
-**Date:** 2026-08-04 · **Tag:** [`v0.8.3`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.3)
-
-## New features
-
-- **Version-based documentation**: Each release now carries a
- complete docs snapshot (manual + API reference). Via the
- version dropdown you can reach the docs of the respective version
- (`/docs/vX.Y.Z/…`) — including the manual and reference as they
- applied at release time. The last 7 versions remain available.
-- **Help buttons in forms (NetBox style)**: For evaluation, tool
- create/edit, costs, comparing, watchlist and analytics there is now
- a help icon that leads directly to the matching guide in the manual.
-
-## Fixes & improvements
-
-- **Gitea tag links fixed**: `…/tags/vX.Y.Z` was a 404 page; the
- correct URL is `/releases/tag/vX.Y.Z` (in all release notes and the
- docs page).
-- Version switching now leads to the docs of the selected version instead of
- just the release page; old `/docs/vX.Y.Z` redirects are removed.
-- Docs generator: `--snapshot` creates manual + reference per version; on
- build, the snapshots of the last 7 versions are included.
-
-## API changes
-
-- No changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none. New release notes must use the correct
- tag link (see `docs/releases/TEMPLATE.md`). For versions before
- this release, snapshots can be created retroactively:
- `node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`.
-
-## Known limitations
-
-- Older releases without a snapshot (e.g. v0.6.0) only show their release notes,
- no manual/reference. Backfill with `--snapshot`.
-- The docs version corresponds to the state of the docs at the time the
- snapshot was created; manual changes apply from the respective next release.
-
-## Links
-
-- Commit: [`3bb4598`](https://git.kubebase.de/admin/tool-evaluator/commit/3bb4598)
-- Tag: [`v0.8.3`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.3)
diff --git a/docs/releases/v0.8.3.md b/docs/releases/v0.8.3.md
deleted file mode 100644
index 3cc81a4..0000000
--- a/docs/releases/v0.8.3.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# v0.8.3 — Release Notes
-
-**Datum:** 2026-08-04 · **Tag:** [`v0.8.3`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.3)
-
-## Neue Features
-
-- **Versionsbasierte Dokumentation**: Jedes Release trägt jetzt einen
- vollständigen Doku-Snapshot (Handbuch + API-Referenz). Über das
- Versions-Dropdown gelangst du zur Doku der jeweiligen Version
- (`/docs/vX.Y.Z/…`) — inklusive Handbuch und Referenz, wie sie zum
- Release-Zeitpunkt galten. Die letzten 7 Versionen bleiben verfügbar.
-- **Hilfe-Buttons in Formularen (NetBox-Stil)**: Bei Bewertung, Tool
- anlegen/bearbeiten, Kosten, Vergleichen, Merkliste und Analytics gibt es
- jetzt ein Hilfe-Icon, das direkt zur passenden Anleitung im Handbuch führt.
-
-## Fixes & Verbesserungen
-
-- **Gitea-Tag-Links korrigiert**: `…/tags/vX.Y.Z` war eine 404-Seite; die
- korrekte URL lautet `/releases/tag/vX.Y.Z` (in allen Release-Notes und der
- Doku-Seite).
-- Versions-Wechsel führt jetzt zur Doku der gewählten Version statt direkt
- nur zur Release-Seite; alte `/docs/vX.Y.Z`-Redirects entfallen.
-- Doku-Generator: `--snapshot` erzeugt Handbuch + Referenz pro Version; beim
- Build werden die Snapshots der letzten 7 Versionen eingespielt.
-
-## API-Änderungen
-
-- Keine Änderungen an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine. Neue Release-Notes müssen den korrekten
- Tag-Link verwenden (siehe `docs/releases/TEMPLATE.md`). Für Versionen vor
- diesem Release können Snapshots nachträglich erzeugt werden:
- `node scripts/src/generate-docs.mjs --snapshot vX.Y.Z`.
-
-## Bekannte Einschränkungen
-
-- Ältere Releases ohne Snapshot (z. B. v0.6.0) zeigen nur ihre Release-Notes,
- kein Handbuch/keine Referenz. Mit `--snapshot` nachpflegen.
-- Die Doku-Version entspricht dem Doku-Stand zum Zeitpunkt der Erstellung des
- Snapshots; Änderungen am Handbuch gelten ab dem jeweils nächsten Release.
-
-## Links
-
-- Commit: [`3bb4598`](https://git.kubebase.de/admin/tool-evaluator/commit/3bb4598)
-- Tag: [`v0.8.3`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.3)
diff --git a/docs/releases/v0.8.4.en.md b/docs/releases/v0.8.4.en.md
deleted file mode 100644
index c668e2f..0000000
--- a/docs/releases/v0.8.4.en.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# v0.8.4 — Release Notes
-
-**Date:** 2026-08-04 · **Tag:** [`v0.8.4`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.4)
-
-## New features
-
-- **Full app localization (German/English)**: All pages and components are
- now translated — tool detail page, admin area, trash, redundancy dashboard,
- compare, watchlist, analytics, create and edit tool, admin tools tab,
- category combobox and theme toggle. The language picker in the top right
- switches the whole UI.
-- **Bilingual documentation**: The manual (all 17 pages) and the release
- notes are now available in German and English. The docs page has a
- language switcher that switches content, navigation titles and search.
- Versioned docs snapshots (v0.8.1, v0.8.2) also contain the English pages.
-
-## Fixes & improvements
-
-- All remaining hardcoded UI strings replaced with `t()` calls; the locales
- are in sync (453 keys per language, 0 missing).
-- API reference: table headers (Name/In), required badges and request body
- labels in the docs are translated.
-- Docs search respects the active language (separate index per language).
-
-## API changes
-
-- No changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none. The docs generator output now includes
- additional English files (`*.en.md`) and `search.en.json`; these are
- generated automatically during the build.
-
-## Known limitations
-
-- Versioned docs snapshots before v0.8.1 (e.g. v0.6.0) do not contain
- English manual pages; the German version is used as fallback there.
-
-## Links
-
-- Commit: [`3de59cc`](https://git.kubebase.de/admin/tool-evaluator/commit/3de59cc)
-- Tag: [`v0.8.4`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.4)
diff --git a/docs/releases/v0.8.4.md b/docs/releases/v0.8.4.md
deleted file mode 100644
index db2c936..0000000
--- a/docs/releases/v0.8.4.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# v0.8.4 — Release Notes
-
-**Datum:** 2026-08-04 · **Tag:** [`v0.8.4`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.4)
-
-## Neue Features
-
-- **Komplette Lokalisierung der App (Deutsch/Englisch)**: Alle Seiten und
- Komponenten sind jetzt übersetzt — Tool-Detailseite, Verwaltung, Papierkorb,
- Redundanz-Dashboard, Vergleichen, Merkliste, Analytics, Tool anlegen und
- bearbeiten, Admin-Bereich inkl. Tools-Tab, Kategorie-Combobox und
- Theme-Umschalter. Die Sprachauswahl oben rechts wechselt die gesamte
- Oberfläche.
-- **Dokumentation zweisprachig**: Handbuch (alle 17 Seiten) und Release-Notes
- sind jetzt in Deutsch und Englisch verfügbar. In der Doku gibt es einen
- Sprach-Umschalter, der Inhalte, Navigationstitel und Suche umschaltet.
- Auch versionierte Doku-Snapshots (v0.8.1, v0.8.2) enthalten die englischen
- Seiten.
-
-## Fixes & Verbesserungen
-
-- Alle verbliebenen hartkodierten UI-Strings durch `t()`-Aufrufe ersetzt;
- die Locales sind synchron (453 Keys pro Sprache, 0 fehlend).
-- API-Referenz: Tabellen-Header (Name/In), Pflicht-Badges und
- Request-Body-Label der Doku übersetzt.
-- Suche in der Doku berücksichtigt die aktive Sprache (eigener Index pro
- Sprache).
-
-## API-Änderungen
-
-- Keine Änderungen an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine. Die Doku-Generator-Ausgabe umfasst jetzt
- zusätzliche englische Dateien (`*.en.md`) und `search.en.json`; beim Build
- werden diese automatisch erzeugt.
-
-## Bekannte Einschränkungen
-
-- Versionierte Doku-Snapshots vor v0.8.1 (z. B. v0.6.0) enthalten keine
- englischen Handbuch-Seiten; dort greift die deutsche Fassung als Fallback.
-
-## Links
-
-- Commit: [`3de59cc`](https://git.kubebase.de/admin/tool-evaluator/commit/3de59cc)
-- Tag: [`v0.8.4`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.4)
diff --git a/docs/releases/v0.8.5.en.md b/docs/releases/v0.8.5.en.md
deleted file mode 100644
index a5eb6b4..0000000
--- a/docs/releases/v0.8.5.en.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# v0.8.5 — Release Notes
-
-**Date:** 2026-08-04 · **Tag:** [`v0.8.5`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.5)
-
-## New features
-
-- **Help buttons across the app**: The main pages (Home, Browse tools, Trash,
- Redundancy dashboard, Admin tools) as well as the premium dialog and the
- password dialog now show a book icon next to the title that links directly
- to the matching manual page (following the existing buttons on the tool
- detail, create, edit, compare, watchlist and analytics pages).
-
-## Fixes & improvements
-
-- **Translated submit button when creating a tool**: The "Submit Tool" /
- "Adding Tool…" button was still hardcoded and appeared in English in the
- German UI. It is now translated, e.g. "Tool einreichen" / "Füge Tool
- hinzu…" in German.
-- **More translated UI strings**: View mode (Grid/Table/Rows), list density
- (Compact/Comfortable), minimum rating in the filter and the password hint
- "min. 6 characters" are now translated correctly.
-- **Consistent docs terminology**: The manual now consistently calls the
- watchlist "Merkliste" in all German pages and release notes; the English
- version stays "Watchlist". The `watchlist` permission name and the URLs
- are unchanged.
-- All locales are in sync (462 keys per language, 0 missing).
-
-## API changes
-
-- No changes to the API.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none.
-
-## Known limitations
-
-- None.
-
-## Links
-
-- Commit: [`70e72da`](https://git.kubebase.de/admin/tool-evaluator/commit/70e72da)
-- Tag: [`v0.8.5`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.5)
diff --git a/docs/releases/v0.8.5.md b/docs/releases/v0.8.5.md
deleted file mode 100644
index e94bcc4..0000000
--- a/docs/releases/v0.8.5.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# v0.8.5 — Release Notes
-
-**Datum:** 2026-08-04 · **Tag:** [`v0.8.5`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.5)
-
-## Neue Features
-
-- **Hilfe-Buttons in der gesamten App**: Auf den Hauptseiten (Start, Tools
- durchsuchen, Papierkorb, Redundanz-Dashboard, Admin-Tools) sowie in
- Premium-Dialog und Passwort-Dialog gibt es jetzt ein Buch-Icon neben dem
- Titel, das direkt zur passenden Anleitung im Handbuch verlinkt (analog zu
- den bestehenden Buttons auf Tool-Detail-, Anlegen-, Bearbeiten-,
- Vergleichen-, Merkliste- und Analytics-Seiten).
-
-## Fixes & Verbesserungen
-
-- **Submit-Button beim Tool-Anlegen übersetzt**: Der Button „Submit Tool" /
- „Adding Tool…" war noch hartkodiert und erschien auf Deutsch auf Englisch.
- Jetzt: „Tool einreichen" / „Füge Tool hinzu…" (bzw. die englischen
- Entsprechungen).
-- **Weitere übersetzte UI-Strings**: Ansichtsmodus (Raster/Tabelle/Zeilen),
- Listendichte (Kompakt/Komfortabel), Mindestbewertung im Filter sowie der
- Passwort-Hinweis „min. 6 Zeichen" werden jetzt korrekt übersetzt.
-- **Doku-Terminologie konsistent**: Das Handbuch heißt die Merkliste jetzt
- einheitlich „Merkliste" (statt „Watchlist") in allen deutschen Seiten und
- Release-Notes; die englische Fassung bleibt „Watchlist". Die
- Permissions-Bezeichnung `watchlist` und die URLs sind unverändert.
-- Alle Locales synchron (462 Keys pro Sprache, 0 fehlend).
-
-## API-Änderungen
-
-- Keine Änderungen an der API.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine.
-
-## Bekannte Einschränkungen
-
-- Keine.
-
-## Links
-
-- Commit: [`70e72da`](https://git.kubebase.de/admin/tool-evaluator/commit/70e72da)
-- Tag: [`v0.8.5`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.5)
diff --git a/docs/releases/v0.8.6.en.md b/docs/releases/v0.8.6.en.md
deleted file mode 100644
index 0424564..0000000
--- a/docs/releases/v0.8.6.en.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# v0.8.6 — Release Notes
-
-**Date:** 2026-08-04 · **Tag:** [`v0.8.6`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.6)
-
-## New features
-
-- **Bulk tool import in the admin area (premium)**: Admins can now create
- multiple tools at once via the new **Import** button in the "Tools" tab.
- The format is detected automatically (CSV, JSON or YAML); for CSV the
- delimiter can be chosen (auto-detect, comma, semicolon or tab). Data can be
- pasted directly or uploaded as a file. Faulty rows are skipped and listed
- with their row number while correct rows are still created. Every import
- produces audit-log entries. The feature is enabled via the `tool-import`
- feature (premium/enterprise); admins always pass the check.
-
-## Improvements
-
-- **NetBox-style help buttons**: The previously attached book icon and the
- `FieldHelp` question marks (which showed a German tooltip in the English
- layout) have been removed. Forms (create tool, edit tool, rate, password
- dialog) now show a "Hilfe"/"Help" outline button with a question-mark icon
- at the top right that opens the corresponding handbook page — fully
- localized.
-- All locales are in sync (482 keys per language, 0 missing).
-
-## API changes
-
-- **New:** `POST /admin/tools/import` (admin + `tool-import` feature).
- Request body: `format` (`auto|csv|json|yaml`, default `auto`), `delimiter`
- (`auto|comma|semicolon|tab`, default `auto`), `data` (string). Response:
- `{ imported, total, errors: [{ row, error }] }`.
-
-## Operations / upgrade
-
-- **Env vars:** unchanged.
-- **Migration:** none.
-- **Breaking changes:** none. The import endpoint is only available to
- premium/enterprise admins; free/user accounts keep standard access.
-
-## Known limitations
-
-- CSV columns whose header does not map to a supported field are ignored;
- only the defined fields (`name`, `description`, `category`, `websiteUrl`,
- `iconUrl`, `features`, `tags`) are taken over.
-
-## Links
-
-- Commit: [`8f2fd89`](https://git.kubebase.de/admin/tool-evaluator/commit/8f2fd89)
-- Tag: [`v0.8.6`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.6)
\ No newline at end of file
diff --git a/docs/releases/v0.8.6.md b/docs/releases/v0.8.6.md
deleted file mode 100644
index f4bcbfd..0000000
--- a/docs/releases/v0.8.6.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# v0.8.6 — Release Notes
-
-**Datum:** 2026-08-04 · **Tag:** [`v0.8.6`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.6)
-
-## Neue Features
-
-- **Bulk-Tool-Import im Admin (Premium)**: Admins können über den neuen Button
- **Importieren** im Tab „Tools" mehrere Tools gleichzeitig anlegen. Das Format
- wird automatisch erkannt (CSV, JSON oder YAML); für CSV ist der Trenner
- wählbar (automatisch, Komma, Semikolon oder Tabulator). Daten lassen sich
- direkt einfügen oder als Datei hochladen. Fehlerhafte Zeilen werden übersprungen
- und mit Zeilennummer aufgelistet, korrekte weiterhin angelegt. Jeder Import
- erzeugt Audit-Log-Einträge. Das Feature ist über das `tool-import`-Feature
- (Premium/Enterprise) freigeschaltet; Admins passieren den Check immer.
-
-## Verbesserungen
-
-- **Hilfe-Buttons im NetBox-Stil**: Das zuvor angebundene Buch-Icon und die
- `FieldHelp`-Fragezeichen (die im englischen Layout deutschen Tooltip zeigten)
- wurden entfernt. Formulare (Tool anlegen, Tool bearbeiten, Bewerten,
- Passwort-Dialog) haben jetzt oben rechts einen „Hilfe"/„Help"-Outline-Button mit
- Fragezeichen-Icon, der die zugehörige Handbuch-Seite öffnet — vollständig
- übersetzt.
-- Alle Locales synchron (482 Keys pro Sprache, 0 fehlend).
-
-## API-Änderungen
-
-- **Neu:** `POST /admin/tools/import` (Admin + `tool-import`-Feature).
- Request-Body: `format` (`auto|csv|json|yaml`, Default `auto`), `delimiter`
- (`auto|comma|semicolon|tab`, Default `auto`), `data` (String). Antwort:
- `{ imported, total, errors: [{ row, error }] }`.
-
-## Betrieb / Upgrade
-
-- **Env-Vars:** unverändert.
-- **Migration:** keine.
-- **Breaking Changes:** keine. Der Import-Endpunkt ist ausschließlich für
- Premium/Enterprise-Admins; Free-/User-Konten erhalten weiterhin den Standard-
- Zugriff.
-
-## Bekannte Einschränkungen
-
-- CSV-Spalten, die in der Kopfzeile nicht als unterstützte Felder erkannt werden,
- werden ignoriert; nur die definierten Felder (`name`, `description`,
- `category`, `websiteUrl`, `iconUrl`, `features`, `tags`) werden übernommen.
-
-## Links
-
-- Commit: [`8f2fd89`](https://git.kubebase.de/admin/tool-evaluator/commit/8f2fd89)
-- Tag: [`v0.8.6`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.8.6)
\ No newline at end of file
diff --git a/docs/releases/v0.9.0.de.md b/docs/releases/v0.9.0.de.md
new file mode 100644
index 0000000..2a61930
--- /dev/null
+++ b/docs/releases/v0.9.0.de.md
@@ -0,0 +1,46 @@
+# v0.9.0 — Release Notes
+
+**Datum:** 2026-08-05 · **Tag:** [`v0.9.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.0)
+
+## Neue Features
+
+- **Neuausrichtung der Versionierung:** Die Dokumentation startet mit dieser
+ Version neu bei `v0.9.0`. Ältere Release-Notizen und Versionen-Snapshots
+ (v0.6.0–v0.8.6) wurden entfernt. Das Handbuch und die Referenz (API/Admin)
+ sind jetzt wieder für jede Version verfügbar — auch für neuere Versionen.
+- **Sprachsuffixe:** Alle Dokumentationsdateien verwenden jetzt einheitlich die
+ Suffixe `.de.md` und `.en.md`. Damit lassen sich später weitere Sprachen
+ ergänzen; die App liefert automatisch die passende Sprachfassung.
+- **Import — fertige Beispieldatei:** Unter `docs/examples/import-tools.yaml`
+ liegt eine sofort importierbare YAML-Beispieldatei mit 24 gängigen
+ Enterprise-Tools (Kategorien wie Kommunikation, Monitoring, CI/CD,
+ Infrastruktur). Die Datei ist in der Administration-Dokumentation verlinkt.
+
+## Fixes & Verbesserungen
+
+- Der Versionsumschalter zeigt die Dokumentation jetzt auch für neuere
+ Versionen korrekt an (vorher fehlende Versionen-Snapshots machten Handbuch und
+ Referenz nicht verfügbar).
+- Wording bereinigt: Die Tagline und Platzhaltertexte ohne Berufsbezeichnung
+ („Bewerte dein Tool." / „Rate your Tool.", „Anonymer Benutzer" /
+ „Anonymous User"). Es werden keine Gender-Sonderformen mehr verwendet
+ (`Nutzer:innen` → `Nutzer`, `Ersteller:in` → `Ersteller`).
+
+## API-Änderungen
+
+- Keine Änderungen gegenüber v0.8.6 (siehe `lib/api-spec/openapi.yaml`).
+
+## Betrieb / Upgrade
+
+- **Migration:** keine. Bereits vorhandene Tools-, Bewertungs- und Konto-Daten
+ bleiben unverändert.
+- **Breaking Changes:** keine.
+
+## Bekannte Einschränkungen
+
+- Keine im Rahmen dieses Releases.
+
+## Links
+
+- Commit: [``](https://git.kubebase.de/admin/tool-evaluator/commit/)
+- Tag: [`v0.9.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.0)
\ No newline at end of file
diff --git a/docs/releases/v0.9.0.en.md b/docs/releases/v0.9.0.en.md
new file mode 100644
index 0000000..fb7976d
--- /dev/null
+++ b/docs/releases/v0.9.0.en.md
@@ -0,0 +1,46 @@
+# v0.9.0 — Release Notes
+
+**Date:** 2026-08-05 · **Tag:** [`v0.9.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.0)
+
+## New Features
+
+- **Versioning reset:** Documentation starts fresh at `v0.9.0` with this
+ release. Older release notes and version snapshots (v0.6.0–v0.8.6) have been
+ removed. The handbook and reference (API/admin) are now available again for
+ every version — including newer versions.
+- **Language suffixes:** All documentation files now consistently use the
+ `.de.md` and `.en.md` suffixes. This makes it easy to add more languages
+ later; the app automatically serves the matching language variant.
+- **Import — ready-to-use example file:** A ready-to-import YAML example file
+ with 24 common enterprise tools is provided at
+ `docs/examples/import-tools.yaml` (categories such as communication,
+ monitoring, CI/CD, infrastructure). The file is linked from the
+ administration documentation.
+
+## Fixes & Polish
+
+- The version switcher now displays documentation correctly for newer versions
+ as well (previously, missing version snapshots made the handbook and
+ reference unavailable).
+- Wording cleanup: tagline and placeholder texts no longer reference a specific
+ job title ("Rate your Tool.", "Anonymous User"). No gender-specific forms are
+ used anymore.
+
+## API Changes
+
+- No changes compared to v0.8.6 (see `lib/api-spec/openapi.yaml`).
+
+## Operations / Upgrade
+
+- **Migration:** none. Existing tool, rating, and account data remain
+ unchanged.
+- **Breaking Changes:** none.
+
+## Known Limitations
+
+- None within the scope of this release.
+
+## Links
+
+- Commit: [``](https://git.kubebase.de/admin/tool-evaluator/commit/)
+- Tag: [`v0.9.0`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.0)
\ No newline at end of file
diff --git a/docs/releases/v0.8.2/handbook/administration.md b/docs/releases/v0.9.0/handbook/administration.de.md
similarity index 62%
rename from docs/releases/v0.8.2/handbook/administration.md
rename to docs/releases/v0.9.0/handbook/administration.de.md
index 585e0ce..87b386d 100644
--- a/docs/releases/v0.8.2/handbook/administration.md
+++ b/docs/releases/v0.9.0/handbook/administration.de.md
@@ -32,6 +32,49 @@ Zentraler Zugriff auf den Tool-Katalog.
- **Massenaktion:** mehrere Tools auswählen und in den Papierkorb verschieben
(Bestätigungsdialog; soft gelöschte Tools sind aus allen öffentlichen Ansichten
entfernt und können wiederhergestellt oder endgültig gelöscht werden).
+- **Importieren** (Premium): über die Schaltfläche **Importieren** oben rechts
+ können mehrere Tools gleichzeitig angelegt werden. Das Format wird automatisch
+ erkannt (CSV, JSON oder YAML); für CSV lässt sich der Trenner wählen
+ (automatisch, Komma, Semikolon oder Tabulator). Die Daten lassen sich direkt
+ ins Formular einfügen oder als Datei hochladen.
+
+ Unterstützte Felder: `name` (Pflicht), `description`, `category`, `websiteUrl`,
+ `iconUrl`, `features`, `tags` (`features`/`tags` sind mit `|` getrennte Listen).
+
+ **CSV-Beispiel:**
+
+ ```csv
+ name;description;category;features;tags
+ Grafana;Observability- und Dashboard-Plattform;Monitoring;Dashboards|Alerts;devops
+ Prometheus;Zeitreihen-Datenbank;Monitoring;Metrics;devops
+ ```
+
+ **JSON-Beispiel:**
+
+ ```json
+ [
+ { "name": "Grafana", "category": "Monitoring", "features": ["Dashboards"] },
+ { "name": "Prometheus", "category": "Monitoring" }
+ ]
+ ```
+
+ **YAML-Beispiel:**
+
+ ```yaml
+ - name: Grafana
+ category: Monitoring
+ features:
+ - Dashboards
+ - name: Prometheus
+ category: Monitoring
+ ```
+
+ Eine umfangreichere, fertig importierbare Beispieldatei liegt unter
+ `docs/examples/import-tools.yaml` (24 gängige Enterprise-Tools).
+
+ Beim Import werden einzelne fehlerhafte Zeilen übersprungen und mit Zeilennummer
+ aufgelistet; korrekte Zeilen werden trotzdem angelegt. Jeder Import erzeugt
+ Audit-Log-Einträge.
## Tab „Audit-Log"
diff --git a/docs/releases/v0.8.2/handbook/administration.en.md b/docs/releases/v0.9.0/handbook/administration.en.md
similarity index 61%
rename from docs/releases/v0.8.2/handbook/administration.en.md
rename to docs/releases/v0.9.0/handbook/administration.en.md
index 9fe7806..e5b1e38 100644
--- a/docs/releases/v0.8.2/handbook/administration.en.md
+++ b/docs/releases/v0.9.0/handbook/administration.en.md
@@ -32,6 +32,49 @@ Central access to the tool catalog.
- **Bulk action:** select multiple tools and move them to the trash
(confirmation dialog; soft-deleted tools are removed from all public views
and can be restored or permanently deleted).
+- **Import** (premium): via the **Import** button at the top right, multiple
+ tools can be created at once. The format is detected automatically (CSV,
+ JSON or YAML); for CSV the delimiter can be chosen (auto-detect, comma,
+ semicolon or tab). Data can be pasted directly into the form or uploaded
+ as a file.
+
+ Supported fields: `name` (required), `description`, `category`, `websiteUrl`,
+ `iconUrl`, `features`, `tags` (`features`/`tags` are `|`-separated lists).
+
+ **CSV example:**
+
+ ```csv
+ name;description;category;features;tags
+ Grafana;Observability and dashboard platform;Monitoring;Dashboards|Alerts;devops
+ Prometheus;Time-series database;Monitoring;Metrics;devops
+ ```
+
+ **JSON example:**
+
+ ```json
+ [
+ { "name": "Grafana", "category": "Monitoring", "features": ["Dashboards"] },
+ { "name": "Prometheus", "category": "Monitoring" }
+ ]
+ ```
+
+ **YAML example:**
+
+ ```yaml
+ - name: Grafana
+ category: Monitoring
+ features:
+ - Dashboards
+ - name: Prometheus
+ category: Monitoring
+ ```
+
+ A larger, ready-to-import example file is located at
+ `docs/examples/import-tools.yaml` (24 common enterprise tools).
+
+ During import, individual faulty rows are skipped and listed with their row
+ number; correct rows are still created. Every import produces audit-log
+ entries.
## "Audit log" tab
diff --git a/docs/releases/v0.8.1/handbook/analytics.md b/docs/releases/v0.9.0/handbook/analytics.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/analytics.md
rename to docs/releases/v0.9.0/handbook/analytics.de.md
diff --git a/docs/releases/v0.8.1/handbook/analytics.en.md b/docs/releases/v0.9.0/handbook/analytics.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/analytics.en.md
rename to docs/releases/v0.9.0/handbook/analytics.en.md
diff --git a/docs/releases/v0.8.1/handbook/bewerten.md b/docs/releases/v0.9.0/handbook/bewerten.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/bewerten.md
rename to docs/releases/v0.9.0/handbook/bewerten.de.md
diff --git a/docs/releases/v0.8.1/handbook/bewerten.en.md b/docs/releases/v0.9.0/handbook/bewerten.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/bewerten.en.md
rename to docs/releases/v0.9.0/handbook/bewerten.en.md
diff --git a/docs/releases/v0.8.1/handbook/datenmodell.md b/docs/releases/v0.9.0/handbook/datenmodell.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/datenmodell.md
rename to docs/releases/v0.9.0/handbook/datenmodell.de.md
diff --git a/docs/releases/v0.8.1/handbook/datenmodell.en.md b/docs/releases/v0.9.0/handbook/datenmodell.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/datenmodell.en.md
rename to docs/releases/v0.9.0/handbook/datenmodell.en.md
diff --git a/docs/releases/v0.8.2/handbook/getting-started.md b/docs/releases/v0.9.0/handbook/getting-started.de.md
similarity index 94%
rename from docs/releases/v0.8.2/handbook/getting-started.md
rename to docs/releases/v0.9.0/handbook/getting-started.de.md
index 0fd7820..b5d6906 100644
--- a/docs/releases/v0.8.2/handbook/getting-started.md
+++ b/docs/releases/v0.9.0/handbook/getting-started.de.md
@@ -6,7 +6,7 @@ Besuch bis zum Anlegen und Bewerten eines Tools.
## 1. Anmelden
-Die meisten Aktionen (Tool anlegen, bewerten, Watchlist, Vergleichen) erfordern
+Die meisten Aktionen (Tool anlegen, bewerten, Merkliste, Vergleichen) erfordern
ein Konto. Klicke unten links auf **Anmelden**. Je nach Konfiguration der
Instanz hast du zwei Möglichkeiten:
@@ -47,7 +47,7 @@ Siehe [Bewerten](/docs/handbook/bewerten).
## 5. Weiterführend
- [Tools vergleichen](/docs/handbook/vergleichen)
-- [Watchlist](/docs/handbook/watchlist)
+- [Merkliste](/docs/handbook/watchlist)
- [Analytics](/docs/handbook/analytics)
- [Pläne & Berechtigungen](/docs/handbook/plaene)
- [Administration](/docs/handbook/administration)
diff --git a/docs/releases/v0.8.1/handbook/getting-started.en.md b/docs/releases/v0.9.0/handbook/getting-started.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/getting-started.en.md
rename to docs/releases/v0.9.0/handbook/getting-started.en.md
diff --git a/docs/releases/v0.8.1/handbook/index.md b/docs/releases/v0.9.0/handbook/index.de.md
similarity index 90%
rename from docs/releases/v0.8.1/handbook/index.md
rename to docs/releases/v0.9.0/handbook/index.de.md
index f527a6e..fb4d3d5 100644
--- a/docs/releases/v0.8.1/handbook/index.md
+++ b/docs/releases/v0.9.0/handbook/index.de.md
@@ -2,7 +2,7 @@
# Willkommen bei toolr
toolr ist eine Plattform zum **Entdecken, Bewerten und Vergleichen von
-Entwicklungstools**. Nutzer:innen pflegen einen gemeinsamen Katalog von Tools,
+Entwicklungstools**. Nutzer pflegen einen gemeinsamen Katalog von Tools,
vergeben Bewertungen (Nützlichkeit & Bedienbarkeit) und nutzen Statistiken, um
die richtige Wahl zu treffen.
@@ -12,13 +12,14 @@ die richtige Wahl zu treffen.
| --- | --- | --- |
| **Tools durchsuchen** | Katalog filtern, sortieren und durchsuchen | Alle |
| **Tool anlegen** | Neues Tool mit Beschreibung, Kategorie, Features & Tags eintragen | Angemeldet |
-| **Tool bearbeiten/löschen** | Eigene Tools pflegen (Ersteller:in oder Admin) | Angemeldet |
+| **Tool bearbeiten/löschen** | Eigene Tools pflegen (Ersteller oder Admin) | Angemeldet |
| **Bewerten** | Nützlichkeit & Bedienbarkeit (1–5) plus Kommentar vergeben | Angemeldet |
-| **Watchlist** | Tools als Favoriten speichern | Premium |
+| **Merkliste** | Tools als Favoriten speichern | Premium |
| **Vergleichen** | Tools nebeneinander gegenüberstellen | Premium |
| **Kosten erfassen** | Lizenz- und Kostenmodelle je Tool eintragen | Premium |
| **Analytics** | Statistiken, Top-Tools, Verteilungen | Alle |
| **Papierkorb** | Soft-gelöschte Tools wiederherstellen oder endgültig löschen | Premium |
+| **Import** | Mehrere Tools per CSV, JSON oder YAML anlegen | Admin (Premium) |
| **Admin** | Nutzerverwaltung, Audit-Log, Systeminformationen | Admin |
| **Redundanz** | Automatische Doppelungs-Erkennung | Admin |
diff --git a/docs/releases/v0.8.2/handbook/index.en.md b/docs/releases/v0.9.0/handbook/index.en.md
similarity index 96%
rename from docs/releases/v0.8.2/handbook/index.en.md
rename to docs/releases/v0.9.0/handbook/index.en.md
index 490c2c5..5231030 100644
--- a/docs/releases/v0.8.2/handbook/index.en.md
+++ b/docs/releases/v0.9.0/handbook/index.en.md
@@ -18,6 +18,7 @@ tools**. Users maintain a shared catalog of tools, submit ratings
| **Record costs** | Enter license and cost models per tool | Premium |
| **Analytics** | Statistics, top tools, distributions | Everyone |
| **Trash** | Restore soft-deleted tools or delete them permanently | Premium |
+| **Import** | Create multiple tools via CSV, JSON or YAML | Admin (premium) |
| **Admin** | User management, audit log, system information | Admin |
| **Redundancy detection** | Automatic duplicate detection | Admin |
diff --git a/docs/releases/v0.8.1/handbook/index.json b/docs/releases/v0.9.0/handbook/index.json
similarity index 81%
rename from docs/releases/v0.8.1/handbook/index.json
rename to docs/releases/v0.9.0/handbook/index.json
index 4dc0aa7..1ab56d9 100644
--- a/docs/releases/v0.8.1/handbook/index.json
+++ b/docs/releases/v0.9.0/handbook/index.json
@@ -1,7 +1,7 @@
[
{
"slug": "index",
- "file": "index.md",
+ "file": "index.de.md",
"title": "Überblick",
"order": 1,
"fileEn": "index.en.md",
@@ -9,7 +9,7 @@
},
{
"slug": "getting-started",
- "file": "getting-started.md",
+ "file": "getting-started.de.md",
"title": "Erste Schritte",
"order": 2,
"fileEn": "getting-started.en.md",
@@ -17,7 +17,7 @@
},
{
"slug": "konto",
- "file": "konto.md",
+ "file": "konto.de.md",
"title": "Anmelden & Konto",
"order": 3,
"fileEn": "konto.en.md",
@@ -25,7 +25,7 @@
},
{
"slug": "tools-finden",
- "file": "tools-finden.md",
+ "file": "tools-finden.de.md",
"title": "Tools finden & durchsuchen",
"order": 4,
"fileEn": "tools-finden.en.md",
@@ -33,7 +33,7 @@
},
{
"slug": "tool-anlegen",
- "file": "tool-anlegen.md",
+ "file": "tool-anlegen.de.md",
"title": "Tool anlegen",
"order": 5,
"fileEn": "tool-anlegen.en.md",
@@ -41,7 +41,7 @@
},
{
"slug": "tool-bearbeiten",
- "file": "tool-bearbeiten.md",
+ "file": "tool-bearbeiten.de.md",
"title": "Tool bearbeiten & löschen",
"order": 6,
"fileEn": "tool-bearbeiten.en.md",
@@ -49,7 +49,7 @@
},
{
"slug": "bewerten",
- "file": "bewerten.md",
+ "file": "bewerten.de.md",
"title": "Bewerten",
"order": 7,
"fileEn": "bewerten.en.md",
@@ -57,15 +57,15 @@
},
{
"slug": "watchlist",
- "file": "watchlist.md",
- "title": "Watchlist",
+ "file": "watchlist.de.md",
+ "title": "Merkliste",
"order": 8,
"fileEn": "watchlist.en.md",
"titleEn": "Watchlist"
},
{
"slug": "vergleichen",
- "file": "vergleichen.md",
+ "file": "vergleichen.de.md",
"title": "Vergleichen",
"order": 9,
"fileEn": "vergleichen.en.md",
@@ -73,7 +73,7 @@
},
{
"slug": "analytics",
- "file": "analytics.md",
+ "file": "analytics.de.md",
"title": "Analytics",
"order": 10,
"fileEn": "analytics.en.md",
@@ -81,7 +81,7 @@
},
{
"slug": "plaene",
- "file": "plaene.md",
+ "file": "plaene.de.md",
"title": "Pläne & Berechtigungen",
"order": 11,
"fileEn": "plaene.en.md",
@@ -89,7 +89,7 @@
},
{
"slug": "kosten",
- "file": "kosten.md",
+ "file": "kosten.de.md",
"title": "Kosten erfassen",
"order": 12,
"fileEn": "kosten.en.md",
@@ -97,7 +97,7 @@
},
{
"slug": "administration",
- "file": "administration.md",
+ "file": "administration.de.md",
"title": "Administration",
"order": 13,
"fileEn": "administration.en.md",
@@ -105,7 +105,7 @@
},
{
"slug": "redundanz",
- "file": "redundanz.md",
+ "file": "redundanz.de.md",
"title": "Redundanz-Dashboard",
"order": 14,
"fileEn": "redundanz.en.md",
@@ -113,7 +113,7 @@
},
{
"slug": "papierkorb",
- "file": "papierkorb.md",
+ "file": "papierkorb.de.md",
"title": "Papierkorb",
"order": 15,
"fileEn": "papierkorb.en.md",
@@ -121,7 +121,7 @@
},
{
"slug": "tastatur",
- "file": "tastatur.md",
+ "file": "tastatur.de.md",
"title": "Tastenkürzel & Kommandopalette",
"order": 16,
"fileEn": "tastatur.en.md",
@@ -129,7 +129,7 @@
},
{
"slug": "datenmodell",
- "file": "datenmodell.md",
+ "file": "datenmodell.de.md",
"title": "Datenmodell",
"order": 17,
"fileEn": "datenmodell.en.md",
diff --git a/docs/releases/v0.8.2/handbook/konto.md b/docs/releases/v0.9.0/handbook/konto.de.md
similarity index 94%
rename from docs/releases/v0.8.2/handbook/konto.md
rename to docs/releases/v0.9.0/handbook/konto.de.md
index 40aae3d..1fc81aa 100644
--- a/docs/releases/v0.8.2/handbook/konto.md
+++ b/docs/releases/v0.9.0/handbook/konto.de.md
@@ -22,7 +22,7 @@ Der aktive Modus steht im Endpunkt
Dein Profil (Avatar, Name, E-Mail, Tarif) siehst du unten links im
Benutzermenü. Dort stehen dir folgende Aktionen zur Verfügung:
-- **Watchlist** — deine gespeicherten Tools (nur mit dem entsprechenden Tarif).
+- **Merkliste** — deine gespeicherten Tools (nur mit dem entsprechenden Tarif).
- **Papierkorb** — wiederherstellbare, gelöschte Tools (Premium/Enterprise).
- **Passwort ändern** — für lokale Konten direkt in toolr; für OIDC-Konten wird
die Passwortverwaltung im Identitätsanbieter angeboten.
@@ -47,7 +47,7 @@ API-Referenz: [`POST /auth/me/password`](/docs/reference/endpoints/auth#changeMy
- die **Listenansicht** und **Dichte** im Bereich Tools durchsuchen anpassen
(siehe [Tools finden & durchsuchen](/docs/handbook/tools-finden)).
-Deine Präferenzen (inkl. Watchlist) werden im Endpunkt
+Deine Präferenzen (inkl. Merkliste) werden im Endpunkt
[`GET /auth/me/preferences`](/docs/reference/endpoints/auth#getMePreferences)
gespeichert und über [`PUT /auth/me/preferences`](/docs/reference/endpoints/auth#updateMePreferences)
aktualisiert.
diff --git a/docs/releases/v0.8.1/handbook/konto.en.md b/docs/releases/v0.9.0/handbook/konto.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/konto.en.md
rename to docs/releases/v0.9.0/handbook/konto.en.md
diff --git a/docs/releases/v0.8.1/handbook/kosten.md b/docs/releases/v0.9.0/handbook/kosten.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/kosten.md
rename to docs/releases/v0.9.0/handbook/kosten.de.md
diff --git a/docs/releases/v0.8.1/handbook/kosten.en.md b/docs/releases/v0.9.0/handbook/kosten.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/kosten.en.md
rename to docs/releases/v0.9.0/handbook/kosten.en.md
diff --git a/docs/releases/v0.8.1/handbook/papierkorb.md b/docs/releases/v0.9.0/handbook/papierkorb.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/papierkorb.md
rename to docs/releases/v0.9.0/handbook/papierkorb.de.md
diff --git a/docs/releases/v0.8.1/handbook/papierkorb.en.md b/docs/releases/v0.9.0/handbook/papierkorb.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/papierkorb.en.md
rename to docs/releases/v0.9.0/handbook/papierkorb.en.md
diff --git a/docs/releases/v0.8.2/handbook/plaene.md b/docs/releases/v0.9.0/handbook/plaene.de.md
similarity index 84%
rename from docs/releases/v0.8.2/handbook/plaene.md
rename to docs/releases/v0.9.0/handbook/plaene.de.md
index d4546b7..2c79230 100644
--- a/docs/releases/v0.8.2/handbook/plaene.md
+++ b/docs/releases/v0.9.0/handbook/plaene.de.md
@@ -9,7 +9,7 @@ Feature-Beschränkungen.
| Tarif | Beschreibung |
| --- | --- |
| **Free** | Grundfunktionen: suchen, filtern, ansehen, Analytics |
-| **Premium** | Zusätzlich Watchlist, Vergleichen, Papierkorb, Kosten |
+| **Premium** | Zusätzlich Merkliste, Vergleichen, Papierkorb, Kosten |
| **Enterprise** | Alle Premium-Features + erweiterter Support |
### Feature-Berechtigungen
@@ -19,9 +19,10 @@ Premium/Enterprise schalten folgende Features frei:
| Feature | Funktion | Mehr erfahren |
| --- | --- | --- |
| `compare` | Tools vergleichen | [Vergleichen](/docs/handbook/vergleichen) |
-| `watchlist` | Favoritenliste | [Watchlist](/docs/handbook/watchlist) |
+| `watchlist` | Favoritenliste | [Merkliste](/docs/handbook/watchlist) |
| `trash` | Papierkorb (soft gelöschte Tools) | [Papierkorb](/docs/handbook/papierkorb) |
| `costs` | Kosten-/Lizenzmodelle erfassen | [Kosten erfassen](/docs/handbook/kosten) |
+| `tool-import` | Tools per CSV/JSON/YAML importieren (Admin) | [Administration](/docs/handbook/administration) |
Fehlt dir ein Feature, zeigt die App einen **Upgrade-Hinweis** mit Link zur
Tarifverwaltung.
diff --git a/docs/releases/v0.8.2/handbook/plaene.en.md b/docs/releases/v0.9.0/handbook/plaene.en.md
similarity index 92%
rename from docs/releases/v0.8.2/handbook/plaene.en.md
rename to docs/releases/v0.9.0/handbook/plaene.en.md
index f73d6dc..29cce75 100644
--- a/docs/releases/v0.8.2/handbook/plaene.en.md
+++ b/docs/releases/v0.9.0/handbook/plaene.en.md
@@ -22,6 +22,7 @@ Premium/Enterprise unlock the following features:
| `watchlist` | Favorites list | [Watchlist](/docs/handbook/watchlist) |
| `trash` | Trash (soft-deleted tools) | [Trash](/docs/handbook/papierkorb) |
| `costs` | Record cost/license models | [Recording costs](/docs/handbook/kosten) |
+| `tool-import` | Import tools via CSV/JSON/YAML (admin) | [Administration](/docs/handbook/administration) |
If you are missing a feature, the app shows an **upgrade notice** with a link
to the plan management.
diff --git a/docs/releases/v0.8.1/handbook/redundanz.md b/docs/releases/v0.9.0/handbook/redundanz.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/redundanz.md
rename to docs/releases/v0.9.0/handbook/redundanz.de.md
diff --git a/docs/releases/v0.8.1/handbook/redundanz.en.md b/docs/releases/v0.9.0/handbook/redundanz.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/redundanz.en.md
rename to docs/releases/v0.9.0/handbook/redundanz.en.md
diff --git a/docs/releases/v0.8.2/handbook/tastatur.md b/docs/releases/v0.9.0/handbook/tastatur.de.md
similarity index 93%
rename from docs/releases/v0.8.2/handbook/tastatur.md
rename to docs/releases/v0.9.0/handbook/tastatur.de.md
index 7eb6f17..96489bf 100644
--- a/docs/releases/v0.8.2/handbook/tastatur.md
+++ b/docs/releases/v0.9.0/handbook/tastatur.de.md
@@ -15,7 +15,7 @@ Ohne Eingabe zeigt die Palette:
- **Zuletzt angesehen** — die letzten 5 Tools, die du besucht hast.
- **Navigation** — Tools durchsuchen, Tool hinzufügen, Analytics sowie
- (abhängig von Berechtigungen) Watchlist, Papierkorb und Admin.
+ (abhängig von Berechtigungen) Merkliste, Papierkorb und Admin.
### Suche
diff --git a/docs/releases/v0.8.1/handbook/tastatur.en.md b/docs/releases/v0.9.0/handbook/tastatur.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tastatur.en.md
rename to docs/releases/v0.9.0/handbook/tastatur.en.md
diff --git a/docs/releases/v0.8.1/handbook/tool-anlegen.md b/docs/releases/v0.9.0/handbook/tool-anlegen.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tool-anlegen.md
rename to docs/releases/v0.9.0/handbook/tool-anlegen.de.md
diff --git a/docs/releases/v0.8.1/handbook/tool-anlegen.en.md b/docs/releases/v0.9.0/handbook/tool-anlegen.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tool-anlegen.en.md
rename to docs/releases/v0.9.0/handbook/tool-anlegen.en.md
diff --git a/docs/releases/v0.8.1/handbook/tool-bearbeiten.md b/docs/releases/v0.9.0/handbook/tool-bearbeiten.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tool-bearbeiten.md
rename to docs/releases/v0.9.0/handbook/tool-bearbeiten.de.md
diff --git a/docs/releases/v0.8.1/handbook/tool-bearbeiten.en.md b/docs/releases/v0.9.0/handbook/tool-bearbeiten.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tool-bearbeiten.en.md
rename to docs/releases/v0.9.0/handbook/tool-bearbeiten.en.md
diff --git a/docs/releases/v0.8.2/handbook/tools-finden.md b/docs/releases/v0.9.0/handbook/tools-finden.de.md
similarity index 94%
rename from docs/releases/v0.8.2/handbook/tools-finden.md
rename to docs/releases/v0.9.0/handbook/tools-finden.de.md
index c976515..a0f8add 100644
--- a/docs/releases/v0.8.2/handbook/tools-finden.md
+++ b/docs/releases/v0.9.0/handbook/tools-finden.de.md
@@ -43,7 +43,7 @@ Mit **Filter zurücksetzen** bzw. **Alle entfernen** räumst du sie wieder auf.
- **Ansicht wechseln:** Raster / Tabelle / Zeilen.
- **Dichte:** gemütlich / kompakt (Schieberegler).
-Deine Auswahl wird gespeichert — lokal im Browser und für angemeldete Nutzer:innen
+Deine Auswahl wird gespeichert — lokal im Browser und für angemeldete Nutzer
zusätzlich serverseitig in den Präferenzen. Ansicht, Dichte, Suche, Filter und
Sortierung werden dabei in die URL übernommen, sodass du Ergebnisse teilen
kannst.
@@ -54,12 +54,12 @@ In der Tabellenansicht sind die Spalten **Tool**, **Bewertung** und **Anzahl
Bewertungen** sortierbar. Beim Überfahren einer Zeile erscheint eine Vorschau
mit Bewertungsdetails, Tags und Mini-Balken.
-## Auswählen für Vergleich & Watchlist
+## Auswählen für Vergleich & Merkliste
- Auf jeder Karte/Zeile findest du ein **Vergleichs-Icon**, mit dem du Tools zur
[Vergleichsleiste](/docs/handbook/vergleichen) hinzufügst.
- Das **Lesezeichen-Icon** speichert Tools in deiner
- [Watchlist](/docs/handbook/watchlist) (nur mit dem entsprechenden Tarif).
+ [Merkliste](/docs/handbook/watchlist) (nur mit dem entsprechenden Tarif).
## API
diff --git a/docs/releases/v0.8.1/handbook/tools-finden.en.md b/docs/releases/v0.9.0/handbook/tools-finden.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/tools-finden.en.md
rename to docs/releases/v0.9.0/handbook/tools-finden.en.md
diff --git a/docs/releases/v0.8.1/handbook/vergleichen.md b/docs/releases/v0.9.0/handbook/vergleichen.de.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/vergleichen.md
rename to docs/releases/v0.9.0/handbook/vergleichen.de.md
diff --git a/docs/releases/v0.8.1/handbook/vergleichen.en.md b/docs/releases/v0.9.0/handbook/vergleichen.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/vergleichen.en.md
rename to docs/releases/v0.9.0/handbook/vergleichen.en.md
diff --git a/docs/releases/v0.8.1/handbook/watchlist.md b/docs/releases/v0.9.0/handbook/watchlist.de.md
similarity index 64%
rename from docs/releases/v0.8.1/handbook/watchlist.md
rename to docs/releases/v0.9.0/handbook/watchlist.de.md
index 783da0c..eb25bf1 100644
--- a/docs/releases/v0.8.1/handbook/watchlist.md
+++ b/docs/releases/v0.9.0/handbook/watchlist.de.md
@@ -1,10 +1,10 @@
-# Watchlist
+# Merkliste
-Die **Watchlist** ist eine persönliche Favoritenliste. Tools darin kannst du
+Die **Merkliste** ist eine persönliche Favoritenliste. Tools darin kannst du
jederzeit per Klick wieder aufrufen und vergleichen.
-> Die Watchlist ist ein **Premium-Feature** (Premium/Enterprise) und steht
+> Die Merkliste ist ein **Premium-Feature** (Premium/Enterprise) und steht
> Admins immer zur Verfügung.
## Voraussetzung
@@ -17,18 +17,18 @@ beim Lesezeichen ein Hinweis auf den Tarifwechsel
- Auf jeder Karte/Zeile im Bereich **Tools durchsuchen** findest du das
**Lesezeichen-Icon**.
-- Ein Klick speichert das Tool in deiner Watchlist — das Icon wird gefüllt.
+- Ein Klick speichert das Tool in deiner Merkliste — das Icon wird gefüllt.
- Ein erneuter Klick entfernt es wieder.
-## Watchlist ansehen
+## Merkliste ansehen
-Öffne die Watchlist über das Benutzermenü oder die Seitenleiste. Sie zeigt alle
+Öffne die Merkliste über das Benutzermenü oder die Seitenleiste. Sie zeigt alle
gespeicherten Tools als Karten. Das gefüllte Lesezeichen auf einer Karte
entfernt das Tool aus der Liste.
-## Wo wird die Watchlist gespeichert?
+## Wo wird die Merkliste gespeichert?
-Die Watchlist ist eine Liste von Tool-IDs in deinen **Benutzerpräferenzen**.
+Die Merkliste ist eine Liste von Tool-IDs in deinen **Benutzerpräferenzen**.
Damit ist sie geräteübergreifend mit deinem Konto verbunden.
-API-Referenz: [`GET /auth/me/watchlist`](/docs/reference/endpoints/auth#getMeWatchlist).
+API-Referenz: [`GET /auth/me/watchlist`](/docs/reference/endpoints/auth#getMeMerkliste).
diff --git a/docs/releases/v0.8.1/handbook/watchlist.en.md b/docs/releases/v0.9.0/handbook/watchlist.en.md
similarity index 100%
rename from docs/releases/v0.8.1/handbook/watchlist.en.md
rename to docs/releases/v0.9.0/handbook/watchlist.en.md
diff --git a/docs/releases/v0.7.0/reference.json b/docs/releases/v0.9.0/reference.json
similarity index 97%
rename from docs/releases/v0.7.0/reference.json
rename to docs/releases/v0.9.0/reference.json
index a3adfd9..caa9761 100644
--- a/docs/releases/v0.7.0/reference.json
+++ b/docs/releases/v0.9.0/reference.json
@@ -2206,6 +2206,78 @@
}
]
},
+ {
+ "name": "ToolImportBody",
+ "description": "",
+ "fields": [
+ {
+ "name": "format",
+ "type": {
+ "kind": "type",
+ "value": "string"
+ },
+ "required": false,
+ "description": "",
+ "constraints": "auto, csv, json, yaml"
+ },
+ {
+ "name": "delimiter",
+ "type": {
+ "kind": "type",
+ "value": "string"
+ },
+ "required": false,
+ "description": "",
+ "constraints": "auto, comma, semicolon, tab"
+ },
+ {
+ "name": "data",
+ "type": {
+ "kind": "type",
+ "value": "string"
+ },
+ "required": true,
+ "description": "",
+ "constraints": ""
+ }
+ ]
+ },
+ {
+ "name": "ToolImportResponse",
+ "description": "",
+ "fields": [
+ {
+ "name": "imported",
+ "type": {
+ "kind": "type",
+ "value": "integer"
+ },
+ "required": true,
+ "description": "",
+ "constraints": ""
+ },
+ {
+ "name": "total",
+ "type": {
+ "kind": "type",
+ "value": "integer"
+ },
+ "required": true,
+ "description": "",
+ "constraints": ""
+ },
+ {
+ "name": "errors",
+ "type": {
+ "kind": "array",
+ "value": "object"
+ },
+ "required": true,
+ "description": "",
+ "constraints": ""
+ }
+ ]
+ },
{
"name": "ToolUpdate",
"description": "",
diff --git a/scripts/src/generate-docs.mjs b/scripts/src/generate-docs.mjs
index 4bc6270..26f7132 100644
--- a/scripts/src/generate-docs.mjs
+++ b/scripts/src/generate-docs.mjs
@@ -25,20 +25,20 @@ const handbookDir = resolve(root, "docs/handbook");
const releasesDir = resolve(root, "docs/releases");
const targetDir = resolve(root, "artifacts/toolrate/public/docs");
-const isReleaseFile = (name) => /^v\d+\.\d+\.\d+\.md$/.test(name);
+const isReleaseFile = (name) => /^v\d+\.\d+\.\d+\.de\.md$/.test(name);
const isEnReleaseFile = (name) => /^v\d+\.\d+\.\d+\.en\.md$/.test(name);
-const isHandbookFile = (name) => /\.md$/.test(name) && !name.endsWith(".en.md");
+const isHandbookFile = (name) => /\.de\.md$/.test(name);
const isEnHandbookFile = (name) => /\.en\.md$/.test(name);
-const enName = (file) => (file.endsWith(".md") ? `${file.slice(0, -3)}.en.md` : null);
-const deName = (file) => (file.endsWith(".en.md") ? `${file.slice(0, -6)}.md` : null);
+const enName = (file) => (file.endsWith(".de.md") ? `${file.slice(0, -6)}.en.md` : null);
+const deName = (file) => (file.endsWith(".en.md") ? `${file.slice(0, -6)}.de.md` : null);
// ---------------------------------------------------------------------------
// Version helpers
// ---------------------------------------------------------------------------
function parseVersion(name) {
- return name.replace(/\.md$/, "");
+ return name.replace(/\.(de|en)\.md$/, "");
}
function cmp(a, b) {
@@ -198,7 +198,7 @@ function parseHandbook(content) {
}
function slugify(name) {
- return name.replace(/\.md$/, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-");
+ return name.replace(/\.(de|en)?\.md$/, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-");
}
async function readFileOptional(path) {
@@ -328,7 +328,7 @@ async function buildSearchIndex(reference, handbookPages, releaseVersions) {
}
for (const version of releaseVersions) {
- const file = join(releasesDir, `${version}.md`);
+ const file = join(releasesDir, `${version}.de.md`);
const content = await readFile(file, "utf8");
const base = {
title: version,
@@ -418,9 +418,9 @@ async function main() {
const version = parseVersion(name);
const content = await readFile(join(releasesDir, name), "utf8");
await copyFile(join(releasesDir, name), join(targetDir, "releases", name));
- const enName = `${version}.en.md`;
- const enContent = await readFileOptional(join(releasesDir, enName));
- if (enContent) await copyFile(join(releasesDir, enName), join(targetDir, "releases", enName));
+ const releaseEnName = enName(name);
+ const enContent = await readFileOptional(join(releasesDir, releaseEnName));
+ if (enContent) await copyFile(join(releasesDir, releaseEnName), join(targetDir, "releases", releaseEnName));
const snapDir = join(releasesDir, version);
const hasReference = await stat(join(snapDir, "reference.json"))
.then(() => true)
@@ -459,7 +459,7 @@ async function main() {
versions.push({
version,
file: `releases/${name}`,
- fileEn: enContent ? `releases/${enName}` : null,
+ fileEn: enContent ? `releases/${releaseEnName}` : null,
title: extractTitle(content) ?? version,
titleEn: enContent ? extractTitle(enContent) ?? version : null,
date: extractDate(content) ?? null,