Files
webshop/funktionen.md
DanielS 305af64fd6
All checks were successful
Staging Build / build (push) Successful in 3m36s
feat: assign orders to companies directly and support admin reassignment
2026-07-04 16:08:31 +02:00

7.2 KiB

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

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

    • Partner sehen und modifizieren nur Bestellungen von Benutzern, die derselben Company angehören (sie müssen einer company zugewiesen sein).
    • Admins haben uneingeschränkten Zugriff.
  • Lizenzen (licenses):

    • Partner sehen nur Lizenzen von Endkunden, die ihrer Company zugeordnet sind.
  • **Erstellung: jede bestellung wird der firma des erstellers zugewiesen. Ein admin ist aber fähig einer bestellung nachträglich eine andere firma zuzuweisen.


Kommentarbereich

Bitte nutze diesen Bereich oder füge Zeilenkommentare hinzu, um Änderungen oder Ergänzungen vorzuschlagen.

  • Kommentar 1:
  • Kommentar 2: