Files
erp_naurua/docs/SPEC_PHASE1_COMPONENTS.md

8.9 KiB

Phase 1 Component Specification

Dokumentstatus

  1. Typ: operational
  2. Zweck: verbindliche Umsetzungs-Spezifikation fuer Schritt 1 Komponenten
  3. Normative Referenz: /Users/mathias/Documents/Dokumente Chouchou/Codebases/erp_naurua/docs/CONCEPT.md
  4. Abgeleitete Referenz: /Users/mathias/Documents/Dokumente Chouchou/Codebases/erp_naurua/docs/SCHEMA_PHASE1.sql
  5. Prozessreferenz: /Users/mathias/Documents/Dokumente Chouchou/Codebases/erp_naurua/docs/PROCESS_PHASE1.md
  6. Implementierungsreferenz: /Users/mathias/Documents/Dokumente Chouchou/Codebases/erp_naurua/db/migrations/

Scope

Diese Spezifikation deckt alle Schritt-1-Komponenten ab:

  1. Bestellerfassung
  2. Kontakt- und Adressdaten
  3. Artikel-Mapping und Stuecklisten
  4. Lagerverwaltung mit Chargen, MHD, Zu-/Abgaengen
  5. Chargenrueckverfolgung
  6. Teil-/Vollstorno
  7. Inbound/Outbound Webhooks
  8. Audit und technische Guardrails

Globale Invarianten

  1. sales_order.external_ref ist eindeutig und dient als Upsert-Schluessel (Shop: BestellungNr, Direktverkauf: DIR-...).
  2. Datensaetze werden nicht geloescht; Statusaenderungen und Audit-Trail werden verwendet.
  3. Verkaufsbewegungen sind immer chargengebunden.
  4. Negativbestand ist unzulaessig.
  5. Pro Produkt existieren exakt eine current-Charge und eine open-Charge.
  6. open darf nie fehlen.
  7. Zahlungsstatus aus Shop wird intern auf paid normalisiert.
  8. Direktverkaeufe haben order_source = direct und external_ref mit DIR--Praefix.

Komponente 1: Bestellerfassung

Ziel

Persistente Erfassung von Bestellungen aus Shop und Direktverkauf inkl. Positionen, Summen und Import-/Erfassungsdaten.

Eingangsquelle

  1. n8n Inbound Webhook mit Shop-JSON (order_source = wix)
  2. Manuelle ERP-Erfassung fuer Direktverkauf (order_source = direct)

Datenregeln

  1. Upsert auf sales_order.external_ref fuer Shop-Bestellungen.
  2. Direktbestellungen erhalten ERP-interne Nummern mit DIR--Praefix.
  3. order_status initial imported.
  4. Summenfelder werden direkt gespeichert (amount_net, amount_shipping, amount_tax, amount_discount, total_amount).
  5. webhook_payload wird fuer Shop-Rohdaten gespeichert (Nachvollziehbarkeit).
  6. Fuer Direktverkauf darf party_id leer sein (Laufkundschaft).

Fehlerverhalten

  1. Bei fehlender BestellungNr: Import ablehnen, Audit-Log import_rejected.
  2. Bei unbekanntem Artikelfehler: Bestellung speichern, Position mit Rohdaten speichern, Mapping-Luecke markieren.

Akzeptanzkriterien

  1. Wiederholter Import derselben BestellungNr erzeugt kein Duplikat.
  2. Direktbestellungen sind ueber den DIR--Praefix eindeutig erkennbar.
  3. Positionsdaten bleiben stabil und auditierbar.

Komponente 2: Kontakt- und Adressdaten

Ziel

Speicherung von Kundenkontakt, Lieferadresse und optionaler Rechnungsadresse.

Datenregeln

  1. Rechnungsadresse darf vollstaendig NULL sein.
  2. Lieferadresse wird als eigener Datensatz gespeichert.
  3. Land wird immer doppelt gespeichert: country_name + country_iso2.
  4. Keine serverseitige Adressvalidierung in Phase 1.
  5. Ausnahmefaelle bei Name/Firma werden unveraendert uebernommen.
  6. Bei Direktverkauf ist keine Kontakt-/Adressanlage erforderlich.

Akzeptanzkriterien

  1. Bestellung kann ohne Rechnungsadresse gespeichert werden.
  2. Liefer- und Rechnungsadresse sind getrennt auswertbar.

Komponente 3: Artikel-Mapping und Stuecklisten

Ziel

Stabile Entkopplung von Shop-Artikeln und lagergefuehrten Produkten.

Datenmodell

  1. sellable_item: verkaufbarer Artikel (auch Bundles).
  2. external_item_alias: Mapping Shop-Artikelnummer/Titel -> sellable_item.
  3. sellable_item_component: Stueckliste sellable_item -> product mit Menge.

Aufloesungsreihenfolge

  1. Match ueber external_article_number.
  2. Fallback ueber normalisierten Titel.
  3. Wenn beides fehlschlaegt: Position als unmapped speichern und auditieren.

Akzeptanzkriterien

  1. Bundle-Artikel koennen auf mehrere Lagerprodukte aufgeloest werden.
  2. Ohne Mapping bleibt Bestellung dennoch erfassbar.

Komponente 4: Lagerverwaltung und Chargen

Ziel

Konsistente Bestandsfuehrung je Charge inklusive Auto-Wechsel.

Statusmodell Charge

  1. open: vorbereitete Charge
  2. current: aktive Entnahmecharge
  3. closed: abgeschlossene Charge

Lebenszyklus

  1. open -> current -> closed
  2. Wenn current auf qty_net <= 0 faellt:
    1. alte current wird closed
    2. vorhandene open wird current
    3. neue open wird auto-angelegt

Feldregeln

  1. lot_number bei open darf leer sein.
  2. lot_number fuer current/closed ist Pflicht.
  3. Chargennummer ist pro Produkt eindeutig.
  4. Chargensalden werden aus stock_move berechnet (v_stock_lot_balance).
  5. Abverkaufprognose pro aktueller Charge wird im System gepflegt (sellout_date, warning_state).

Korrekturregeln

  1. Korrekturen erfolgen ueber adjustment-Bewegungen.
  2. Keine direkten Netto-Setzungen als Betriebsprozess.

Akzeptanzkriterien

  1. Nach jeder Entnahme bleibt die Invariante 1x current + 1x open erhalten.
  2. Negativbestand wird technisch verhindert.
  3. Warnstatus fuer UI ist ohne E-Mail nutzbar (none, due_60d, due_now).

Komponente 5: Chargenrueckverfolgung

Ziel

Lueckenlose Rueckverfolgung Bestellung -> Position -> Produkt -> Charge -> Lagerbewegung.

Datenregeln

  1. Jede Entnahme schreibt stock_move (move_type = out) mit lot_id.
  2. Pro Entnahme wird sales_order_line_lot_allocation geschrieben.
  3. allocation_status in Phase 1 standardmaessig allocated.

Akzeptanzkriterien

  1. Fuer jede ausgelieferte Position ist die verwendete Charge abfragbar.
  2. Rueckverfolgung funktioniert auch nach Teilstorno.

Komponente 6: Storno (Teil/Voll)

Ziel

Revisionssicheres Storno ohne physisches Loeschen.

Datenregeln

  1. Teil- und Vollstorno sind erlaubt.
  2. sales_order_line.qty_cancelled wird fortgeschrieben.
  3. line_status: allocated, partially_cancelled, cancelled.
  4. Bei Storno von bereits allocated Mengen erfolgt Gegenbuchung als adjustment in auf dieselbe Charge.
  5. Bestellung bleibt erhalten; Statuswechsel statt Delete.

Akzeptanzkriterien

  1. Historische Ursprungs- und Korrekturbewegungen bleiben sichtbar.
  2. Vollstorno setzt sales_order.order_status = cancelled.

Komponente 7: Webhooks

Inbound (n8n -> ERP)

  1. Transport: JSON via HTTP.
  2. Idempotenzschluessel: BestellungNr.
  3. Verarbeitung: Upsert Bestellung, Kontakt, Positionen, Lagerabgang, Audit.
  4. Quelle wird als order_source = wix gespeichert.

Direkt (ERP intern)

  1. Transport: manuelle Erfassung in ERP-Maske.
  2. Nummernlogik: ERP erzeugt external_ref mit DIR--Praefix.
  3. Verarbeitung: Bestellung (optional ohne Kontakt), Positionen, Lagerabgang, Audit.

Outbound (ERP -> n8n)

  1. Transport: Queue-basierter POST ueber outbound_webhook_event.
  2. Events Phase 1:
    1. order.imported
    2. order.cancelled.partial
    3. order.cancelled.full
    4. lot.auto_switched
  3. Signatur: X-ERP-Signature (HMAC-SHA256).
  4. Zustellung: Retry mit Backoff; final dead_letter.

Akzeptanzkriterien

  1. Event-Zustellung ist idempotent (event_key eindeutig).
  2. Fehlgeschlagene Events sind operativ auffindbar.
  3. Outbound-Payload enthaelt die Quelle (order_source), damit wix und direct getrennt auswertbar sind.

Komponente 8: Audit und Betriebssicherheit

Audit

  1. Jede fachliche Aenderung schreibt audit_log.
  2. Pflichtfelder: entity_name, entity_id, action, changed_at.
  3. Vorher/Nachher-Daten werden als JSON gespeichert, wenn verfuegbar.

Guardrails

  1. Check-Constraints fuer Statuswerte.
  2. Check-Constraints fuer Mengenbereiche.
  3. Unique-Constraints fuer kritische Eindeutigkeiten.
  4. Outbox-Statusmaschine fuer robuste externe Zustellung.

Komponenten-Matrix

  1. Bestellerfassung Zustandsquelle: sales_order, sales_order_line Hauptereignisse: order.imported, order.cancelled.*
  2. Kontakt/Adressen Zustandsquelle: party, contact, address Hauptereignisse: order.imported
  3. Artikel-Mapping Zustandsquelle: sellable_item, external_item_alias, sellable_item_component Hauptereignisse: order.imported
  4. Lagerverwaltung Zustandsquelle: stock_lot, stock_move, v_stock_lot_balance Hauptereignisse: order.imported, lot.auto_switched, order.cancelled.*
  5. Rueckverfolgung Zustandsquelle: sales_order_line_lot_allocation Hauptereignisse: alle Abgaenge und Stornos
  6. Outbound-Integration Zustandsquelle: outbound_webhook_event Hauptereignisse: alle publizierten Domain-Events

Nicht in Phase 1

  1. Rechnungswesen, Buchungssaetze, OCR-Verarbeitung.
  2. Automatisierte Preis-/Steuerneuberechnung.
  3. Vollautomatische Chargennummerngenerierung nach Produktklasse.

Change Governance

  1. Konzeptaenderungen zuerst in CONCEPT.md.
  2. Prozess- und Betriebsablauf in PROCESS_PHASE1.md.
  3. Technische Ableitung in SCHEMA_PHASE1.sql.
  4. Diese Spezifikation synchronisiert alle Komponenten auf Umsetzungsniveau.