docs: restructure agentsspec into grand-functions skill

This commit is contained in:
DanielS
2026-07-09 21:49:47 +02:00
parent 6b35917a06
commit 54b9dea70f
6 changed files with 169 additions and 144 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View File

@@ -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.

View File

@@ -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**: