Erweitere Schema fuer Shopify Delta Import
This commit is contained in:
@@ -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`
|
||||
|
||||
|
||||
+113
@@ -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.
|
||||
Reference in New Issue
Block a user