v2.1: Gutschein-/Rabatt-Engine + editierbare gebrandete 404
Feature 1 — Rabatt-Engine (store-sqlite.js): - Tabellen discounts + discount_redemptions; orders um discount_code/discount_cents erweitert. - Helper: getDiscountByCode, listDiscounts, create/update/deleteDiscount, validateDiscount (Zeitplan/Mindestwert/Limits/pro-Kunde), bestAutoDiscount, redeemDiscount. - Seed: WILLKOMMEN10, NAEHEN5, GRATISVERSAND (geplant), AUTO15AB75 (auto). - Checkout: /api/discount (serverseitige Subtotal-Berechnung) + /api/checkout re-validiert, wendet Rabatt/Gratisversand an, speichert + redeemt, auto-Discount-Fallback, Stripe-Coupon. - Cart/Checkout-UI mit Code-Feld + Einlösen; Rabattzeile in Order-Detail + Erfolgsseite. - Admin "Rabatte" (owner+redaktion) mit Status-Badges + Editor (Zufallscode, Typ-abh. Wertfeld). - Popups: Typ discount zeigt Code + Kopieren-Button; Stile modal/slidein/bar (CSS ergaenzt). Feature 2 — 404: - src/pages/404.astro nutzt Base + BlockRenderer, laedt System-Seite slug 404. - ensureSystemPages() legt 404 idempotent bei jedem Boot an (INSERT OR IGNORE, flache Bloecke). - 404/system erscheint in Admin "Inhalte" und oeffnet im Block-Editor. API/MCP: discounts in /api/admin/* (CRUD), Manifest + ai-admin.txt ergaenzt (inkl. Hinweis: Block-Objekte sind flach); MCP list/upsert/delete_discount. README + Versionen (2.1.0) aktualisiert.
This commit is contained in:
+7
-1
@@ -33,12 +33,15 @@ const TOOLS = [
|
||||
{ name: 'list_orders', description: 'Bestellungen auflisten (nur lesen).', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'list_slides', description: 'Slider-Slides auflisten.', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'upsert_slide', description: 'Slide anlegen/aktualisieren.', inputSchema: { type: 'object', properties: { slide: { type: 'object' } }, required: ['slide'] } },
|
||||
{ name: 'list_discounts', description: 'Alle Rabatte/Gutscheine auflisten.', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'upsert_discount', description: 'Rabatt anlegen/aktualisieren. Mit id oder code => Update, sonst Create. type: percent|fixed|freeshipping; value bei percent 1-100, bei fixed in Cent.', inputSchema: { type: 'object', properties: { discount: { type: 'object', description: 'Felder: code, title, type, value, min_order_cents, starts_at, expires_at, max_uses, max_per_customer, active, secret, auto' } }, required: ['discount'] } },
|
||||
{ name: 'delete_discount', description: 'Rabatt löschen (per ID).', inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] } },
|
||||
{ name: 'get_settings', description: 'Shop-Einstellungen (Key/Value) holen.', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'update_settings', description: 'Shop-Einstellungen aktualisieren (Key/Value-Map, z.B. shop_name, brand_accent).', inputSchema: { type: 'object', properties: { settings: { type: 'object' } }, required: ['settings'] } },
|
||||
{ name: 'get_manifest', description: 'API-Manifest (alle Ressourcen, Felder, Block-Typen).', inputSchema: { type: 'object', properties: {} } },
|
||||
];
|
||||
|
||||
const server = new Server({ name: 'hd-commerce', version: '2.0.0' }, { capabilities: { tools: {} } });
|
||||
const server = new Server({ name: 'hd-commerce', version: '2.1.0' }, { capabilities: { tools: {} } });
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
||||
@@ -57,6 +60,9 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
||||
case 'list_orders': out = await api('GET', '/api/admin/orders'); break;
|
||||
case 'list_slides': out = await api('GET', '/api/admin/slides'); break;
|
||||
case 'upsert_slide': out = await api('POST', '/api/admin/slides', a.slide); break;
|
||||
case 'list_discounts': out = await api('GET', '/api/admin/discounts'); break;
|
||||
case 'upsert_discount': out = await api('POST', '/api/admin/discounts', a.discount); break;
|
||||
case 'delete_discount': out = await api('DELETE', '/api/admin/discounts/' + encodeURIComponent(a.id)); break;
|
||||
case 'get_settings': out = await api('GET', '/api/admin/settings'); break;
|
||||
case 'update_settings': out = await api('POST', '/api/admin/settings', a.settings); break;
|
||||
case 'get_manifest': out = await api('GET', '/api/admin'); break;
|
||||
|
||||
Reference in New Issue
Block a user