Moodia
Moodia is de handelspartner/distributeur die Spranz producten afhandelt. Zij beheren het order fulfilment proces : zodra een Spranz klant een offerte accepteert, moet de order bij Moodia terechtkomen voor verwerking, verzending en levering. Moodia fungeert als de backoffice voor orderafhandeling — zij ontvangen orders, beheren voorraad, en verzorgen de logistiek.
Wiresphere
Wiresphere is het open-source applicatieframework (MIT licentie) waarop Moodia’s platform draait. Het is een TypeScript-based ecosysteem met een headless CMS, ingebouwd admin panel, en API-first architectuur. De API die wij aanspreken (staging-beton2go.mymoodia.de) is een Wiresphere-instantie die Moodia heeft ingericht voor hun order- en voorraadbeheer.
Partij Rol Verantwoordelijkheden Spranz (klant van Brinxx)Merkhouder / producteigenaar Productcatalogus, prijsstaffels, branding, klantrelaties Brinxx / Magic e-Verse (wij)Platform & automatisering AI sales agent, offerte generatie, e-mail verwerking, product search, designer tool, e-commerce platform Moodia Fulfilment & distributie Orderverwerking, voorraadbeheer, verzending, CRM, logistiek
┌──────────────────────────────────────────────────────────────────────────┐
│ SPRANZ KLANT BRINXX / MAGIC e-VERSE MOODIA │
│ 1. Klant stuurt 2. Magic Agent Spranz 5. Order │
│ offerte-aanvraag ──► verwerkt e-mail wordt │
│ 3. AI genereert offerte │
│ 4. Klant accepteert met tierprijzen 6. Voorraad │
│ de offerte ──────► check │
│ ┌──── DEZE INTEGRATIE ────┐ │
│ │ Geaccepteerde order ───►│──► pack & │
│ │ automatisch pushen │ ship │
│ │ Wiresphere API │ 8. Status │
│ └──────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
Geen handmatige order invoer meer — geaccepteerde offertes worden automatisch doorgestuurd naar Moodia
Real-time voorraadcontrole — voordat een offerte wordt verstuurd kan de voorraad bij Moodia gecheckt worden
Order tracking — status van bestellingen opvragen via de agent of n8n flow
CRM synchronisatie — klantgegevens automatisch aanmaken/matchen in Moodia’s systeem
Foutafhandeling — bij API fouten automatische escalatie via WhatsApp
Component Technologie Locatie Magic Agent Spranz TypeScript/Express, Claude AI, PM2 /home/adminwayne/magic_agent/agents/spranz/ (port 11010)n8n SpranzMailFlow02 n8n workflow engine http://192.168.1.26:8090Moodia Wiresphere API Wiresphere framework, JWT auth staging-beton2go.mymoodia.de (46 endpoints)Order tracking DB PostgreSQL magic_agent_brinxx → moodia_order_sync tabel
╔══════════════════════════════════════════════════════════════════════╗
║ STATUS: DRAFT — Wacht op API verkenning & antwoorden Moodia ║
║ BRON: Wayne → Michiel ║
║ Fase 0: Voorbereiding & API Verkenning ⬜ PENDING ║
║ Fase 1: Moodia API Service Module ⬜ PENDING ║
║ Fase 2: Agent Tool Definities ⬜ PENDING ║
║ Fase 3: n8n SpranzMailFlow02 Uitbreiding ⬜ PENDING ║
║ Fase 4: End-to-End Testing ⬜ PENDING ║
║ Fase 5: Productie Migratie ⬜ BLOCKED ║
║ BLOCKER: Geen zichtbaar order creation endpoint in API docs. ║
║ Moet bij Moodia nagevraagd worden (zie Open Vragen #2). ║
╚══════════════════════════════════════════════════════════════════════╝
SpranzMailFlow02
n8n workflow die inkomende e-mails verwerkt, producten matcht, tierprijzen ophaalt en professionele offertes genereert. Draait op http://192.168.1.26:8090.
Magic Agent Spranz
TypeScript/Express agent (PM2: magic-agent-spranz, port 11010) met Claude Tool Use, product search, photo search, n8n bridge en e-mail service.
Moodia Staging API
46 endpoints beschikbaar op staging-beton2go.mymoodia.de. Auth via JWT. Geen productie URL beschikbaar. Onduidelijk hoe orders worden aangemaakt.
Order Push
Nog niet geïmplementeerd. Geaccepteerde offertes worden niet automatisch doorgestuurd naar Moodia.
┌─────────────────────────────────────────────────────────────────┐
│ ┌──────────────────────────┐ │
│ │ n8n SpranzMailFlow02 │ │
│ │ 1. Email ontvangen │ │
│ │ 2. Claude analyse │ │
│ │ 3. Product matching │ │
│ │ 4. Tierprijzen ophalen │ │
│ │ 5. Offerte genereren │ │
│ │ 6. ??? (hier stopt het) │ │
│ └──────────────────────────┘ │
│ ┌──────────────────────────┐ ┌───────────────────────────┐ │
│ │ Magic Agent Spranz │ │ Moodia Wiresphere │ │
│ │ (port 11010) │ │ (staging API) │ │
│ │ ✅ Product search │ │ ✅ Inventory endpoints │ │
│ │ ✅ Photo search │ │ ✅ Transaction endpoints │ │
│ │ ✅ n8n bridge │ │ ✅ CRM endpoints │ │
│ │ ❌ Moodia integratie │ ←──│ ❓ Order creation ??? │ │
│ └──────────────────────────┘ └───────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ ┌──────────────────────────┐ │
│ │ n8n SpranzMailFlow02 │ │
│ │ 1. Email ontvangen │ │
│ │ 2. Claude analyse │ │
│ │ 3. Product matching │ │
│ │ 4. Tierprijzen ophalen │ │
│ │ 5. Offerte genereren │ │
│ │ 6. ✅ Offerte accepted? │ │
│ │ 7. ✅ Moodia klant check│───────┐ │
│ │ 8. ✅ Moodia order push │ │ │
│ │ 9. ✅ Status tracking │ │ │
│ └──────────────────────────┘ │ │
│ ┌──────────────────────────┐ ┌───────────────────────────┐ │
│ │ Magic Agent Spranz │ │ Moodia Wiresphere │ │
│ │ (port 11010) │ │ (productie API) │ │
│ │ ✅ Product search │ │ ✅ Auth (JWT) │ │
│ │ ✅ Photo search │ │ ✅ Inventory check │ │
│ │ ✅ n8n bridge │◄──►│ ✅ Order push │ │
│ │ ✅ Moodia tools (5x) │ │ ✅ CRM sync │ │
│ │ ✅ Order tracking DB │ │ ✅ Status tracking │ │
│ └──────────────────────────┘ └───────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Base URL: https://staging-beton2go.mymoodia.de
Method Endpoint Beschrijving POST /api/v1/auth/token-authJWT token ophalen
Method Endpoint Beschrijving GET /api/v1/admin/inventory/Alle producten ophalen PUT /api/v1/admin/inventory/Product aanmaken of bijwerken (upsert) DELETE /api/v1/admin/inventory/Producten verwijderen GET /api/v1/admin/inventory/{sku}Product ophalen op SKU
Method Endpoint Beschrijving GET /api/v1/admin/transaction/Alle transacties ophalen GET /api/v1/admin/transaction/{processId}/{docId}Specifieke transactie ophalen POST /api/v1/admin/transaction/{processId}/cancelTransactie annuleren POST /api/v1/admin/transaction/{processId}/{docId}/cancelSpecifiek document annuleren GET /api/v1/transaction/Publieke transacties endpoint GET /api/v1/transaction/{processId}/{docId}Publieke transactie detail
Method Endpoint Beschrijving POST /api/v1/admin/business-contacts/organisationsOrganisatie aanmaken GET /api/v1/admin/business-contacts/organisationsAlle organisaties GET /api/v1/admin/business-contacts/organisations/{id}Organisatie op ID PUT /api/v1/admin/business-contacts/organisations/{id}Organisatie bijwerken POST /api/v1/admin/business-contacts/peoplePersoon registreren GET /api/v1/admin/business-contacts/people/allAlle contactpersonen
Method Endpoint Beschrijving POST /api/v1/admin/import/{entity}Entity importeren (bulk) GET /api/v1/admin/export/{entity}Entity exporteren
BLOCKER: Geen POST endpoint voor order aanmaak
Er is geen zichtbaar POST /api/v1/admin/transaction/ endpoint in de API docs. Alleen GET (ophalen) en POST cancel (annuleren) zijn beschikbaar. Dit is de grootste blocker. Mogelijke oplossingen:
Via POST /api/v1/admin/import/transaction (bulk import)
Via een niet-gedocumenteerd endpoint
Via PUT /api/v1/admin/inventory/ dat een transactie triggert
Moet bij Moodia nagevraagd worden!
Deze vragen moeten beantwoord zijn voordat ontwikkeling start
Zonder antwoord op minimaal vraag 1, 2, 4, en 6 kan Fase 1 niet beginnen.
# Vraag Impact Status 1 Wat is de productie base URL ? (nu alleen staging beschikbaar) Fase 5 geblokkeerd ⬜ Open 2 Hoe werkt order aanmaak precies? Geen POST /transaction/ zichtbaar — alleen GET en cancel Hele integratie geblokkeerd ⬜ Open 3 Is er een webhook/callback als transactiestatus wijzigt? (order verzonden, geleverd, etc.) Status tracking design ⬜ Open 4 Hoe mappen Spranz SKUs naar Moodia inventory SKUs? (1:1 of vertaaltabel?) SKU mapping implementatie ⬜ Open 5 Is er rate limiting op de API? Zo ja, hoeveel requests/minuut? Retry/throttle design ⬜ Open 6 Welke credentials voor POST /api/v1/auth/token-auth? Aparte staging vs productie? Auth implementatie ⬜ Open 7 Welke verplichte velden bij het aanmaken van organisatie/persoon/transactie? (Swagger schema) Type definities ⬜ Open
Toegevoegd na codebase analyse — 19 maart 2026
Deze vragen zijn geïdentificeerd na analyse van de bestaande Spranz Agent codebase en de Moodia API documentatie. Antwoorden hierop bepalen architectuurbeslissingen.
# Vraag Context Impact 8 Welke entity waarden accepteert POST /api/v1/admin/import/{entity}? (bijv. transaction, order, invoice) En wat is het verwachte payload formaat? Als dit het order creation mechanisme is, moeten we exact weten welke entity values geldig zijn en wat de request body structuur is. Bepaalt of import endpoint bruikbaar is als order push 9 Is er een sandbox/test modus op staging? Kunnen we test-transacties aanmaken die geen echte inventory of fulfilment triggeren? We willen veilig kunnen testen zonder bijwerkingen op voorraad of leveringen. Voorkomt ongewenste side-effects tijdens development 10 Wat is het error response formaat ? Is er een consistent schema met error codes en messages? (bijv. { "error": { "code": "...", "message": "..." } }) We moeten errors gestructureerd kunnen loggen en afhandelen in de retry/escalatie logica. Error handling implementatie 11 Wat is de JWT token lifetime ? Is er een refresh token mechanisme of moeten we opnieuw authenticeren? Plan gaat uit van refresh 5 min voor expiry — maar we weten de werkelijke lifetime niet. Token management strategie 12 Hoe werkt paginering op list endpoints? (transactions, inventory, organisations) Is er een page size limiet? Bij grote datasets moeten we alle resultaten kunnen ophalen zonder data te missen. API service implementatie 13 Ondersteunt de API idempotency keys ? Wat gebeurt er als dezelfde order twee keer wordt gepusht? (bijv. bij network retry) Zonder idempotency risico op dubbele orders bij retry na timeout. Retry logica en data integriteit
# Vraag Context Impact 14 Welke Spranz producten staan in Moodia’s inventory ? Is dit de volledige Spranz catalogus of een subset? Moeten we eerst producten syncen via PUT /inventory/? Als Moodia niet alle Spranz SKUs kent, falen orders op onbekende SKUs. Bepaalt of product sync nodig is voor order push 15 Wat is de unieke sleutel voor klant matching in Moodia? E-mailadres, bedrijfsnaam, KvK/BTW nummer? We moeten bestaande klanten kunnen vinden om duplicaten te voorkomen. CRM zoek- en matchlogica 16 Wat is de order lifecycle ? Welke statussen kan een transactie doorlopen? (bijv. pending → confirmed → shipped → delivered) Moeten we op statuswijzigingen reageren? Bepaalt welke statussen we in moodia_order_sync moeten bijhouden en of we polling of webhooks nodig hebben. Status tracking architectuur 17 Is Moodia de pricing authority ? Worden de prijzen uit onze offerte gevalideerd/overschreven door Moodia, of worden ze 1:1 overgenomen? Als Moodia prijzen overschrijft, kunnen klant en offerte niet meer overeenkomen. Prijsintegriteit en klantcommunicatie 18 Hoe wordt BTW/valuta afgehandeld? Verwacht de API prijzen inclusief of exclusief BTW? Welke valuta? Spranz tier pricing is in EUR excl. BTW — mismatch leidt tot verkeerde facturatie. Prijs mapping in order push 19 Hoe gaat Moodia om met partial fulfillment ? Als een artikel niet op voorraad is, wordt de hele order geweigerd of deels geleverd? Bepaalt of we vooraf voorraad moeten checken en hoe we de klant informeren. Inventory check flow en klantcommunicatie
Dit versnelt de ontwikkeling aanzienlijk
De Swagger UI op staging is niet extern benaderbaar. Werkende voorbeelden zijn essentieel.
# Verzoek Toelichting 20 Postman collection of curl voorbeelden voor de belangrijkste flows: auth → create org → create orderSwagger UI retourneert geen schema’s bij remote access. Werkende voorbeelden versnellen ontwikkeling aanzienlijk. 21 Technisch contactpersoon voor doorlopende integratie-vragen tijdens developmentVoorkomt vertragingen door wachten op meetings voor elke technische vraag. 22 Sample request/response payloads voor minimaal: authenticatie, organisatie aanmaken, order aanmakenWe hebben de exacte veldnamen, types en required fields nodig voor onze TypeScript type definities.
English version for Moodia meeting
Same questions as above, translated for sharing directly with Moodia’s technical team.
Questions 1, 2, 4, and 6 are required before Phase 1 can begin
Without answers to at least these four questions, development cannot start.
# Question Impact Status 1 What is the production base URL ? (currently only staging is available) Phase 5 blocked Open 2 How does order creation work exactly? There is no visible POST /api/v1/admin/transaction/ endpoint — only GET (retrieve) and POST cancel are documented. How do we push a new order into the system? Entire integration blocked Open 3 Are there webhooks/callbacks when a transaction status changes? (e.g. order shipped, delivered, etc.) Determines polling vs. push architecture for status tracking Open 4 How do Spranz SKUs map to Moodia inventory SKUs? Are they identical (1:1) or do we need a translation table? SKU mapping implementation Open 5 Is there rate limiting on the API? If so, how many requests per minute/hour? Retry and throttle design Open 6 What are the authentication credentials for POST /api/v1/auth/token-auth? Are staging and production credentials separate? Auth implementation Open 7 What are the required fields when creating an organisation, person, or transaction? (Swagger schemas are not accessible remotely) TypeScript type definitions Open
# Question Context Impact 8 What entity values does POST /api/v1/admin/import/{entity} accept? (e.g. transaction, order, invoice) And what is the expected payload format? If this is the order creation mechanism, we need to know the exact valid entity values and request body structure. Determines if the import endpoint can be used for order push 9 Is there a sandbox/test mode on staging? Can we create test transactions that don’t affect real inventory or trigger fulfilment? We want to test safely without side effects on stock or shipments. Prevents unwanted side effects during development 10 What is the error response format ? Is there a consistent schema with error codes and messages? (e.g. { "error": { "code": "...", "message": "..." } }) We need to log and handle errors in a structured way for retry and escalation logic. Error handling implementation 11 What is the JWT token lifetime ? Is there a refresh token mechanism, or do we need to re-authenticate with username/password each time? Our plan assumes refreshing 5 minutes before expiry — but we don’t know the actual token lifetime. Token management strategy 12 How does pagination work on list endpoints? (transactions, inventory, organisations) Is there a page size limit? With large datasets we need to be able to retrieve all results without missing data. API service implementation 13 Does the API support idempotency keys ? What happens if the same order is pushed twice? (e.g. during a network retry after timeout) Without idempotency there is a risk of duplicate orders on retry. Retry logic and data integrity
# Question Context Impact 14 Which Spranz products are in Moodia’s inventory ? Is this the full Spranz catalogue or a subset? Do we need to sync products first via PUT /inventory/? If Moodia doesn’t know all Spranz SKUs, orders will fail on unknown SKUs. Determines if product sync is needed before order push 15 What is the unique key for customer matching in Moodia? Email address, company name, tax/VAT number? We need to find existing customers to prevent duplicates. CRM search and match logic 16 What is the order lifecycle ? What statuses can a transaction go through? (e.g. pending → confirmed → shipped → delivered) Do we need to react to status changes on our side? Determines which statuses we track in our moodia_order_sync table and whether we need polling or webhooks. Status tracking architecture 17 Is Moodia the pricing authority ? Are the prices from our quotation validated/overridden by Moodia, or accepted as-is? If Moodia overrides prices, the customer’s accepted quotation and actual invoice won’t match. Price integrity and customer communication 18 How is VAT/currency handled? Does the API expect prices including or excluding VAT? What currency? Spranz tier pricing is in EUR excluding VAT — a mismatch leads to incorrect invoicing. Price mapping in order push 19 How does Moodia handle partial fulfilment ? If an item is out of stock, is the entire order rejected or partially fulfilled? Determines whether we need to check inventory before pushing and how we inform the customer. Inventory check flow and customer communication
# Request Explanation 20 Postman collection or curl examples for the main flows: auth → create organisation → create orderThe Swagger UI does not return schemas when accessed remotely. Working examples will significantly speed up development. 21 Technical contact person for ongoing integration questions during developmentPrevents delays from having to wait for meetings for every technical question. 22 Sample request/response payloads for at minimum: authentication, create organisation, create orderWe need the exact field names, types, and required fields for our TypeScript type definitions.
Doel: Alle open vragen beantwoorden, API handmatig testen, n8n capaciteit evalueren.
Open vragen naar Moodia sturen
Stuur de 7 open vragen hierboven naar het Moodia contactpersoon. Zonder antwoord op vraag 2 (order aanmaak) kan er niet verder ontwikkeld worden.
Staging API authenticatie testen
curl -X POST https://staging-beton2go.mymoodia.de/api/v1/auth/token-auth \
-H " Content-Type: application/json " \
-d ' {"username": "<MOODIA_USER>", "password": "<MOODIA_PASS>"} '
# Token bewaren en testen met inventory endpoint
curl -H " Authorization: Bearer $TOKEN " \
https://staging-beton2go.mymoodia.de/api/v1/admin/inventory/
Alle relevante endpoints handmatig testen
Test met curl of Postman:
GET /api/v1/admin/inventory/ — producten ophalen
GET /api/v1/admin/inventory/{sku} — specifiek product
GET /api/v1/admin/business-contacts/organisations — organisaties
POST /api/v1/admin/business-contacts/organisations — organisatie aanmaken
GET /api/v1/admin/transaction/ — transacties ophalen
POST /api/v1/admin/import/transaction — testen als order creation mechanisme
GET /api/v1/admin/export/transaction — export om schema te reverse-engineeren
Documenteer request/response schemas voor elk endpoint.
n8n capaciteitscheck
Check op http://192.168.1.26:8090:
- Huidig execution/worker gebruik
- Beschikbare execution slots voor extra Moodia stappen
- Test connectiviteit: n8n → staging-beton2go.mymoodia.de (firewall, DNS)
SKU mapping analyseren
Vergelijk Spranz product SKUs uit de aplt_products tabel (magic_spranz_logo database) met de Moodia inventory. Bepaal of SKUs 1:1 matchen of dat een mapping tabel nodig is.
Doel: Centrale TypeScript service class voor alle Moodia API communicatie.
Locatie: /home/adminwayne/magic_agent/agents/spranz/src/services/moodia-api.ts
MoodiaApiService class implementeren
import axios, { AxiosInstance } from ' axios ' ;
import logger from ' ../utils/logger ' ;
import { moodia } from ' ../../config/config ' ;
export class MoodiaApiService {
private client : AxiosInstance ;
private token : string | null = null ;
private tokenExpiry : number = 0 ;
this . client = axios . create ({
headers: { ' Content-Type ' : ' application/json ' },
// ── Auth ─────────────────────────────────────────
async authenticate () : Promise < string > { /* POST /api/v1/auth/token-auth */ }
async getToken () : Promise < string > { /* Auto-refresh 5min voor expiry */ }
// ── Inventory ────────────────────────────────────
async getInventory () : Promise < MoodiaProduct []> { /* GET /api/v1/admin/inventory/ */ }
async getProductBySku ( sku : string ) : Promise < MoodiaProduct > { /* GET /api/v1/admin/inventory/{sku} */ }
async upsertProduct ( data : any ) : Promise < void > { /* PUT /api/v1/admin/inventory/ */ }
// ── Transactions / Orders ────────────────────────
async getTransactions () : Promise < MoodiaTransaction []> { /* GET /api/v1/admin/transaction/ */ }
async getTransaction ( processId : string , docId : string ) : Promise < MoodiaTransaction > { /* GET .../{processId}/{docId} */ }
async createOrder ( orderData : any ) : Promise < MoodiaOrderResult > { /* Endpoint TBD — zie Open Vraag #2 */ }
async cancelTransaction ( processId : string ) : Promise < void > { /* POST .../cancel */ }
// ── CRM — Organisaties ──────────────────────────
async findOrganisation ( query : string ) : Promise < MoodiaOrganisation []> { /* GET .../organisations */ }
async getOrganisation ( id : string ) : Promise < MoodiaOrganisation > { /* GET .../organisations/{id} */ }
async createOrganisation ( data : any ) : Promise < MoodiaOrganisation > { /* POST .../organisations */ }
async updateOrganisation ( id : string , data : any ) : Promise < MoodiaOrganisation > { /* PUT .../organisations/{id} */ }
// ── CRM — Personen ──────────────────────────────
async findPerson ( query : string ) : Promise < MoodiaPerson []> { /* GET .../people/all */ }
async createPerson ( data : any ) : Promise < MoodiaPerson > { /* POST .../people */ }
// ── Import (potentieel voor order push) ──────────
async importEntity ( entity : string , data : any ) : Promise < void > { /* POST .../import/{entity} */ }
async exportEntity ( entity : string ) : Promise < any > { /* GET .../export/{entity} */ }
export const moodiaApi = new MoodiaApiService ();
Token Management:
JWT token cachen in geheugen
Automatisch refreshen 5 minuten voor expiry
Bij 401 response automatisch re-authenticeren en request herhalen (max 3 retries)
Error Handling:
Retry met exponential backoff (1s, 2s, 4s) voor 5xx errors
Geen retry voor 4xx errors (behalve 401 → re-auth)
Gestructureerde error logging via Winston logger
Timeout van 30 seconden per request
Type definities aanmaken
Locatie: /home/adminwayne/magic_agent/agents/spranz/src/types/moodia.types.ts
export interface MoodiaAuthResponse {
export interface MoodiaProduct {
// Verdere velden na API verkenning in Fase 0
export interface MoodiaTransaction {
items : MoodiaTransactionItem [];
customer ?: MoodiaOrganisation ;
export interface MoodiaTransactionItem {
export interface MoodiaOrganisation {
contactPersons ?: MoodiaPerson [];
export interface MoodiaPerson {
export interface MoodiaAddress {
export interface MoodiaOrderResult {
export interface SpranzToMoodiaOrderMapping {
Config uitbreiden
Wijzig: /home/adminwayne/magic_agent/agents/spranz/config/config.ts
Voeg toe na de bestaande n8n config:
* Moodia Wiresphere API Configuration
apiUrl: process . env . MOODIA_API_URL || ' https://staging-beton2go.mymoodia.de ' ,
username: process . env . MOODIA_API_USERNAME || '' ,
password: process . env . MOODIA_API_PASSWORD || '' ,
timeout: parseInt (process . env . MOODIA_API_TIMEOUT || ' 30000 ' , 10 ) ,
enabled: !! process . env . MOODIA_API_URL ,
En aan de default export toevoegen: moodia.
Environment variabelen toevoegen
Wijzig: /home/adminwayne/magic_agent/agents/spranz/.env en .env.example
MOODIA_API_URL = https://staging-beton2go.mymoodia.de
MOODIA_API_USERNAME = <op te vragen bij Moodia>
MOODIA_API_PASSWORD = <op te vragen bij Moodia>
Er is een mapping nodig tussen Spranz SKUs en Moodia inventory SKUs. Drie opties:
Optie Wanneer Complexiteit A: Directe 1:1 mapping SKUs zijn identiek in beide systemen Laag B: Database mapping tabel SKUs verschillen, vertaaltabel nodig Middel C: Prefix/suffix transformatie Systematisch verschil (bijv. SPRANZ-376-00.001) Laag
Doel: 5 nieuwe Claude Tool Use tools voor Moodia integratie in de Spranz Agent.
Locatie: /home/adminwayne/magic_agent/agents/spranz/src/api/moodia-tools.ts
De tools volgen het bestaande patroon uit photo-search-agentic.ts — gedefinieerd als Anthropic.Tool objecten.
Tool 1: moodia_check_inventory
const MOODIA_CHECK_INVENTORY : Anthropic. Tool = {
name: ' moodia_check_inventory ' ,
description: ' Controleer productvoorraad en details in het Moodia/Wiresphere systeem op basis van SKU. ' ,
sku: { type: ' string ' , description: ' Product SKU code (bijv. "376-00.001") ' }
// Handler: moodiaApi.getProductBySku(sku) → GET /api/v1/admin/inventory/{sku}
Tool 2: moodia_push_order
const MOODIA_PUSH_ORDER : Anthropic. Tool = {
name: ' moodia_push_order ' ,
description: ' Stuur een geaccepteerde Spranz order door naar het Moodia/Wiresphere systeem. ' ,
customer_name: { type: ' string ' , description: ' Naam van de klant/organisatie ' },
customer_email: { type: ' string ' , description: ' E-mailadres van de klant ' },
sku: { type: ' string ' , description: ' Product SKU ' },
quantity: { type: ' number ' , description: ' Aantal stuks ' },
unit_price: { type: ' number ' , description: ' Prijs per stuk in EUR ' },
description: { type: ' string ' , description: ' Productomschrijving ' }
required: [ ' sku ' , ' quantity ' ]
description: ' Orderregels met producten '
reference: { type: ' string ' , description: ' Spranz order/offerte referentienummer ' },
notes: { type: ' string ' , description: ' Opmerkingen bij de order ' }
required: [ ' customer_name ' , ' customer_email ' , ' items ' ]
Handler logica:
1. moodiaApi.findOrganisation(customer_name) → bestaat klant al?
2. Zo nee: moodiaApi.createOrganisation({...}) → maak klant aan
3. moodiaApi.createOrder({...}) → push order
4. Sla mapping op in moodia_order_sync tabel (spranz_reference ↔ moodia_processId)
5. Return processId + docId voor tracking
Tool 3: moodia_get_transaction_status
const MOODIA_GET_STATUS : Anthropic. Tool = {
name: ' moodia_get_transaction_status ' ,
description: ' Haal de status op van een order/transactie in Moodia voor track & trace. ' ,
process_id: { type: ' string ' , description: ' Moodia process ID ' },
doc_id: { type: ' string ' , description: ' Moodia document ID ' }
required: [ ' process_id ' , ' doc_id ' ]
// Handler: moodiaApi.getTransaction(processId, docId)
// → GET /api/v1/transaction/{processId}/{docId}
Tool 4: moodia_find_organisation
const MOODIA_FIND_ORG : Anthropic. Tool = {
name: ' moodia_find_organisation ' ,
description: ' Zoek een klant/organisatie in het Moodia CRM systeem. ' ,
query: { type: ' string ' , description: ' Zoekterm: bedrijfsnaam of e-mailadres ' }
// Handler: moodiaApi.findOrganisation(query)
// → GET /api/v1/admin/business-contacts/organisations
// Filter resultaten op naam of e-mail match
Tool 5: moodia_create_organisation
const MOODIA_CREATE_ORG : Anthropic. Tool = {
name: ' moodia_create_organisation ' ,
description: ' Maak een nieuwe klant/organisatie aan in het Moodia CRM systeem. ' ,
name: { type: ' string ' , description: ' Bedrijfsnaam ' },
email: { type: ' string ' , description: ' E-mailadres ' },
phone: { type: ' string ' , description: ' Telefoonnummer ' },
street: { type: ' string ' , description: ' Straat + huisnummer ' },
city: { type: ' string ' , description: ' Plaats ' },
postal_code: { type: ' string ' , description: ' Postcode ' },
country: { type: ' string ' , description: ' Land (ISO code, bijv. "NL", "DE") ' }
required: [ ' name ' , ' email ' ]
// Handler: moodiaApi.createOrganisation(data)
// → POST /api/v1/admin/business-contacts/organisations
Tools integreren in de agent chat flow
Wijzig: /home/adminwayne/magic_agent/agents/spranz/src/api/send-message.ts
De Moodia tools moeten beschikbaar worden gemaakt in de Claude API call wanneer de conversatie context over Moodia, orders, voorraad, of track & trace gaat. Dit volgt het bestaande patroon van photo-search-agentic.ts:
// In send-message.ts, bij het samenstellen van de Claude API call:
// Detecteer Moodia-gerelateerde intent
const moodiaKeywords = / moodia | voorraad | inventory | order . * push | track . * trace | transactie . * status / i ;
if (moodiaKeywords . test (userMessage)) {
tools = [ ... MOODIA_TOOLS ]; // Alle 5 tools beschikbaar maken
Aan te maken in: magic_agent_brinxx database
CREATE TABLE moodia_order_sync (
spranz_reference VARCHAR ( 100 ), -- Spranz offerte/order referentie
moodia_process_id VARCHAR ( 100 ), -- Moodia processId
moodia_doc_id VARCHAR ( 100 ), -- Moodia docId
customer_name VARCHAR ( 255 ),
customer_email VARCHAR ( 255 ),
moodia_organisation_id VARCHAR ( 100 ), -- Moodia CRM organisatie ID
status VARCHAR ( 50 ) DEFAULT ' pushed ' , -- pushed, confirmed, shipped, delivered, cancelled
order_data JSONB, -- Volledige order data als JSON
moodia_response JSONB, -- Response van Moodia bij aanmaak
created_at TIMESTAMP DEFAULT NOW (),
updated_at TIMESTAMP DEFAULT NOW (),
synced_via VARCHAR ( 20 ) DEFAULT ' agent ' , -- 'agent' of 'n8n'
error_message TEXT -- Eventuele foutmelding
CREATE INDEX idx_moodia_sync_process ON moodia_order_sync(moodia_process_id);
CREATE INDEX idx_moodia_sync_reference ON moodia_order_sync(spranz_reference);
CREATE INDEX idx_moodia_sync_status ON moodia_order_sync( status );
Doel: De bestaande n8n flow uitbreiden met Moodia order-push stappen.
Email → Claude analyse → Product matching → Tierprijzen → Offerte → [EINDE]
Email → Claude analyse → Product matching → Tierprijzen → Offerte →
[NIEUW] Offerte geaccepteerd? →
JA → [NIEUW] Moodia Auth →
[NIEUW] Moodia Klant Check →
NIET GEVONDEN → [NIEUW] Moodia Klant Aanmaken →
[NIEUW] Moodia Order Push →
Node: “Moodia Auth” (HTTP Request)
Eigenschap Waarde Method POST URL {{$env.MOODIA_API_URL}}/api/v1/auth/token-authBody (JSON) { "username": "{{$env.MOODIA_USERNAME}}", "password": "{{$env.MOODIA_PASSWORD}}" }Output JWT token opslaan in flow variabele
Node: “Moodia Klant Check” (HTTP Request)
Eigenschap Waarde Method GET URL {{$env.MOODIA_API_URL}}/api/v1/admin/business-contacts/organisationsHeaders Authorization: Bearer {{$node.MoodiaAuth.json.token}}Query Zoek op klantnaam/email uit offerte Logic Niet gevonden → Node 3, wel gevonden → Node 4
Node: “Moodia Klant Aanmaken” (HTTP Request)
Eigenschap Waarde Method POST URL {{$env.MOODIA_API_URL}}/api/v1/admin/business-contacts/organisationsHeaders Authorization: Bearer {{$node.MoodiaAuth.json.token}}Body Klantgegevens uit de offerte/order data
Node: “Moodia Order Push” (HTTP Request)
Eigenschap Waarde Method Nader te bepalen (zie Open Vraag #2)URL Nader te bepalen Headers Authorization: Bearer {{$node.MoodiaAuth.json.token}}Body Order data gemapped vanuit Spranz offerte
Afhankelijk van Open Vraag #2
De exacte configuratie van deze node hangt af van het antwoord van Moodia over hoe orders aangemaakt worden. Mogelijkheden: POST /api/v1/admin/import/transaction, een niet-gedocumenteerd endpoint, of een ander mechanisme.
Node: “Order Status Logging” (PostgreSQL)
INSERT INTO moodia_order_sync
(spranz_reference, moodia_process_id, moodia_doc_id, customer_name,
customer_email, status , order_data, moodia_response, synced_via)
($ 1 , $ 2 , $ 3 , $ 4 , $ 5 , ' pushed ' , $ 6 ::jsonb, $ 7 ::jsonb, ' n8n ' );
Node: “Error Handler” (IF + Webhook)
→ WhatsApp escalatie (bestaand patroon in flow)
→ Log error in moodia_order_sync tabel
→ Optionele bevestigingsmail naar klant
Aanpak Voordeel Nadeel Aanbeveling Elke execution nieuw token Eenvoudig te implementeren Iets trager (extra API call) Start hiermee Token cachen in n8n static data Sneller, minder API calls Complexer, static data management Later optimaliseren
Doel: Alle componenten testen op staging voordat productie wordt uitgerold.
Test Verwacht Resultaat Authenticatie met geldige credentials JWT token ontvangen Authenticatie met ongeldige credentials Error 401, nette foutmelding Token refresh mechanisme Automatisch nieuw token na expiry getProductBySku met bestaand SKUProduct data retour getProductBySku met onbekend SKU404, nette foutmelding findOrganisation met bestaande naamOrganisatie gevonden createOrganisation met valide dataOrganisatie aangemaakt, ID retour createOrder (endpoint TBD)Order aangemaakt, processId + docId retour getTransaction met bestaand processIdTransactie status retour Timeout handling Request faalt netjes na 30s 5xx retry Retry met backoff, max 3 pogingen
Test Verwacht Resultaat Agent chat: “check voorraad SKU 376-00.001” Tool moodia_check_inventory aangeroepen, voorraad getoond Agent chat: “push order naar Moodia” Tool moodia_push_order aangeroepen, klant check + order push Agent chat: “status van mijn bestelling” Tool moodia_get_transaction_status aangeroepen met processId Agent chat: “zoek klant Bedrijf X” Tool moodia_find_organisation aangeroepen Agent chat: “maak klant aan” Tool moodia_create_organisation aangeroepen Duplicate klant check Bestaande klant wordt gevonden, niet opnieuw aangemaakt
Test Verwacht Resultaat Flow met geaccepteerde offerte Moodia auth + klant check + order push succesvol Flow met nieuwe klant Klant aangemaakt in Moodia CRM Flow met bestaande klant Klant gevonden, niet opnieuw aangemaakt Flow met API error WhatsApp escalatie, error gelogd Flow execution tijd < 30 seconden inclusief Moodia API calls Meerdere orders achter elkaar Geen race conditions, alle orders correct
Volledige end-to-end flow
Stuur test e-mail naar Spranz mailbox
Verifieer offerte generatie
Simuleer offerte acceptatie
Controleer Moodia staging: klant aangemaakt?
Controleer Moodia staging: order zichtbaar?
Controleer database: moodia_order_sync record aanwezig?
Status tracking test
Vraag transactie status op via agent
Controleer of processId/docId correct zijn
Controleer publieke endpoint: GET /api/v1/transaction/{processId}/{docId}
Error recovery test
Simuleer Moodia API downtime (verkeerde URL)
Verifieer WhatsApp escalatie
Verifieer error logging in database
Herstel API URL en test opnieuw
BLOCKER: Productie API URL nodig
Deze fase kan pas starten wanneer Moodia de productie API URL en credentials levert. Tot die tijd werken we uitsluitend op staging.
Productie configuratie
# Update .env op de server
MOODIA_API_URL = https://<productie-url-van-moodia>
MOODIA_API_USERNAME = <productie-credentials>
MOODIA_API_PASSWORD = <productie-credentials>
PM2 restart
pm2 restart magic-agent-spranz
pm2 logs magic-agent-spranz --lines 50
n8n credentials updaten
Update Moodia API credentials in n8n voor de productie URL.
Eerste productie order
Push handmatig 1 order via de agent
Verifieer in Moodia productie dashboard
Controleer transactie status ophalen
Monitoring opzetten
Winston log level op info voor Moodia calls
Alerting bij herhaalde API failures
Dagelijkse check op moodia_order_sync tabel voor error status records
Bestand Actie Beschrijving agents/spranz/src/services/moodia-api.tsNIEUW Centrale Moodia API service class met JWT auth, retry logic agents/spranz/src/types/moodia.types.tsNIEUW TypeScript interfaces voor Moodia data modellen agents/spranz/src/api/moodia-tools.tsNIEUW 5 Claude Tool Use definities voor Moodia integratie agents/spranz/config/config.tsWIJZIG Moodia config sectie toevoegen agents/spranz/.envWIJZIG Moodia environment variabelen toevoegen agents/spranz/.env.exampleWIJZIG Moodia env vars documenteren agents/spranz/src/api/send-message.tsWIJZIG Moodia tools integreren in chat flow agents/spranz/src/index.tsWIJZIG Moodia health check, export config n8n SpranzMailFlow02 WIJZIG 6 nieuwe nodes voor Moodia integratie
Database Tabel Actie Beschrijving magic_agent_brinxxmoodia_order_syncNIEUW Order tracking en sync status magic_agent_brinxxmoodia_sku_mappingNIEUW (optioneel)SKU vertaaltabel indien nodig
Risico Impact Kans Mitigatie Geen POST endpoint voor order aanmaak HOOG — Gehele integratie geblokkeerdMiddel Import endpoint testen; Moodia contacten voor docs Moodia staging API instabiel MIDDEL — Testing vertraagdLaag Retry mechanisme; optioneel mock server SKU mapping mismatch MIDDEL — Orders met verkeerde productenMiddel Eerst inventory export vergelijken met Spranz SKUs n8n capacity tekort LAAG — Extra stappen te traagLaag Worker/execution limiet verhogen JWT token expiry tijdens flow LAAG — Order push faaltLaag Auto-refresh; retry op 401 Rate limiting niet bekend MIDDEL — API calls geblokkeerdMiddel Throttle implementeren; batch requests
Resource URL / Locatie Moodia staging API docs https://staging-beton2go.mymoodia.de/api/docs/#/Moodia auth endpoint POST /api/v1/auth/token-authn8n SpranzMailFlow02 http://192.168.1.26:8090/workflow/SpranzMailFlow02Spranz Agent codebase /home/adminwayne/magic_agent/agents/spranz/Spranz Agent PM2 magic-agent-spranz (port 11010)Agent database magic_agent_brinxx (PostgreSQL)Product database magic_spranz_logo (Spranz SKUs)
Plan aangemaakt: 4 maart 2026 | Bron ticket: Wayne → Michiel | Status: Draft — wacht op Moodia API verkenning