Files
vans-diy-bastelbedarf/d1/schema.sql
T
qciganoandClaude Sonnet 5 fb7a7b76c2 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]>
2026-08-03 20:32:46 +02:00

53 lines
2.4 KiB
SQL

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