Erweitere Schema fuer Shopify Delta Import

This commit is contained in:
2026-08-12 17:31:37 +02:00
parent 769f448332
commit fd00a851ed
3 changed files with 182 additions and 0 deletions
@@ -0,0 +1,68 @@
BEGIN;
-- Additive Shopify delta-sync identities. Existing Wix and direct orders,
-- their lines and their lot allocations remain unchanged.
ALTER TABLE sales_order
ADD COLUMN IF NOT EXISTS shopify_order_gid TEXT,
ADD COLUMN IF NOT EXISTS shopify_order_name TEXT,
ADD COLUMN IF NOT EXISTS shopify_created_at TIMESTAMP,
ADD COLUMN IF NOT EXISTS shopify_updated_at TIMESTAMP,
ADD COLUMN IF NOT EXISTS shopify_financial_status TEXT,
ADD COLUMN IF NOT EXISTS shopify_fulfillment_status TEXT;
ALTER TABLE sales_order_line
ADD COLUMN IF NOT EXISTS shopify_line_item_gid TEXT,
ADD COLUMN IF NOT EXISTS shopify_variant_gid TEXT,
ADD COLUMN IF NOT EXISTS shopify_product_gid TEXT,
ADD COLUMN IF NOT EXISTS sku TEXT;
ALTER TABLE external_item_alias
ADD COLUMN IF NOT EXISTS shopify_product_gid TEXT,
ADD COLUMN IF NOT EXISTS shopify_variant_gid TEXT;
CREATE TABLE IF NOT EXISTS party_external_identity (
id BIGSERIAL PRIMARY KEY,
party_id BIGINT NOT NULL REFERENCES party(id) ON DELETE CASCADE,
source_system TEXT NOT NULL,
external_id TEXT NOT NULL,
observed_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
CONSTRAINT uq_party_external_identity_source_external UNIQUE (source_system, external_id)
);
ALTER TABLE sales_order
DROP CONSTRAINT IF EXISTS chk_sales_order_source;
ALTER TABLE sales_order
ADD CONSTRAINT chk_sales_order_source
CHECK (order_source IN ('wix', 'direct', 'shopify'));
ALTER TABLE sales_order
DROP CONSTRAINT IF EXISTS chk_sales_order_payment_status;
ALTER TABLE sales_order
ADD CONSTRAINT chk_sales_order_payment_status
CHECK (payment_status IN ('pending', 'authorized', 'paid', 'partially_refunded', 'refunded', 'voided', 'unknown'));
CREATE UNIQUE INDEX IF NOT EXISTS uq_sales_order_shopify_order_gid
ON sales_order(shopify_order_gid)
WHERE shopify_order_gid IS NOT NULL;
CREATE UNIQUE INDEX IF NOT EXISTS uq_sales_order_line_shopify_line_item_gid
ON sales_order_line(shopify_line_item_gid)
WHERE shopify_line_item_gid IS NOT NULL;
CREATE UNIQUE INDEX IF NOT EXISTS uq_external_item_alias_shopify_variant_gid
ON external_item_alias(shopify_variant_gid)
WHERE shopify_variant_gid IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_party_external_identity_party
ON party_external_identity(party_id);
CREATE INDEX IF NOT EXISTS idx_sales_order_shopify_updated_at
ON sales_order(shopify_updated_at DESC)
WHERE shopify_order_gid IS NOT NULL;
COMMIT;
@@ -13,6 +13,7 @@ Diese Referenz ordnet die aktuellen Tabellen, Views und technischen DB-Artefakte
- `party`
- `address`
- `contact`
- `party_external_identity`
### `bestellungen`
@@ -0,0 +1,113 @@
# erp.import-integration.shopify_delta_order_import
Stand: 2026-08-12
Status: Verbindliche Prozess-Spezifikation
## 1. Zweck
Read-only-Abgleich von Shopify-Bestellungen nach dem ERP-Stichtag und identifier-only Übergabe qualifizierter Bestellungen an `erp/bestellungen`.
## 2. Prozess-Einbettung
Manuell startbarer Initial-Deltalauf und später wiederverwendbarer Reconciliation-Prozess im Submodul `erp/import-integration`. Er ist vom Webhook-Empfang getrennt.
## 3. Input
- `cutoff_timestamp`
- optional `dry_run`
Es werden keine vorbereiteten Shopify-Geschäftsdaten an nachgelagerte Module übergeben.
## 4. Exakter Prozessablauf
1. `cutoff_timestamp` und `dry_run` validieren.
2. Read-only Shopify-Bestellungen mit `createdAt` nach dem Stichtag in stabiler Reihenfolge laden.
3. Stornierte oder vollständig erstattete Bestellungen als nicht lagerwirksam klassifizieren und nur technisch protokollieren.
4. Für jede qualifizierte Bestellung die Shopify Order-GID idempotent gegen `sales_order.shopify_order_gid` prüfen.
5. Nur die Shopify Order-GID an die Bestell-Schnittstelle übergeben; diese lädt und projiziert die erforderlichen Shopify-Daten selbst.
6. Bei `dry_run` keine fachlichen DB-Writes, Lagerbewegungen oder externen Aufrufe ausführen.
7. Keine Shopify-Mutation, keine n8n-Zustellung, kein Klaviyo-Ereignis, keine Kundenmail und keine Label-Aktion ausführen.
8. Den technischen Lauf in `process_runs` abschliessen.
Read sources:
- Shopify Admin API, ausschliesslich read-only
- `sales_order` für die Idempotenzprüfung
- `shopify_webhook_event` und `process_runs` als technische Eingangs-/Laufdaten
Write targets:
- `process_runs`
- technische Ergebnisdaten im owning Submodul
- Bestelldaten ausschliesslich über die Schnittstelle von `erp/bestellungen`
## 5. Batch, Betriebsmodell und Einbettung
Der Initiallauf verarbeitet den festen Zeitraum nach dem bestehenden ERP-Stichtag seriell. Spätere Reconciliation-Läufe nutzen denselben Prozess mit einem definierten Wasserzeichen. Keine Parallelisierung.
## 6. Output
Kompaktes Ergebnis mit geprüfter, übersprungener, bereits vorhandener und übergebener Bestellanzahl.
## 7. Erfolgskriterien
- nur Bestellungen nach dem Stichtag werden berücksichtigt
- stornierte/erstattete Bestellungen sind nicht lagerwirksam
- jede Shopify Order-GID wird höchstens einmal als ERP-Bestellung angelegt
- der Dry-Run verändert keine fachlichen Daten
- n8n, Klaviyo, Mail, Labels und Shopify bleiben unbeeinflusst
## 8. Fehlerschranke
Ein Shopify-API- oder technischer DB-Fehler beendet den Lauf hart. Eine fachlich nicht abbildbare Einzelbestellung wird als Klärfall gezählt; weitere Bestellungen werden verarbeitet.
## 9. Fachliche Betriebsregel
Die bestehenden 93 ERP-Bestellungen inklusive ihrer Chargen- und Lagerrelationen bleiben erhalten. Nur neuere, qualifizierte Shopify-Bestellungen erzeugen neue Bestellpositionen und Lagerbewegungen.
## 10. Sub-Prozess-Referenzen
- `erp.bestellungen.shopify_order_projection`
## 11. End-to-End Sub-Prozess-Kette
Delta-Scope bestimmen → Shopify read-only laden → Qualifikation → identifier-only Bestellübergabe → technischer Abschluss.
## 12. Sub-Prozess-Wiederverwendung
Der bestehende Shopify-API-Client und die vorhandene technische Laufpersistenz werden wiederverwendet. Die Bestell- und Lagerfachlichkeit bleibt in ihren owning Modulen.
## 13. Step-Liste
1. `validate_delta_scope`
2. `load_shopify_delta`
3. `classify_order_for_inventory`
4. `shopify_order_projection`
5. `finalize_delta_run`
## 14. Parallelisierung
Nicht anwendbar. Der aktuelle Delta-Scope ist klein und wird seriell, nachvollziehbar verarbeitet.
## 15. Output-Payload
```json
{
"status": "done|partial_success|failed",
"cutoff_timestamp": "ISO-8601 timestamp",
"dry_run": true,
"checked_orders": 0,
"skipped_cancelled_or_refunded": 0,
"already_imported": 0,
"handed_off": 0,
"clarification_order_gids": [],
"technical_run_id": 0
}
```
## 16. Done-Kriterien
- Stichtag und Qualifikationsregel sind umgesetzt und testbar.
- Shopify-Identitäten sind im Datenmodell eindeutig speicherbar.
- Bestehende Bestellungen und Chargenrelationen bleiben unverändert.
- Der Dry-Run ist nebenwirkungsfrei.
- Externe Kommunikation bleibt in diesem Prozess ausgeschlossen.