API: mehrere Produkte je Zugang (m2m) + Produktwahl im Order-Request
- api_clients bekommt ein m2m-Feld `products` (Mehrfachauswahl) über die neue Junction `api_client_products`; das Einzelfeld `product` bleibt als Fallback. - POST /v1/orders: neues Pflichtfeld `product` (Produkt-Key) wählt aus den erlaubten Produkten; bei genau einem optional. Ungültig/fehlend → 400 mit Liste der erlaubten Keys. - POST /v1/clients akzeptiert `products: [id, …]`. - Doku (Swagger UI) + OpenAPI um das product-Feld ergänzt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -453,7 +453,10 @@ const collections = [
|
||||
f('key_prefix', 'string', { interface: 'input', note: 'Erkennungspräfix des Keys (nur Anzeige).' }),
|
||||
f('key_hash', 'string', { interface: 'input', note: 'SHA-256 des API-Keys – automatisch gesetzt. Nicht manuell ändern.' }),
|
||||
m2o('customer', 'directus_users', { note: 'Verknüpftes Kundenkonto (optional).' }),
|
||||
m2o('product', 'products', { nullable: false, note: 'Einziges Produkt, das dieser Zugang bestellen darf.' }),
|
||||
// Mehrere erlaubte Produkte (m2m). Die Order gibt per „product" an, welches genutzt wird.
|
||||
{ field: 'products', type: 'alias', meta: { interface: 'list-m2m', special: ['m2m'], note: 'Erlaubte Produkte für diesen Zugang (Mehrfachauswahl).' }, schema: null },
|
||||
// Einzelprodukt (optional, Fallback/alt) – wird nur genutzt, wenn keine m2m-Produkte gesetzt sind.
|
||||
m2o('product', 'products', { note: 'Einzelprodukt (Fallback). Für mehrere Produkte „products" nutzen.' }),
|
||||
f('active', 'boolean', { interface: 'boolean', default: true }),
|
||||
f('webhook_url', 'string', { interface: 'input', note: 'Optionaler Webhook für Statusänderungen (derzeit ungenutzt – Kunde pollt).' }),
|
||||
f('config', 'json', { interface: 'input-code', note: 'Kundenspezifische Konfiguration (optional).' }),
|
||||
@@ -464,6 +467,12 @@ const collections = [
|
||||
f('contract_ref', 'string', { interface: 'input', note: 'Referenz zum unterschriebenen Vertrag (Aktenzeichen/Link).' }),
|
||||
] },
|
||||
|
||||
// Junction API-Zugang ↔ Produkt (m2m für api_clients.products).
|
||||
{ collection: 'api_client_products', meta: { icon: 'link', note: 'Junction API-Zugang ↔ Produkt.', hidden: true }, fields: [
|
||||
m2o('api_client', 'api_clients', { onDelete: 'CASCADE' }),
|
||||
m2o('product', 'products', { onDelete: 'CASCADE' }),
|
||||
] },
|
||||
|
||||
// Unterschriften je Kunde (SVG-Datei). Wird am Kundenkonto als o2m gezeigt.
|
||||
{ collection: 'signatures', meta: { icon: 'draw', note: 'Unterschriften je Kunde.' }, fields: [
|
||||
m2o('customer', 'directus_users', { onDelete: 'CASCADE' }),
|
||||
@@ -636,6 +645,9 @@ async function applySchema() {
|
||||
try {
|
||||
await api('PATCH', '/relations/order_addons/order', { meta: { one_field: 'addons', junction_field: 'price_item' } });
|
||||
await api('PATCH', '/relations/order_addons/price_item', { meta: { junction_field: 'order' } });
|
||||
// m2m api_clients.products ↔ products über api_client_products
|
||||
await api('PATCH', '/relations/api_client_products/api_client', { meta: { one_field: 'products', junction_field: 'product' } });
|
||||
await api('PATCH', '/relations/api_client_products/product', { meta: { junction_field: 'api_client' } });
|
||||
log('m2m verdrahtet');
|
||||
} catch (e) { console.warn(' m2m-Verdrahtung übersprungen (bitte melden):', e.message); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user