From 3e30246342bebf98cada56357026ed9152e3d3ff Mon Sep 17 00:00:00 2001 From: opencode Date: Thu, 6 Aug 2026 23:57:27 +0200 Subject: [PATCH] docs: add v0.9.7 release notes --- docs/releases/v0.9.7.de.md | 41 + docs/releases/v0.9.7.en.md | 39 + .../v0.9.7/handbook/administration.de.md | 104 + .../v0.9.7/handbook/administration.en.md | 104 + docs/releases/v0.9.7/handbook/analytics.de.md | 29 + docs/releases/v0.9.7/handbook/analytics.en.md | 29 + docs/releases/v0.9.7/handbook/bewerten.de.md | 39 + docs/releases/v0.9.7/handbook/bewerten.en.md | 39 + .../v0.9.7/handbook/datenmodell.de.md | 70 + .../v0.9.7/handbook/datenmodell.en.md | 70 + .../v0.9.7/handbook/getting-started.de.md | 53 + .../v0.9.7/handbook/getting-started.en.md | 53 + docs/releases/v0.9.7/handbook/index.de.md | 53 + docs/releases/v0.9.7/handbook/index.en.md | 52 + docs/releases/v0.9.7/handbook/index.json | 138 + docs/releases/v0.9.7/handbook/konto.de.md | 53 + docs/releases/v0.9.7/handbook/konto.en.md | 52 + docs/releases/v0.9.7/handbook/kosten.de.md | 35 + docs/releases/v0.9.7/handbook/kosten.en.md | 35 + .../releases/v0.9.7/handbook/papierkorb.de.md | 41 + .../releases/v0.9.7/handbook/papierkorb.en.md | 40 + docs/releases/v0.9.7/handbook/plaene.de.md | 42 + docs/releases/v0.9.7/handbook/plaene.en.md | 42 + docs/releases/v0.9.7/handbook/redundanz.de.md | 38 + docs/releases/v0.9.7/handbook/redundanz.en.md | 38 + docs/releases/v0.9.7/handbook/tastatur.de.md | 36 + docs/releases/v0.9.7/handbook/tastatur.en.md | 36 + .../v0.9.7/handbook/tool-anlegen.de.md | 46 + .../v0.9.7/handbook/tool-anlegen.en.md | 46 + .../v0.9.7/handbook/tool-bearbeiten.de.md | 33 + .../v0.9.7/handbook/tool-bearbeiten.en.md | 32 + .../v0.9.7/handbook/tools-finden.de.md | 67 + .../v0.9.7/handbook/tools-finden.en.md | 66 + .../v0.9.7/handbook/vergleichen.de.md | 42 + .../v0.9.7/handbook/vergleichen.en.md | 42 + docs/releases/v0.9.7/handbook/watchlist.de.md | 34 + docs/releases/v0.9.7/handbook/watchlist.en.md | 33 + docs/releases/v0.9.7/reference.json | 2854 +++++++++++++++++ 38 files changed, 4696 insertions(+) create mode 100644 docs/releases/v0.9.7.de.md create mode 100644 docs/releases/v0.9.7.en.md create mode 100644 docs/releases/v0.9.7/handbook/administration.de.md create mode 100644 docs/releases/v0.9.7/handbook/administration.en.md create mode 100644 docs/releases/v0.9.7/handbook/analytics.de.md create mode 100644 docs/releases/v0.9.7/handbook/analytics.en.md create mode 100644 docs/releases/v0.9.7/handbook/bewerten.de.md create mode 100644 docs/releases/v0.9.7/handbook/bewerten.en.md create mode 100644 docs/releases/v0.9.7/handbook/datenmodell.de.md create mode 100644 docs/releases/v0.9.7/handbook/datenmodell.en.md create mode 100644 docs/releases/v0.9.7/handbook/getting-started.de.md create mode 100644 docs/releases/v0.9.7/handbook/getting-started.en.md create mode 100644 docs/releases/v0.9.7/handbook/index.de.md create mode 100644 docs/releases/v0.9.7/handbook/index.en.md create mode 100644 docs/releases/v0.9.7/handbook/index.json create mode 100644 docs/releases/v0.9.7/handbook/konto.de.md create mode 100644 docs/releases/v0.9.7/handbook/konto.en.md create mode 100644 docs/releases/v0.9.7/handbook/kosten.de.md create mode 100644 docs/releases/v0.9.7/handbook/kosten.en.md create mode 100644 docs/releases/v0.9.7/handbook/papierkorb.de.md create mode 100644 docs/releases/v0.9.7/handbook/papierkorb.en.md create mode 100644 docs/releases/v0.9.7/handbook/plaene.de.md create mode 100644 docs/releases/v0.9.7/handbook/plaene.en.md create mode 100644 docs/releases/v0.9.7/handbook/redundanz.de.md create mode 100644 docs/releases/v0.9.7/handbook/redundanz.en.md create mode 100644 docs/releases/v0.9.7/handbook/tastatur.de.md create mode 100644 docs/releases/v0.9.7/handbook/tastatur.en.md create mode 100644 docs/releases/v0.9.7/handbook/tool-anlegen.de.md create mode 100644 docs/releases/v0.9.7/handbook/tool-anlegen.en.md create mode 100644 docs/releases/v0.9.7/handbook/tool-bearbeiten.de.md create mode 100644 docs/releases/v0.9.7/handbook/tool-bearbeiten.en.md create mode 100644 docs/releases/v0.9.7/handbook/tools-finden.de.md create mode 100644 docs/releases/v0.9.7/handbook/tools-finden.en.md create mode 100644 docs/releases/v0.9.7/handbook/vergleichen.de.md create mode 100644 docs/releases/v0.9.7/handbook/vergleichen.en.md create mode 100644 docs/releases/v0.9.7/handbook/watchlist.de.md create mode 100644 docs/releases/v0.9.7/handbook/watchlist.en.md create mode 100644 docs/releases/v0.9.7/reference.json diff --git a/docs/releases/v0.9.7.de.md b/docs/releases/v0.9.7.de.md new file mode 100644 index 0000000..b5afb3c --- /dev/null +++ b/docs/releases/v0.9.7.de.md @@ -0,0 +1,41 @@ +# v0.9.7 — Release Notes + +**Datum:** 2026-08-06 · **Tag:** [`v0.9.7`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.7) + +## Design: Violett-Leuchtkraft für den Light-Mode + +Der Hell-Modus erhält eine eigene, einheitliche Farbwelt — ein +**Violett-Akzent** mit sanftem Pastell-Neon-Look, der dich kräftig durch +die ganze Oberfläche trägt und an den dunklen Modus anschluss. + +## Fixes & Verbesserungen + +- **Light-Mode mit Violett-Akzent:** Primärfarbe, Fokus-Ringe und erste + Chart-Farbe leuchten jetzt in einem frischen Violett statt Orange — die + Buttons, Balken, Fokus-Ringe und Sterne sprechen dieselbe SpraFarbwelt. +- **Pastell-Neon-Glow:** Glows sind im Light-Mode deutlich sichtbar + (statt auf Weiß zu verpuffen) und mit größerem Spread/Schein versehen. +- **Pastell-Wash & Karten:** Der Seitenhintergrund bekommt einen sanften + Violett-Wash (fixiert), Karten einen zarten Violett-Rand für mehr Tiefe. +- **Dark-Mode unberührt:** Cyan-Akzent und Neon-Glows des Dunkel-Modus + bleiben exakt wie zuvor; die Glow-Farbwerte sind dort jetzt fest + eingefroren. + +## API-Änderungen + +- Keine. + +## Betrieb / Upgrade + +- **Migration:** keine. **Breaking Changes:** keine. +- **Hinweis:** Nur visuelle / UI-Änderungen im Light-Modus; Dark-Mode + unverändert. + +## Bekannte Einschränkungen + +- Keine im Rahmen dieses Releases. + +## Links + +- Commit: [`f296070`](https://git.kubebase.de/admin/tool-evaluator/commit/f296070) +- Tag: [`v0.9.7`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.7) \ No newline at end of file diff --git a/docs/releases/v0.9.7.en.md b/docs/releases/v0.9.7.en.md new file mode 100644 index 0000000..ee4550c --- /dev/null +++ b/docs/releases/v0.9.7.en.md @@ -0,0 +1,39 @@ +# v0.9.7 — Release Notes + +**Date:** 2026-08-06 · **Tag:** [`v0.9.7`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.7) + +## Design: violet glow for light mode + +The light mode gains its own cohesive color world — a **violet accent** +with a soft pastel-neon glow that carries across the whole surface and +matches the character of the dark mode. + +## Fixes & improvements + +- **Light mode violet accent:** Primary color, focus rings and first chart + color now glow in a fresh violet instead of orange — buttons, bars, focus + rings and stars speak the same color language. +- **Pastel neon glow:** Glows are clearly visible in light mode (instead of + washing out on white) with a larger spread and halo. +- **Pastel wash & cards:** The page background gets a subtle violet wash + (fixed); cards gain a faint violet border for more depth. +- **Dark mode untouched:** The cyan accent and neon glows of the dark mode + remain exactly as before; the glow color values are now frozen there. + +## API Changes + +- None. + +## Operations / Upgrade + +- **Migration:** none. **Breaking changes:** none. +- **Note:** Visual / UI-only changes in light mode; dark mode unchanged. + +## Known limitations + +- None within the scope of this release. + +## Links + +- Commit: [`f296070`](https://git.kubebase.de/admin/tool-evaluator/commit/f296070) +- Tag: [`v0.9.7`](https://git.kubebase.de/admin/tool-evaluator/releases/tag/v0.9.7) \ No newline at end of file diff --git a/docs/releases/v0.9.7/handbook/administration.de.md b/docs/releases/v0.9.7/handbook/administration.de.md new file mode 100644 index 0000000..87b386d --- /dev/null +++ b/docs/releases/v0.9.7/handbook/administration.de.md @@ -0,0 +1,104 @@ + +# 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). +- **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" + +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.9.7/handbook/administration.en.md b/docs/releases/v0.9.7/handbook/administration.en.md new file mode 100644 index 0000000..e5b1e38 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/administration.en.md @@ -0,0 +1,104 @@ + +# 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). +- **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 + +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.9.7/handbook/analytics.de.md b/docs/releases/v0.9.7/handbook/analytics.de.md new file mode 100644 index 0000000..3cfacd8 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/analytics.de.md @@ -0,0 +1,29 @@ + +# 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.9.7/handbook/analytics.en.md b/docs/releases/v0.9.7/handbook/analytics.en.md new file mode 100644 index 0000000..7450a33 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/analytics.en.md @@ -0,0 +1,29 @@ + +# 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.9.7/handbook/bewerten.de.md b/docs/releases/v0.9.7/handbook/bewerten.de.md new file mode 100644 index 0000000..b4d054e --- /dev/null +++ b/docs/releases/v0.9.7/handbook/bewerten.de.md @@ -0,0 +1,39 @@ + +# 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.9.7/handbook/bewerten.en.md b/docs/releases/v0.9.7/handbook/bewerten.en.md new file mode 100644 index 0000000..7ccd0c8 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/bewerten.en.md @@ -0,0 +1,39 @@ + +# 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.9.7/handbook/datenmodell.de.md b/docs/releases/v0.9.7/handbook/datenmodell.de.md new file mode 100644 index 0000000..618e160 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/datenmodell.de.md @@ -0,0 +1,70 @@ + +# 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.9.7/handbook/datenmodell.en.md b/docs/releases/v0.9.7/handbook/datenmodell.en.md new file mode 100644 index 0000000..99d602e --- /dev/null +++ b/docs/releases/v0.9.7/handbook/datenmodell.en.md @@ -0,0 +1,70 @@ + +# 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.9.7/handbook/getting-started.de.md b/docs/releases/v0.9.7/handbook/getting-started.de.md new file mode 100644 index 0000000..b5d6906 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/getting-started.de.md @@ -0,0 +1,53 @@ + +# 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, Merkliste, 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) +- [Merkliste](/docs/handbook/watchlist) +- [Analytics](/docs/handbook/analytics) +- [Pläne & Berechtigungen](/docs/handbook/plaene) +- [Administration](/docs/handbook/administration) diff --git a/docs/releases/v0.9.7/handbook/getting-started.en.md b/docs/releases/v0.9.7/handbook/getting-started.en.md new file mode 100644 index 0000000..98344ef --- /dev/null +++ b/docs/releases/v0.9.7/handbook/getting-started.en.md @@ -0,0 +1,53 @@ + +# 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.9.7/handbook/index.de.md b/docs/releases/v0.9.7/handbook/index.de.md new file mode 100644 index 0000000..fb4d3d5 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/index.de.md @@ -0,0 +1,53 @@ + +# Willkommen bei toolr + +toolr ist eine Plattform zum **Entdecken, Bewerten und Vergleichen von +Entwicklungstools**. Nutzer 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 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 | +| **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 | + +## 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.9.7/handbook/index.en.md b/docs/releases/v0.9.7/handbook/index.en.md new file mode 100644 index 0000000..5231030 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/index.en.md @@ -0,0 +1,52 @@ + +# 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 | +| **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 | + +## 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.9.7/handbook/index.json b/docs/releases/v0.9.7/handbook/index.json new file mode 100644 index 0000000..1ab56d9 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/index.json @@ -0,0 +1,138 @@ +[ + { + "slug": "index", + "file": "index.de.md", + "title": "Überblick", + "order": 1, + "fileEn": "index.en.md", + "titleEn": "Overview" + }, + { + "slug": "getting-started", + "file": "getting-started.de.md", + "title": "Erste Schritte", + "order": 2, + "fileEn": "getting-started.en.md", + "titleEn": "Getting Started" + }, + { + "slug": "konto", + "file": "konto.de.md", + "title": "Anmelden & Konto", + "order": 3, + "fileEn": "konto.en.md", + "titleEn": "Login & Account" + }, + { + "slug": "tools-finden", + "file": "tools-finden.de.md", + "title": "Tools finden & durchsuchen", + "order": 4, + "fileEn": "tools-finden.en.md", + "titleEn": "Find & browse tools" + }, + { + "slug": "tool-anlegen", + "file": "tool-anlegen.de.md", + "title": "Tool anlegen", + "order": 5, + "fileEn": "tool-anlegen.en.md", + "titleEn": "Create a tool" + }, + { + "slug": "tool-bearbeiten", + "file": "tool-bearbeiten.de.md", + "title": "Tool bearbeiten & löschen", + "order": 6, + "fileEn": "tool-bearbeiten.en.md", + "titleEn": "Edit & delete tools" + }, + { + "slug": "bewerten", + "file": "bewerten.de.md", + "title": "Bewerten", + "order": 7, + "fileEn": "bewerten.en.md", + "titleEn": "Rating" + }, + { + "slug": "watchlist", + "file": "watchlist.de.md", + "title": "Merkliste", + "order": 8, + "fileEn": "watchlist.en.md", + "titleEn": "Watchlist" + }, + { + "slug": "vergleichen", + "file": "vergleichen.de.md", + "title": "Vergleichen", + "order": 9, + "fileEn": "vergleichen.en.md", + "titleEn": "Compare" + }, + { + "slug": "analytics", + "file": "analytics.de.md", + "title": "Analytics", + "order": 10, + "fileEn": "analytics.en.md", + "titleEn": "Analytics" + }, + { + "slug": "plaene", + "file": "plaene.de.md", + "title": "Pläne & Berechtigungen", + "order": 11, + "fileEn": "plaene.en.md", + "titleEn": "Plans & Permissions" + }, + { + "slug": "kosten", + "file": "kosten.de.md", + "title": "Kosten erfassen", + "order": 12, + "fileEn": "kosten.en.md", + "titleEn": "Recording Costs" + }, + { + "slug": "administration", + "file": "administration.de.md", + "title": "Administration", + "order": 13, + "fileEn": "administration.en.md", + "titleEn": "Administration" + }, + { + "slug": "redundanz", + "file": "redundanz.de.md", + "title": "Redundanz-Dashboard", + "order": 14, + "fileEn": "redundanz.en.md", + "titleEn": "Redundancy dashboard" + }, + { + "slug": "papierkorb", + "file": "papierkorb.de.md", + "title": "Papierkorb", + "order": 15, + "fileEn": "papierkorb.en.md", + "titleEn": "Trash" + }, + { + "slug": "tastatur", + "file": "tastatur.de.md", + "title": "Tastenkürzel & Kommandopalette", + "order": 16, + "fileEn": "tastatur.en.md", + "titleEn": "Keyboard shortcuts & command palette" + }, + { + "slug": "datenmodell", + "file": "datenmodell.de.md", + "title": "Datenmodell", + "order": 17, + "fileEn": "datenmodell.en.md", + "titleEn": "Data model" + } +] \ No newline at end of file diff --git a/docs/releases/v0.9.7/handbook/konto.de.md b/docs/releases/v0.9.7/handbook/konto.de.md new file mode 100644 index 0000000..1fc81aa --- /dev/null +++ b/docs/releases/v0.9.7/handbook/konto.de.md @@ -0,0 +1,53 @@ + +# 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: + +- **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. +- **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. 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.9.7/handbook/konto.en.md b/docs/releases/v0.9.7/handbook/konto.en.md new file mode 100644 index 0000000..22360df --- /dev/null +++ b/docs/releases/v0.9.7/handbook/konto.en.md @@ -0,0 +1,52 @@ + +# 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.9.7/handbook/kosten.de.md b/docs/releases/v0.9.7/handbook/kosten.de.md new file mode 100644 index 0000000..8904047 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/kosten.de.md @@ -0,0 +1,35 @@ + +# 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.9.7/handbook/kosten.en.md b/docs/releases/v0.9.7/handbook/kosten.en.md new file mode 100644 index 0000000..1cf7a3a --- /dev/null +++ b/docs/releases/v0.9.7/handbook/kosten.en.md @@ -0,0 +1,35 @@ + +# 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.9.7/handbook/papierkorb.de.md b/docs/releases/v0.9.7/handbook/papierkorb.de.md new file mode 100644 index 0000000..3179c74 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/papierkorb.de.md @@ -0,0 +1,41 @@ + +# 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.9.7/handbook/papierkorb.en.md b/docs/releases/v0.9.7/handbook/papierkorb.en.md new file mode 100644 index 0000000..7111def --- /dev/null +++ b/docs/releases/v0.9.7/handbook/papierkorb.en.md @@ -0,0 +1,40 @@ + +# 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.9.7/handbook/plaene.de.md b/docs/releases/v0.9.7/handbook/plaene.de.md new file mode 100644 index 0000000..2c79230 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/plaene.de.md @@ -0,0 +1,42 @@ + +# 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 Merkliste, 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 | [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. + +## 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.9.7/handbook/plaene.en.md b/docs/releases/v0.9.7/handbook/plaene.en.md new file mode 100644 index 0000000..29cce75 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/plaene.en.md @@ -0,0 +1,42 @@ + +# 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) | +| `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. + +## 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.9.7/handbook/redundanz.de.md b/docs/releases/v0.9.7/handbook/redundanz.de.md new file mode 100644 index 0000000..7521ffe --- /dev/null +++ b/docs/releases/v0.9.7/handbook/redundanz.de.md @@ -0,0 +1,38 @@ + +# 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.9.7/handbook/redundanz.en.md b/docs/releases/v0.9.7/handbook/redundanz.en.md new file mode 100644 index 0000000..27825b3 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/redundanz.en.md @@ -0,0 +1,38 @@ + +# 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.9.7/handbook/tastatur.de.md b/docs/releases/v0.9.7/handbook/tastatur.de.md new file mode 100644 index 0000000..96489bf --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tastatur.de.md @@ -0,0 +1,36 @@ + +# 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) Merkliste, 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.9.7/handbook/tastatur.en.md b/docs/releases/v0.9.7/handbook/tastatur.en.md new file mode 100644 index 0000000..2eddf47 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tastatur.en.md @@ -0,0 +1,36 @@ + +# 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.9.7/handbook/tool-anlegen.de.md b/docs/releases/v0.9.7/handbook/tool-anlegen.de.md new file mode 100644 index 0000000..db93745 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tool-anlegen.de.md @@ -0,0 +1,46 @@ + +# 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.9.7/handbook/tool-anlegen.en.md b/docs/releases/v0.9.7/handbook/tool-anlegen.en.md new file mode 100644 index 0000000..45618cf --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tool-anlegen.en.md @@ -0,0 +1,46 @@ + +# 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.9.7/handbook/tool-bearbeiten.de.md b/docs/releases/v0.9.7/handbook/tool-bearbeiten.de.md new file mode 100644 index 0000000..7f2fd3f --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tool-bearbeiten.de.md @@ -0,0 +1,33 @@ + +# 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.9.7/handbook/tool-bearbeiten.en.md b/docs/releases/v0.9.7/handbook/tool-bearbeiten.en.md new file mode 100644 index 0000000..9921517 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tool-bearbeiten.en.md @@ -0,0 +1,32 @@ + +# 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.9.7/handbook/tools-finden.de.md b/docs/releases/v0.9.7/handbook/tools-finden.de.md new file mode 100644 index 0000000..a0f8add --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tools-finden.de.md @@ -0,0 +1,67 @@ + +# 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 +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 & 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 + [Merkliste](/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.9.7/handbook/tools-finden.en.md b/docs/releases/v0.9.7/handbook/tools-finden.en.md new file mode 100644 index 0000000..6483d44 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/tools-finden.en.md @@ -0,0 +1,66 @@ + +# 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.9.7/handbook/vergleichen.de.md b/docs/releases/v0.9.7/handbook/vergleichen.de.md new file mode 100644 index 0000000..ddcf0de --- /dev/null +++ b/docs/releases/v0.9.7/handbook/vergleichen.de.md @@ -0,0 +1,42 @@ + +# 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.9.7/handbook/vergleichen.en.md b/docs/releases/v0.9.7/handbook/vergleichen.en.md new file mode 100644 index 0000000..b2e0635 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/vergleichen.en.md @@ -0,0 +1,42 @@ + +# 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.9.7/handbook/watchlist.de.md b/docs/releases/v0.9.7/handbook/watchlist.de.md new file mode 100644 index 0000000..eb25bf1 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/watchlist.de.md @@ -0,0 +1,34 @@ + +# Merkliste + +Die **Merkliste** ist eine persönliche Favoritenliste. Tools darin kannst du +jederzeit per Klick wieder aufrufen und vergleichen. + +> Die Merkliste 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 Merkliste — das Icon wird gefüllt. +- Ein erneuter Klick entfernt es wieder. + +## Merkliste ansehen + +Ö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 Merkliste gespeichert? + +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#getMeMerkliste). diff --git a/docs/releases/v0.9.7/handbook/watchlist.en.md b/docs/releases/v0.9.7/handbook/watchlist.en.md new file mode 100644 index 0000000..55da963 --- /dev/null +++ b/docs/releases/v0.9.7/handbook/watchlist.en.md @@ -0,0 +1,33 @@ + +# 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.9.7/reference.json b/docs/releases/v0.9.7/reference.json new file mode 100644 index 0000000..caa9761 --- /dev/null +++ b/docs/releases/v0.9.7/reference.json @@ -0,0 +1,2854 @@ +{ + "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": "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": "", + "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