From 54b9dea70fc2f9608587184e0010f6ab84e21741 Mon Sep 17 00:00:00 2001 From: DanielS Date: Thu, 9 Jul 2026 21:49:47 +0200 Subject: [PATCH] docs: restructure agentsspec into grand-functions skill --- .agents/skills/grand-functions/SKILL.md | 13 ++ .../grand-functions/references/overviews.md | 16 ++ .../grand-functions/references/processes.md | 41 +++++ .../grand-functions/references/schema.md | 84 ++++++++++ .../grand-functions/references/security.md | 15 ++ .agentsspec | 144 ------------------ 6 files changed, 169 insertions(+), 144 deletions(-) create mode 100644 .agents/skills/grand-functions/SKILL.md create mode 100644 .agents/skills/grand-functions/references/overviews.md create mode 100644 .agents/skills/grand-functions/references/processes.md create mode 100644 .agents/skills/grand-functions/references/schema.md create mode 100644 .agents/skills/grand-functions/references/security.md delete mode 100644 .agentsspec diff --git a/.agents/skills/grand-functions/SKILL.md b/.agents/skills/grand-functions/SKILL.md new file mode 100644 index 0000000..5020f04 --- /dev/null +++ b/.agents/skills/grand-functions/SKILL.md @@ -0,0 +1,13 @@ +--- +name: grand-functions +description: Dokumentation und Spezifikation des CASPOS Webshops inklusive Datenmodell, Kernprozessen und Sicherheitskonzept. +--- + +# Grand Functions - CASPOS Webshop Spezifikation + +Dieser Skill enthält die vollständige Dokumentation und Spezifikation des CASPOS Webshops. Die Spezifikationen sind in logische Referenzdokumente unterteilt: + +- [Projekt-Überblick & Tech-Stack](file:///c:/source/webshop/.agents/skills/grand-functions/references/overviews.md) +- [Datenmodell & Schema](file:///c:/source/webshop/.agents/skills/grand-functions/references/schema.md) +- [Kernprozesse](file:///c:/source/webshop/.agents/skills/grand-functions/references/processes.md) +- [Sicherheitskonzept (RLS)](file:///c:/source/webshop/.agents/skills/grand-functions/references/security.md) diff --git a/.agents/skills/grand-functions/references/overviews.md b/.agents/skills/grand-functions/references/overviews.md new file mode 100644 index 0000000..8a49e85 --- /dev/null +++ b/.agents/skills/grand-functions/references/overviews.md @@ -0,0 +1,16 @@ +# Projekt-Überblick & Technologie-Stack + +## 1. Projekt-Überblick + +Der CASPOS Webshop ist ein B2B-Portal für Vertriebspartner. Partner können hier Software-Pakete und Zusatzmodule (für POS/Kassenlösungen) konfigurieren, Anfragen für ihre Endkunden erstellen und Lizenzen verwalten. + +--- + +## 2. Technologie-Stack + +- **Frontend/Backend**: Next.js 15+ (App Router, React Server Components, Server Actions). +- **Styling**: Tailwind CSS & Vanilla CSS (modernes Dark-Theme). +- **Datenbank & Auth**: Supabase (PostgreSQL, Row Level Security - RLS, Supabase Auth). +- **E-Mail-Versand**: SMTP-Integration für automatisierte Bestätigungen. +- **PDF-Generierung**: `@react-pdf/renderer` zur Erzeugung von Anfragebestätigungen als PDF. +- **Storage**: Supabase Storage (`invoices` Bucket) zur Archivierung der PDF-Dokumente. diff --git a/.agents/skills/grand-functions/references/processes.md b/.agents/skills/grand-functions/references/processes.md new file mode 100644 index 0000000..23b5ac0 --- /dev/null +++ b/.agents/skills/grand-functions/references/processes.md @@ -0,0 +1,41 @@ +# Kernprozesse + +```mermaid +graph TD + A[Partner loggt sich ein] --> B{Firma zugewiesen?} + B -- Nein --> C[Fehlermeldung: Kein Zutritt zum Wizard] + B -- Ja --> D[Wizard öffnen / Konfigurieren] + D --> E[Endkunden auswählen/anlegen] + E --> F[Produkte & Module wählen] + F --> G{Validierung erfolgreich?} + G -- Nein --> H[Validierungsfehler anzeigen] + G -- Ja --> I[Bestellung absenden] + I --> J[Snapshot einfrieren & in DB speichern] + J --> K[Rechnungs-PDF generieren & in Storage laden] + K --> L[E-Mail mit PDF an Partner senden] + L --> M[Bestellung in der Übersicht anzeigen] +``` + +### A. Partner- & Unternehmens-Hierarchie +1. Ein neu registrierter User hat die Rolle `partner` und ist zunächst keiner Firma zugeordnet. +2. Der Administrator ordnet den User in der Admin-Oberfläche (`/admin/users`) einem Unternehmen (`companies`) zu. +3. Nur wenn der User einer Firma zugewiesen ist (oder Admin ist), kann er Endkunden anlegen und Bestellungen aufgeben. + +### B. Endkunden-Verwaltung (`/my-customers`) +- **Firmenweite Sicht**: Da `end_customers.partner_id` on `companies.id` verweist, sehen alle Mitarbeiter desselben Unternehmens dieselben Endkunden. +- **DSGVO Anonymisierung**: Endkunden können unwiderruflich anonymisiert werden. Dabei werden sensible Daten mit `[GELÖSCHT]` überschrieben und `is_anonymized` auf `true` gesetzt. In existierenden Bestellungen (`orders.customer_data`) bleiben die Daten zu steuerlichen Zwecken unverändert. + +### C. Bestell-Wizard & Validierung (`/order`) +- **Kategorie-Pflichten**: Wenn eine Produktkategorie als `is_required` definiert ist, muss ein Produkt ausgewählt werden. +- **Abhängigkeiten (Requirements)**: Ein Modul oder Produkt kann andere Module/Produkte voraussetzen (z.B. Modul B erfordert Modul A). Das System prüft dies client- und serverseitig. +- **Top-Down State-Management**: + - Die Wahl eines Basis-Produkts steuert die Sichtbarkeit und Wählbarkeit aller Module (Top-Down). Modul-Auswahlen dürfen niemals die Liste der wählbaren Basis-Produkte beeinflussen (Verhinderung von UI-Deadlocks). + - **Auto-Reset**: Beim Wechsel des Basis-Produkts über `handleBaseProductChange` werden automatisch alle ausgewählten Module entfernt, die durch `global_exclusions` für das neue Produkt ausgeschlossen sind. + - **Radio-Button-Verhalten (allow_multiselect = false)**: Falls eine Kategorie keine Mehrfachauswahl erlaubt, wird bei Auswahl eines neuen Moduls das zuvor ausgewählte Modul dieser Kategorie automatisch abgewählt. +- **Snapshot-Architektur**: Sobald eine Bestellung aufgegeben wird, werden die Kundendaten (`CustomerSnapshot`) und Produktkonfigurationen (`OrderSnapshot` samt Preisen und Modulversionen) in `orders` als JSONB-Snapshots eingefroren. Preisänderungen im Katalog haben keinen Einfluss auf bestehende Bestellungen. + +### D. Bestellungs-Verwaltung & Statusübergang +- **Sichtbarkeit**: Partner sehen in `/my-orders` alle Bestellungen aller Mitarbeiter ihrer Firma. +- **Bearbeiten**: Unvollständige Bestellungen (`status != 'completed'`) können von jedem Mitarbeiter der jeweiligen Firma nachträglich editiert werden. +- **Admin-Workflow**: Admins sehen in `/admin/orders` alle Bestellungen global, können den Status ändern (z.B. von *Eingegangen* auf *In Bearbeitung* oder *Abgeschlossen*) und PDF-Rechnungen manuell herunterladen. +- **Statusänderungs-Mails**: Bei jedem Statusübergang wird automatisch eine Benachrichtigungs-E-Mail an den Besteller geschickt. diff --git a/.agents/skills/grand-functions/references/schema.md b/.agents/skills/grand-functions/references/schema.md new file mode 100644 index 0000000..096e740 --- /dev/null +++ b/.agents/skills/grand-functions/references/schema.md @@ -0,0 +1,84 @@ +# Datenmodell & Beziehungen (Schema) + +Das Datenbankschema besteht aus folgenden Tabellen im Schema `public`: + +### `companies` (Unternehmen) +- Repräsentiert die Partner-Unternehmen (Retailer). +- `id` (UUID, Primary Key) +- `name` (TEXT) +- `street`, `zip`, `city`, `email` (Adressdaten) + +### `users` (Systembenutzer) +- Erweitert die Authentifizierungsdaten aus `auth.users`. +- `id` (UUID, References `auth.users(id)`) +- `role` (TEXT, standardmäßig `'partner'`, oder `'admin'`) +- `company_id` (UUID, References `public.companies(id)`) + +### `end_customers` (Endkunden) +- Die Endkunden, für die die Partner Lizenzen bestellen. +- `id` (UUID, Primary Key) +- `partner_id` (UUID, References `public.companies(id)`) <-- *Direkte Zuordnung zur Firma des Partners* +- `company_name` (TEXT) +- `first_name`, `last_name`, `street`, `zip`, `city`, `email` (Stammdaten) +- `bank_iban`, `bank_bic`, `bank_name`, `bank_owner` (Bankdaten) +- `is_anonymized` (BOOLEAN) <-- *Für DSGVO-Löschung* + +### `categories` (Kategorien) +- Steuert das Layout und Verhalten im Wizard. +- `id` (UUID, Primary Key) +- `name` (TEXT) +- `is_required` (BOOLEAN) <-- *Muss ausgewählt werden* +- `allow_multiple` (BOOLEAN) <-- *Mehrfachauswahl erlaubt (Checkbox statt Radio)* +- `sort_order` (INTEGER) <-- *Sortierung im Wizard* +- `show_in_branches` (BOOLEAN) +- `preselect` (BOOLEAN) +- `resets_others` (BOOLEAN) + +### `products` (Katalogprodukte / Basis-Editionen) +- Hauptlösungen (z.B. Basic-Kasse, Backoffice). +- `id` (UUID, Primary Key) +- `category_id` (UUID, References `categories`) +- `name` (TEXT) +- `base_price` (DECIMAL) +- `tax_rate` (DECIMAL) +- `billing_interval` (TEXT: `'one_time'` / `'monthly'`) +- `show_in_branches` (BOOLEAN) + +### `modules` (Zusatzmodule / Erweiterungen) +- Optionale Erweiterungen für Produkte. +- `id` (UUID, Primary Key) +- `product_id` (UUID, References `products`) +- `category_id` (UUID, References `categories`) +- `name` (TEXT) +- `price` (DECIMAL) +- `has_quantity` (BOOLEAN) + +### `global_inclusions` (Globale automatische Beigaben) +- Regelt, welche Module bei Auswahl eines Produkts kostenlos enthalten sind. +- `id` (UUID, Primary Key) +- `trigger_product_id` (UUID, References `products`) +- `included_module_id` (UUID, References `modules`) + +### `global_exclusions` (Globale Ausschlüsse) +- Regelt Inkompatibilitäten zwischen Produkten und/oder Modulen. +- `id` (UUID, Primary Key) +- `product_id` (UUID, References `products`) +- `excluded_product_id` (UUID, References `products`, optional) +- `excluded_module_id` (UUID, References `modules`, optional) + +### `orders` (Bestellungen / Anfragen) +- Gespeicherte Snapshots von Konfigurationen. +- `id` (UUID, Primary Key) +- `user_id` (UUID, References `auth.users(id)`) +- `company_id` (UUID, References `public.companies(id)`) +- `end_customer_id` (UUID, References `end_customers(id)`) +- `order_number` (TEXT, Format: `AE-YYYY-NNNNN`) +- `order_hash` (TEXT, Idempotenz-Guard) +- `type` (TEXT: `'purchase'` / `'subscription'`) <-- *Wichtig für den Checkout-Split* +- `payment_method` (TEXT) <-- *Rechnung bei Kauf, SEPA bei Abo* +- `total_price` (DECIMAL) +- `customer_snapshot` (JSONB) <-- *Stammdaten zum Bestellzeitpunkt* +- `order_snapshot` (JSONB) <-- *Konfiguration zum Bestellzeitpunkt* +- `pdf_url` (TEXT) +- `status` (TEXT: `'pending'`, `'active'`, `'completed'`, `'cancelled'`) +- `created_at` (TIMESTAMPTZ) diff --git a/.agents/skills/grand-functions/references/security.md b/.agents/skills/grand-functions/references/security.md new file mode 100644 index 0000000..c97628e --- /dev/null +++ b/.agents/skills/grand-functions/references/security.md @@ -0,0 +1,15 @@ +# Sicherheitskonzept (RLS - Row Level Security) + +RLS ist auf Datenbankebene in Postgres implementiert und erzwingt Datenisolierung: + +- **Unternehmen (`companies`)**: Authentifizierte Benutzer dürfen nur die Unternehmen lesen. +- **Endkunden (`end_customers`)**: + - `USING (partner_id = (SELECT company_id FROM public.users WHERE id = auth.uid()))` + - Partner sehen und modifizieren nur Endkunden, deren `partner_id` mit der `company_id` des angemeldeten Benutzers übereinstimmt. +- **Bestellungen (`orders`)**: + - `USING (company_id = (SELECT company_id FROM public.users WHERE id = auth.uid()))` + - Partner sehen und modifizieren nur Bestellungen, die ihrer Company zugewiesen sind (sie müssen einer Company zugeordnet sein). + - Jede Bestellung wird bei der Erstellung automatisch der Company des Erstellers zugewiesen. + - Admins haben uneingeschränkten Zugriff und können Bestellungen nachträglich anderen Companies zuweisen. +- **Lizenzen (`licenses`)**: + - Partner sehen nur Lizenzen von Endkunden, die ihrer Company zugeordnet sind. diff --git a/.agentsspec b/.agentsspec deleted file mode 100644 index 18638eb..0000000 --- a/.agentsspec +++ /dev/null @@ -1,144 +0,0 @@ -# Projekt-Dokumentation: CASPOS Webshop - -Diese Datei beschreibt die Architektur, das Datenmodell, die Kernprozesse und das Sicherheitskonzept des CASPOS Webshops. - ---- - -## 1. Projekt-Überblick - -Der CASPOS Webshop ist ein B2B-Portal für Vertriebspartner. Partner können hier Software-Pakete und Zusatzmodule (für POS/Kassenlösungen) konfigurieren, Anfragen für ihre Endkunden erstellen und Lizenzen verwalten. - ---- - -## 2. Technologie-Stack - -- **Frontend/Backend**: Next.js 15+ (App Router, React Server Components, Server Actions). -- **Styling**: Tailwind CSS & Vanilla CSS (modernes Dark-Theme). -- **Datenbank & Auth**: Supabase (PostgreSQL, Row Level Security - RLS, Supabase Auth). -- **E-Mail-Versand**: SMTP-Integration für automatisierte Bestätigungen. -- **PDF-Generierung**: `@react-pdf/renderer` zur Erzeugung von Anfragebestätigungen als PDF. -- **Storage**: Supabase Storage (`invoices` Bucket) zur Archivierung der PDF-Dokumente. - ---- - -## 3. Datenmodell & Beziehungen (Schema) - -Das Datenbankschema besteht aus folgenden Tabellen im Schema `public`: - -### `companies` (Unternehmen) -- Repräsentiert die Partner-Unternehmen (Retailer). -- `id` (UUID, Primary Key) -- `name` (TEXT) -- `street`, `zip`, `city`, `email` (Adressdaten) - -### `users` (Systembenutzer) -- Erweitert die Authentifizierungsdaten aus `auth.users`. -- `id` (UUID, References `auth.users(id)`) -- `role` (TEXT, standardmäßig `'partner'`, oder `'admin'`) -- `company_id` (UUID, References `public.companies(id)`) - -### `profiles` (Benutzerprofile) -- Stammdaten der einzelnen Benutzer (Ansprechpartner). -- `id` (UUID, References `auth.users(id)`) -- `first_name`, `last_name`, `email` etc. - -### `end_customers` (Endkunden) -- Die Endkunden, für die die Partner Lizenzen bestellen. -- `id` (UUID, Primary Key) -- `partner_id` (UUID, References `public.companies(id)`) <-- *Direkte Zuordnung zur Firma des Partners* -- `company_name` (TEXT) -- `first_name`, `last_name`, `street`, `zip`, `city`, `email` (Stammdaten) -- `bank_iban`, `bank_bic`, `bank_name`, `bank_owner` (Bankdaten) -- `is_anonymized` (BOOLEAN) <-- *Für DSGVO-Löschung* - -### `products` (Katalogprodukte) -- Hauptlösungen (z.B. Basic-Kasse, Backoffice). -- `id`, `name`, `base_price`, `tax_rate`, `billing_interval` (`one_time` / `monthly`). -- `requirements` (UUID[] von anderen Produkten) -- `exclusions` (UUID[] von inkompatiblen Produkten) - -### `product_modules` (Zusatzmodule) -- Optionale Erweiterungen für Produkte. -- `id`, `product_id` (References `products`), `name`, `price`, `has_quantity` (BOOLEAN). -- `requirements` (UUID[] von Modulen) -- `exclusions` (UUID[] von Modulen) - -### `orders` (Bestellungen / Anfragen) -- Gespeicherte Snapshots von Konfigurationen. -- `id` (UUID, Primary Key) -- `user_id` (UUID, References `auth.users(id)`) <-- *Ersteller der Bestellung* -- `order_number` (TEXT, Format: `AE-YYYY-NNNNN`) -- `order_hash` (TEXT, Idempotenz-Guard gegen Doppelübermittlung) -- `end_customer_id` (UUID, References `end_customers(id)`) -- `total_price` (DECIMAL) -- `customer_data` (JSONB) <-- *Eingefrorener Snapshot des Endkunden* -- `order_data` (JSONB) <-- *Eingefrorener Snapshot der Produktkonfiguration* -- `pdf_url` (TEXT, Link zur PDF-Rechnung im Storage) -- `status` (TEXT: `'pending'`, `'active'`, `'completed'`, `'cancelled'`) - ---- - -## 4. Kernprozesse - -```mermaid -graph TD - A[Partner loggt sich ein] --> B{Firma zugewiesen?} - B -- Nein --> C[Fehlermeldung: Kein Zutritt zum Wizard] - B -- Ja --> D[Wizard öffnen / Konfigurieren] - D --> E[Endkunden auswählen/anlegen] - E --> F[Produkte & Module wählen] - F --> G{Validierung erfolgreich?} - G -- Nein --> H[Validierungsfehler anzeigen] - G -- Ja --> I[Bestellung absenden] - I --> J[Snapshot einfrieren & in DB speichern] - J --> K[Rechnungs-PDF generieren & in Storage laden] - K --> L[E-Mail mit PDF an Partner senden] - L --> M[Bestellung in der Übersicht anzeigen] -``` - -### A. Partner- & Unternehmens-Hierarchie -1. Ein neu registrierter User hat die Rolle `partner` und ist zunächst keiner Firma zugeordnet. -2. Der Administrator ordnet den User in der Admin-Oberfläche (`/admin/users`) einem Unternehmen (`companies`) zu. -3. Nur wenn der User einer Firma zugewiesen ist (oder Admin ist), kann er Endkunden anlegen und Bestellungen aufgeben. - -### B. Endkunden-Verwaltung (`/my-customers`) -- **Firmenweite Sicht**: Da `end_customers.partner_id` auf `companies.id` verweist, sehen alle Mitarbeiter desselben Unternehmens dieselben Endkunden. -- **DSGVO Anonymisierung**: Endkunden können unwiderruflich anonymisiert werden. Dabei werden sensible Daten mit `[GELÖSCHT]` überschrieben und `is_anonymized` auf `true` gesetzt. In existierenden Bestellungen (`orders.customer_data`) bleiben die Daten zu steuerlichen Zwecken unverändert. - -### C. Bestell-Wizard & Validierung (`/order`) -- **Kategorie-Pflichten**: Wenn eine Produktkategorie als `is_required` definiert ist, muss ein Produkt ausgewählt werden. -- **Abhängigkeiten (Requirements)**: Ein Modul oder Produkt kann andere Module/Produkte voraussetzen (z.B. Modul B erfordert Modul A). Das System prüft dies client- und serverseitig. -- **Ausschlüsse (Exclusions)**: Inkompatible Produkte oder Module blockieren sich gegenseitig. -- **Snapshot-Architektur**: Sobald eine Bestellung aufgegeben wird, werden die Kundendaten (`CustomerSnapshot`) und Produktkonfigurationen (`OrderSnapshot` samt Preisen und Modulversionen) in `orders` als JSONB-Snapshots eingefroren. Preisänderungen im Katalog haben keinen Einfluss auf bestehende Bestellungen. - -### D. Bestellungs-Verwaltung & Statusübergang -- **Sichtbarkeit**: Partner sehen in `/my-orders` alle Bestellungen aller Mitarbeiter ihrer Firma. -- **Bearbeiten**: Unvollständige Bestellungen (`status != 'completed'`) können von jedem Mitarbeiter der jeweiligen Firma nachträglich editiert werden. -- **Admin-Workflow**: Admins sehen in `/admin/orders` alle Bestellungen global, können den Status ändern (z.B. von *Eingegangen* auf *In Bearbeitung* oder *Abgeschlossen*) und PDF-Rechnungen manuell herunterladen. -- **Statusänderungs-Mails**: Bei jedem Statusübergang wird automatisch eine Benachrichtigungs-E-Mail an den Besteller geschickt. - ---- - -## 5. Sicherheitskonzept (RLS - Row Level Security) - -RLS ist auf Datenbankebene in Postgres implementiert und erzwingt Datenisolierung: - -- **Unternehmen (`companies`)**: Authentifizierte Benutzer dürfen nur die Unternehmen lesen. -- **Endkunden (`end_customers`)**: - - `USING (partner_id = (SELECT company_id FROM public.users WHERE id = auth.uid()))` - - Partner sehen und modifizieren nur Endkunden, deren `partner_id` mit der `company_id` des angemeldeten Benutzers übereinstimmt. -- **Bestellungen (`orders`)**: - - `USING (company_id = (SELECT company_id FROM public.users WHERE id = auth.uid()))` - - Partner sehen und modifizieren nur Bestellungen, die ihrer Company zugewiesen sind (sie müssen einer Company zugeordnet sein). - - Jede Bestellung wird bei der Erstellung automatisch der Company des Erstellers zugewiesen. - - Admins haben uneingeschränkten Zugriff und können Bestellungen nachträglich anderen Companies zuweisen. -- **Lizenzen (`licenses`)**: - - Partner sehen nur Lizenzen von Endkunden, die ihrer Company zugeordnet sind. - ---- - -## Kommentarbereich -*Bitte nutze diesen Bereich oder füge Zeilenkommentare hinzu, um Änderungen oder Ergänzungen vorzuschlagen.* - -- **Kommentar 1**: -- **Kommentar 2**: