Echtes Bestellsystem: Cloudflare D1 statt Beispieldaten in der Verwaltung
Ersetzt die Phase-1-Beispieldaten in /verwaltung/ durch ein echtes, funktionierendes Bestellsystem: - Neue D1-Datenbank (vans-diy-bastelbedarf-db) mit orders/order_items-Tabellen, an das Pages-Projekt gebunden (wrangler.toml). - Neue API-Routen (Pages Functions): POST /api/orders legt beim Checkout eine echte Bestellung an (mit Validierung); GET/PATCH /api/verwaltung/orders(/:id) listen bzw. ändern Bestellungen — beide zusätzlich zur Middleware nochmal eigenständig gegen die Zugangscode-Sitzung geprüft (Verteidigung in der Tiefe). Gemeinsame Auth-Logik aus _middleware.js nach functions/_shared/auth.js ausgelagert. - Checkout (4 Sprachen) sendet beim Absenden die echte Bestellung an die API, zeigt bei einem Fehler eine klare Meldung statt einfach auf die Danke-Seite weiterzuleiten. - /verwaltung/ lädt Bestellungen jetzt live per fetch(), mit Lade-/Fehlerzustand, und erlaubt direktes Ändern des Bestellstatus per Dropdown (sofort in der Datenbank gespeichert). Neuer Status "storniert" (zählt nicht in Umsatz/Auswertung mit). Vollständig lokal end-to-end getestet (wrangler pages dev + lokale D1): echter Browser-Checkout -> Bestellung landet in der Datenbank -> erscheint sofort in der Verwaltung -> Status ändern bleibt nach Neuladen bestehen. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9170b9bb22
commit
fb7a7b76c2
@@ -0,0 +1,52 @@
|
||||
-- Van's DIY & Bastelbedarf — echtes Bestellsystem (Phase 2).
|
||||
--
|
||||
-- Ersetzt die Beispieldaten in /verwaltung/. Zwei Tabellen: eine Kopf-Tabelle pro Bestellung
|
||||
-- (orders) + eine Zeilen-Tabelle pro bestelltem Artikel (order_items) — bewusst normalisiert
|
||||
-- statt alles als ein JSON-Blob zu speichern, damit "meistverkaufte Produkte je Kategorie"
|
||||
-- eine echte, schnelle SQL-Auswertung ist (GROUP BY) statt jedes Mal alle Bestellungen im
|
||||
-- Code durchzuparsen.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
-- Interne, garantiert eindeutige numerische ID (SQLite AUTOINCREMENT) — die menschenlesbare
|
||||
-- Bestellnummer (z.B. "VDB-2026-0201") wird direkt nach dem Einfügen aus dieser ID abgeleitet
|
||||
-- (siehe functions/api/orders.js), dadurch nie eine Race Condition bei paralleler Bestellung.
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bestellnummer TEXT UNIQUE,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
-- bezahlt: Phase-1-Zahlung gilt sofort als erfolgreich (siehe scripts/account.ts-Kommentar zum
|
||||
-- selben Thema) · bearbeitung/versandVorbereitet/versendet/abgeschlossen: manuelle Pflege durch
|
||||
-- qciga/VanVan in /verwaltung/ · storniert: für echte Rückabwicklungen/Fehlbestellungen.
|
||||
status TEXT NOT NULL DEFAULT 'bezahlt'
|
||||
CHECK (status IN ('bezahlt', 'bearbeitung', 'versandVorbereitet', 'versendet', 'abgeschlossen', 'storniert')),
|
||||
kunde_name TEXT NOT NULL,
|
||||
kunde_email TEXT NOT NULL,
|
||||
land TEXT NOT NULL CHECK (land IN ('de', 'at', 'ch', 'lu')),
|
||||
strasse TEXT,
|
||||
plz TEXT,
|
||||
ort TEXT,
|
||||
zahlungsart TEXT,
|
||||
tracking TEXT,
|
||||
zwischensumme REAL NOT NULL DEFAULT 0,
|
||||
versandkosten REAL NOT NULL DEFAULT 0,
|
||||
rabatt_gesamt REAL NOT NULL DEFAULT 0,
|
||||
summe REAL NOT NULL DEFAULT 0,
|
||||
treuebonus_verwendet INTEGER NOT NULL DEFAULT 0,
|
||||
abo_rabatt_verwendet INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS order_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
|
||||
produkt_slug TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
kategorie_slug TEXT,
|
||||
menge INTEGER NOT NULL,
|
||||
preis REAL NOT NULL,
|
||||
gratis INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_order_items_order_id ON order_items(order_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_land ON orders(land);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);
|
||||
Reference in New Issue
Block a user