Boostlogix · Warehouse Operations Platform

Projectdocumentatie & validatie

Volledige uitleg van elk rekenmodel in het platform: wat er berekend wordt, hoe, waarom het zo is ingericht, en hoe elke berekening gevalideerd is. Elk cijfer in het dashboard is met dit document na te rekenen.

1. Doel & validatiestatus

Dit platform simuleert en analyseert warehouse-operaties (picken, wegzetten, combitruck-rondes, slotting) op basis van echte WMS-data. Dit document is de technische onderbouwing: het legt elk rekenmodel uit zodat resultaten richting klanten verdedigbaar en narekenbaar zijn.

AspectStatus
Geautomatiseerde tests85 tests via node --test "tests/*.test.mjs" — elke engine heeft handmatig narekenbare testgevallen (zie §12)
KwaliteitsbewakingAparte bewakingstests dwingen de projectafspraken af: engines blijven puur (geen UI-code), elke parameter is gedocumenteerd, dit document vermeldt het werkelijke testaantal, en de deploy-map is identiek aan de bron
BrowserverificatieFunctionele end-to-end-test (tests/ui-test.html) die alle modules aanklikt en resultaten controleert
ReproduceerbaarheidAlle steekproeven en mockdata gebruiken een vaste seed (mulberry32) — zelfde invoer geeft altijd exact dezelfde uitkomst
Scheiding logica / weergaveAlle rekenmodellen zijn pure modules in js/engines/ zonder UI-afhankelijkheden — afzonderlijk testbaar en herbruikbaar
Tijd-consistentieDe animatie speelt exact de berekende tijd af (tijdlijn = rijtijd + handelingstijden); vastgelegd met een consistentietest
Leeswijzer eerlijkheid: overal waar het model een aanname of vereenvoudiging bevat, staat dat expliciet vermeld (zie ook §11). Voorbeeldcijfers uit "de demonstratierun" komen uit een vaste seeded steekproef op de echte mutatiedata en zijn dus reproduceerbaar, maar wisselen mee als de invoerdata wisselt.

2. Data & coördinatensysteem

Alle berekeningen werken op drie databestanden die uit WMS-exports gegenereerd worden.

BestandInhoudBron
warehouse_locations.json37.760 locaties: code, gang, blok, verdieping, positie + 3D-coördinatengenerate_layout.py ← plattegrond-xlsx
analysis_data.jsonPer locatie: ABC-klasse, voorraadleeftijd, zone, categorie (momentopname voorraad)generate_analysis.py ← voorraadexport
simulation_data.json9.480 chronologische mutaties (pick/put-away) over 6 dagen: tijdstip, locatie, artikelgenerate_simulation.py ← mutatie-export

Locatiecode → 3D-positie

Locatieformat GG-BB-VA (gang–blok–verdieping+positie). De afbeelding naar meters:

X = floor((blok − 1) / 2) × 4·palletbreedte + positie·palletbreedte [positie A=0 … D=3] Y = (verdieping − 1) × pallethoogte [1,4 m per niveau] Z = (maxGang − gang) × ganginterval ± stellingoffset [5,2 m per gang; even blok +2,0, oneven −2,0]
Voorbeeld: locatie 23-28-1A
X = floor(27/2) × 4 × 1,0 + 0 = 13 × 4 = 52,0 m Y = (1−1) × 1,4 = 0,0 m (begane grond) Z = (24−23) × 5,2 + 2,0 = 7,2 m (even blok, voorzijde van gangpad 23)

Gangen lopen dus in de X-richting; het gangpadcentrum van een gang wordt in de engines afgeleid uit de locatiedata zelf (gemiddelde van min/max Z per gang), zodat ook afwijkende klantlayouts kloppen zonder hardcoded maten.

Bron: generate_layout.py · js/engines/routing.js (constructor) Test: routing.test.mjs — "gangcentrum wordt afgeleid uit de locaties"

3. Afstandsberekening (routeringsmodel)

Alle afstanden in het platform — picksimulatie, wegzetten, combitruck, slottingscore, what-if — komen uit één routeringsengine. Er bestaat dus geen "tweede waarheid".

Het gangpadmodel

Een picker of truck beweegt uitsluitend:

  • binnen een gangpad in de X-richting;
  • tussen gangpaden via een kopgang (links of rechts om de stellingen heen), een doorlopende dwarsgang (indien geconfigureerd) of een doorsteekopening (§4).

Diagonaal door stellingen "snijden" is per constructie onmogelijk: het routenetwerk is een portaalgraaf waarin alleen die verbindingen bestaan. Kortste paden worden berekend met Dijkstra; portaal-naar-portaal-afstanden worden één keer berekend en daarna hergebruikt (exact, geen benadering).

zelfde gang : afstand(a, b) = |x_a − x_b| andere gang : afstand(a, b) = min over portalen p_a, p_b van |x_a − x(p_a)| + kortste netwerkafstand(p_a → p_b) + |x(p_b) − x_b|
Narekenvoorbeeld (vastgelegd als test)

Testwarehouse: 3 gangen (Z = 10, 5, 0), stellingen X 0–20, kopgangen op X = −2 en X = +22. Van (x=2, gang 1) naar (x=8, gang 2):

via links : |2−(−2)| + |10−5| + |8−(−2)| = 4 + 5 + 10 = 19 m ← kortste via rechts: |2−22| + |10−5| + |8−22| = 20 + 5 + 14 = 39 m met extra dwarsgang op X=10: 8 + 5 + 2 = 15 m
Tests: routing.test.mjs — afstand, dwarsgang, symmetrie, axis-aligned paden, kopgang uitschakelen

Verticaal: tijd, geen meters

Een pick op verdieping 5 kost geen extra loopafstand maar wel extra tijd (instelbaar per niveau). In KPI's waar hoog/laag eerlijk moet meewegen (slottingscore, what-if) wordt die tijd omgerekend naar meter-equivalenten — zie §10.

4. Doorsteekdetectie

In veel warehouses zitten doorrijopeningen ónder de stellingen waar een truck van gang kan wisselen. Het platform detecteert ze automatisch uit de layoutdata — geen handmatige invoer, dus ook geen vergeten of verzonnen openingen.

Detectieregel

Een doorsteek tussen twee aangrenzende gangpaden = een X-bereik waarin tussen de twee gangcentra GEEN locaties bestaan op verdieping 1 … doorrijNiveaus, en dat minimaal minOpeningBreedte meter breed is.

Dit dekt twee fysieke situaties: (a) een doorrijopening onder de stellingen — verdieping 1–3 ontbreekt, verdieping 4+ loopt door; (b) gebieden waar simpelweg geen stellingen staan.

Geverifieerd praktijkvoorbeeld uit het demowarehouse

Tussen locatie 23-22-1D (x≈43) en 23-28-1A (x=52): blokken 23–26 van gang 22 én 23 hebben alleen verdieping 4–6 in de data — verdieping 1–3 is vrij. De detectie vindt hier een doorsteek op x 44–52, precies de opening die in de praktijk gebruikt wordt. In totaal vindt de detectie 32 doorsteken in de demolayout.

Elke gedetecteerde doorsteek is in de 3D-view zichtbaar (groen vlak) en per stuk uit te schakelen (rood) als hij in werkelijkheid niet gebruikt mag worden. Uitgeschakelde doorsteken doen niet mee in het routenetwerk.

Bron: js/engines/openingen.js Tests: openingen.test.mjs — incl. integratietest op de echte layout (doorsteek 23↔22 bij x 44–52)

5. Picklogica — orderpicker (4 algoritmen)

De picksimulatie vergelijkt vier routeringsstrategieën op exact dezelfde picklijst. De gerapporteerde afstand van de heuristieken is de werkelijk gelopen route (expliciet pad, inclusief volledige gangtraversen) — niet een optimistische som van hemelsbrede afstanden.

AlgoritmeWerkingWanneer sterk
S-vormElke gang met picks volledig doorlopen, afwisselend van kopgang wisselend (slingerend). Laatste gang: goedkoopste afsluiting (keren of doorlopen) inclusief terugweg naar het depot.Veel picks per gang
Grootste openingPer gang worden picks gesplitst bij de grootste "opening" (gat tussen opeenvolgende picks of naar een kopgang): het deel vóór de opening wordt vanaf links bediend, het deel erna vanaf rechts via keerlussen. De verste gang wordt doorlopen om de andere kopgang te bereiken.Weinig picks per gang
GecombineerdPer gang de goedkoopste keuze: volledig doorlopen (kost ganglengte, wisselt van kant) of keren bij de verste pick (kost 2 × diepte, blijft aan dezelfde kant).Gemengde dichtheid
Optimaal (2-opt)Nearest-neighbour-startvolgorde, verbeterd met 2-opt op de exacte netwerkafstanden (incl. doorsteken). Geen gang-heuristiek: vrije volgorde.Referentie / bovengrens van haalbare winst
keuzeregel gecombineerd, per gang: keren als 2 × max|x_pick − kopgang| ≤ ganglengte splitsing grootste opening: grootste gat in {kopgang_L → p1, p1 → p2, …, pn → kopgang_R}
Narekenvoorbeeld S-vorm (vastgelegd als test, uitkomst exact 82 m)

Testwarehouse §3, depot op (x=10, gang 3). Picks: (x=5, gang 2) en (x=15, gang 1):

heen : depot → linkerkopgang 12 + naar gang 2 5 + pick op x=5 7 + doorlopen naar rechts 17 = 41 m terug: naar gang 1 5 + pick op x=15 7 + keren 7 + terug naar depotgang 10 + naar depot 12 = 41 m totaal = 82 m (keren was hier goedkoper dan doorlopen: 82 vs 92)
Demonstratierun op echte data (picklijst van 15 regels, vaste seed)
S-vorm 2.012 m · Grootste opening 1.544 m · Gecombineerd 1.616 m · Optimaal 1.064 m

Dat "Optimaal" hier wint komt vooral doordat het als enige de 32 doorsteken mag gebruiken — de drie heuristieken zijn klassiek gedefinieerd op kopgangen. Het verschil kwantificeert dus direct de waarde van de doorsteken.

Bron: js/engines/picking.js Tests: picking.test.mjs — volledigheid (elke pick precies 1×), axis-aligned paden, 82 m-narekening, optimaal ≤ s-vorm, grootste-opening-splitsing

6. Combitruck & dual cycling

Full-pallet werkmodel: een combitruck werkt taken strikt per gang af (minimaal gangwisselen). Per gang liggen twee instelbare punten: het drop-off punt (gepickte pallets) en het pick-up punt (inslagvoorraad).

Dual cycling (interleaving)

De besparing ontstaat door een inslagrit en een pickrit te koppelen: vol de gang in (inslag), leeg alleen het stukje tussen inslag- en picklocatie, vol terug (pick).

dual = |pickup − x_inslag| + |x_inslag − x_pick| + |x_pick − dropoff| enkel = 2·|pickup − x_inslag| + |pickup − dropoff| + 2·|dropoff − x_pick| koppel alléén als dual < enkel (de winstcheck per koppel; diepste taken worden eerst gekoppeld)
Narekenvoorbeeld (vastgelegd als test: 84 / 112 / 28)

Eén gang, drop-off x=1, pick-up x=3. Inslag naar x=18, pick op x=15. Aanrijden depot→gang 27 m, terug 25 m:

dual : 3→18 (15) + 18→15 (3) + 15→1 (14) = 32 m → totaal 27+32+25 = 84 m enkel: inslag 2×15 (30) + omrijden 2 + pick 2×14 (28) = 60 m → totaal 112 m besparing dual cycling = 28 m (= 2 × min(diepte_inslag, diepte_pick) bij gelijke punten)

De referentie "enkele cycli" gebruikt dezelfde gangvolgorde en aanrijroutes — alleen het werk ín de gang verschilt. De vergelijking meet dus zuiver het effect van dual cycling, niets anders.

Meerdere trucks & werkzones

  • Zones zijn vrij definieerbare gangbereiken (bv. zone A = gang 1–5) en per truck toewijsbaar.
  • Gang-integriteit: alle taken van één gang gaan altijd naar dezelfde truck — het per-gang-werkmodel blijft intact. Balancering gebeurt op taakaantal.
  • Taken in gangen die geen enkele truck mag bedienen worden niet stilletjes herverdeeld maar gerapporteerd als "niet uitgevoerd" — een bewust signaal dat de zonedekking niet klopt.
  • Doorlooptijd-KPI = tijd van de traagste truck (parallelle uitvoering), naast de totale rijmeters.
Demonstratierun op echte data (20 picks + 19 inslag, 16 gangen, vaste seed)
dual cycling 4.954 m vs enkele cycli 7.416 m → besparing 2.462 m (33,2%), 19 gekoppelde cycli

Schaduwscenario's (A/B-vergelijking van de inrichting)

Een scenario is een vastgelegde momentopname van de inrichting: drop-off/pick-up punten, doorsteken aan/uit, kopgangen, dwarsgangen, zones en truckaantal. Bij een scenariorun draaien alle scenario's op exact dezelfde takenlijst — alleen de inrichting verschilt. Het verschil in rijmeters en doorlooptijd is daardoor zuiver toe te schrijven aan de inrichtingswijziging, niet aan toeval in de taken.

vergelijking per scenario: totale rijafstand · doorlooptijd (= traagste truck) · onverdeelde taken eerlijkheid: zelfde taken, zelfde tijden/snelheden — alléén de ruimtelijke inrichting varieert

Visueel rijdt scenario 1 ("Huidig") ondoorzichtig mét pallets en stapels; schaduwscenario's rijden semi-transparant mee in hun eigen kleur (baken op het dak + bord S2·T1 enz.). De vergelijkingstabel markeert het snelste scenario en toont het verschil in tijd en meters t.o.v. Huidig.

Bron: js/engines/combitruck.js (simuleerScenario) Tests: combitruck.test.mjs — 84/112/28-narekening, drop-off-garantie per gang, gangvolgorde, zoneverdeling (6 tests), besparing ≥ 0, tijdmodel, scenario's (punten aan taakkant korter; doorsteek open korter; 2 trucks halveren doorlooptijd; identieke taken per scenario)

7. Wegzetlogica (orderpicker-variant)

De wegzetsimulatie wijst inkomende pallets toe aan lege locaties volgens een instelbare strategie en vergelijkt het resultaat altijd met willekeurig wegzetten op exact dezelfde palletlijst.

Strafpuntenmodel

Elke strategie is een optelsom van strafpunten + afstand als doorslag. Nieuwe klantregels zijn één extra strafterm — geen herontwerp.

score(locatie) = straf_verkeerde_ABC-band (2000) + straf_geen_golden_zone voor A (500) + straf_bulk/pick-schending (5000) + afstand depot→locatie kies de vrije locatie met de laagste score; elke locatie maximaal één keer

ABC-banden

Gangen worden op depotafstand verdeeld: de dichtstbijzijnde abcZoneA (25%) van de gangen = A-band, de volgende abcZoneB (35%) = B-band, de rest = C-band. Golden zone = instelbare verdiepingen (standaard 1–2).

Zonekwaliteitsscore

kwaliteit = (Σ punten / Σ max punten) × 100 punt per pallet: 1 als hij in zijn juiste ABC-band staat; A-pallets: +0,5 extra als golden zone (max 1,5)
Demonstratierun (12 pallets, vaste seed)
ABC-zone strategie: 380,8 m, kwaliteit 100% · willekeurig: 3.656,8 m, kwaliteit 35,3% besparing 89,6% — let op: dit vergelijkt met wíllekeurig wegzetten, de meest ongunstige referentie
Bron: js/engines/putaway.js Tests: putaway.test.mjs — A-pallets in A-band, golden zone, bulk/pick-splitsing, geen dubbele toewijzing, bezetting voor/na

8. Tijdmodellen

Elke tijdschatting is opgebouwd uit rijden/lopen + handelingstijden + heftijd. Geen verborgen factoren.

orderpicker : tijd = afstand / loopsnelheid + Σ (picktijd_per_regel + (verd−1) × verticale_tijd) combitruck : tijd = afstand / rijsnelheid + Σ handelingen, met per taak: pick = tijd_per_palletpick + (verd−1) × heftijd_per_niveau inslag = tijd_per_inslagpallet + (verd−1) × heftijd_per_niveau + tijd_drop/pickup per bezoek aan een drop-off/pick-up punt
Narekenvoorbeeld combitruck (vastgelegd als test: 109 s)
1 pick op verdieping 4, rijafstand 78 m, snelheid 2 m/s, picktijd 30 s, heftijd 10 s/niveau, droptijd 10 s tijd = 78/2 + 30 + 3×10 + 10 = 39 + 30 + 30 + 10 = 109 s

De 3D-animatie is een afspeling van ditzelfde tijdmodel: de animatieklok telt gesimuleerde seconden (rij-items = afstand/snelheid, pauze-items = handelingsduur). Visualisatie en gerapporteerde tijden kunnen daardoor per constructie niet van elkaar afwijken.

Tests: combitruck.test.mjs — "tijdmodel telt handling, heffen en drop/pickup mee" + "rijtijd + actieduur = berekende tijd"

9. Heatmap

De heatmap kleurt elke locatie op intensiteit 0–1, berekend uit de mutatiestroom en/of de voorraadmomentopname.

WeergaveRuwe waarde per locatie
Pickfrequentieaantal out-mutaties op die locatie
Wegzetfrequentieaantal in-mutaties
Verblijftijdvoorraadleeftijd in dagen (uit analysedata)
ABC-klassevaste schaal A=1,0 · B=0,62 · C=0,3 · deadstock=0,08
Gecombineerdpicks + wegzet + ABC-schaal
intensiteit = min(waarde / P95, 1) ^ gamma P95 = 95e percentiel van de niet-nulwaarden → één uitschieter drukt de kaart niet plat gamma = contrast (standaard 0,6); locaties zonder data krijgen de neutrale kleur

Tijdens de mutatie-replay wordt alleen geteld tot de huidige replaypositie — de heatmap "groeit" dus live en correct mee met de afgespeelde dagen.

Bron: js/engines/heatmap.js Tests: heatmap.test.mjs — bereik [0,1], ordening, dynamische update, kleurschaaleinden

10. Analyse-KPI's & what-if

Het analysepaneel is gebouwd op één centraal uitgangspunt: locaties zijn dynamisch per pallet. Een gepickte pallet wordt niet vanzelf vervangen door hetzelfde artikel. Daarom werkt geen enkele KPI met "de vaste locatie van een SKU".

10.1 Reiskosten van een locatie

reiskosten(locatie) = netwerkafstand(depot → locatie) + (verd − 1) × verticale_tijd × loopsnelheid

De tweede term rekent heftijd om naar meter-equivalenten zodat een snelle locatie op verdieping 5 niet ten onrechte "goedkoop" lijkt. Voorbeeld: verdieping 5, 8 s/niveau, 1,2 m/s → 4 × 8 × 1,2 = +38,4 m-equivalent.

10.2 Pickkosten van een SKU (dynamisch!)

kosten(SKU) = Σ over historische picklocaties ( picks_op_locatie × reiskosten(locatie) ) / Σ picks

Dit is de empirische voetafdruk van de huidige wegzetregels — gemeten uit de werkelijke mutaties, geen aanname. In de demodata wordt topartikel ID-2001 bijvoorbeeld over 189 verschillende locaties gepickt; precies daarom zou een "vaste locatie"-model hier onzin opleveren.

10.3 Slottingefficiëntiescore

score = (ideale reiskosten / werkelijke reiskosten) × 100 werkelijk = Σ picks(locatie) × reiskosten(locatie) ideaal = pickvolumes aflopend gekoppeld aan de goedkoopste locaties van het HELE warehouse — óók lege locaties tellen mee in het ideaal

Dat laatste is essentieel: als alle picks achterin gebeuren terwijl vóórin leegstaat, hoort de score laag te zijn. Een eerdere versie die alleen bezochte locaties meenam gaf een misleidende 99% en is daarom vervangen; de huidige score op de demodata is 38,4% — eerlijk, en het toont meteen het besparingspotentieel.

Test: analytics.test.mjs — "perfecte slotting geeft 100" én "lege goedkope locaties tellen mee in het ideaal"

10.4 What-if: wegzetzone van een SKU wijzigen

Omdat locaties dynamisch zijn, is het enige dat je werkelijk kunt sturen de wegzetzone. Het what-if-model:

verwachte kosten in doelzone = gemiddelde reiskosten van de VRÍJE locaties in die zone (daar landen nieuwe pallets — bewust conservatief, niet de allerbeste plek) Δ per pick = batchfactor × 2 × (verwacht − huidig) Δ per dag = picks_per_dag × Δ per pick Δ per jaar = Δ per dag × werkdagen (250)

De batchfactor (standaard 0,5) corrigeert dat één pick in een batchroute geen volledige eigen retourrit kost. Bij stuks-/enkelorderpicken zet je hem op 1,0. Hij schaalt alle besparingen lineair en staat expliciet bij elk resultaat vermeld.

Demonstratierun: ID-2001 (A-artikel, 31,5 picks/dag) naar zone A
huidige gewogen pickkosten: 173,1 m · verwacht in zone A (2.887 vrije locaties): 116,9 m Δ per pick = 0,5 × 2 × (116,9 − 173,1) = −56,2 m Δ per dag = 31,5 × −56,2 = −1.770 m/dag · per jaar ≈ −442.400 m

Inclusief capaciteitscheck: past de voetafdruk (aantal picklocaties) niet in de vrije ruimte van de doelzone, dan staat er een expliciete waarschuwing.

10.5 Herslottingadvies (top 10)

Zelfde rekenmodel als de what-if, maar capaciteitsbewust over meerdere SKUs: elke aanbeveling reserveert de voetafdruk van de SKU in de doelzone, zodat tien adviezen niet allemaal dezelfde "beste plek" claimen. Drempel: minimaal 5 m/dag besparing. Elke regel heeft de volledige onderbouwing als hover-tekst.

10.6 Congestie & pickpadtrend

  • Congestie: aantal mutaties per gang per uur (matrix) — toont knelpunten op piektijden. Directe telling, geen model.
  • Pickpadtrend: afstand tussen opeenvolgende picks per dag als proxy voor de gelopen route (de mutatiedata bevat geen rondenummers). Geschikt als trendindicator dag-op-dag, niet als absolute routelengte — zie §11.
Bron: js/engines/analytics.js Tests: analytics.test.mjs — 13 tests, o.a. gewogen pickkosten, zoneverwachting A < C, what-if-tekens en batchfactor-lineariteit, capaciteitsbewust advies

11. Aannames & beperkingen (eerlijkheidsparagraaf)

Wat het model bewust níet doet — essentieel voor een verdedigbaar klantgesprek.

Aanname / vereenvoudigingEffect & mitigatie
Trucks/pickers hinderen elkaar niet fysiek in een gangCongestie wordt apart geanalyseerd (gang×uur-matrix); wachttijden zitten niet in de tijdschatting
Pickpadtrend is een proxy (opeenvolgende picks)Alleen voor dag-op-dag-vergelijking gebruiken; met rondenummers in de export wordt dit exact
Batchfactor is een instelling, niet gemetenPer klant afstemmen op het pickproces (1,0 enkelorder, ~0,3–0,6 batch); met ordernummers in de data is hij meetbaar
Verwachte zonekosten = gemiddelde vrije locatieBewust conservatief (onderschat de besparing eerder dan overschat)
Inslagtaken in de demo zijn gegenereerdDe engine accepteert elke takenlijst — een echte inbound-lijst is direct aansluitbaar
Wegzet-vergelijking is t.o.v. wíllekeurigBij presentatie benoemen: 89,6% is t.o.v. de slechtst denkbare referentie
S-vorm/grootste-opening/gecombineerd gebruiken alleen kopgangenConform de klassieke definities; "Optimaal" gebruikt het volledige netwerk incl. doorsteken — het verschil kwantificeert de doorsteekwinst
250 werkdagen/jaar voor projectiesInstelbaar (Instellingen → Analyse)
Heftijd lineair per verdiepingInstelbaar per klant; werkelijke hefcurves zijn niet-lineair maar het verschil is klein t.o.v. rijtijden

12. Validatie & tests

85 geautomatiseerde tests dekken elke engine. De belangrijkste categorie zijn handmatig narekenbare gevallen: kleine voorbeelden waarvan de uitkomst op papier is uitgerekend en exact vastgelegd.

TestbestandDektVoorbeelden van vastgelegde waarheden
routing.test.mjs (12)Afstanden, paden, netwerk4+5+10=19 m; dwarsgang 15 m; paden nooit diagonaal; symmetrie; kopgang uitschakelen → 39 m
openingen.test.mjs (6)Doorsteekdetectieechte doorsteek 23↔22 op x 44–52 gevonden; vervalt bij hogere doorrijhoogte-eis
picking.test.mjs (7)4 pickalgoritmenS-vorm exact 82 m; elke pick precies één keer; optimaal ≤ s-vorm; splitsing grootste gat
putaway.test.mjs (10)WegzetregelsA-pallets in A-band; bulk vanaf niveau 3; geen dubbele toewijzing; bezetting +12 na 12 pallets
combitruck.test.mjs (17)Dual cycling, zones, tijd, scenario's84/112/28 m exact; 109 s exact; picks eindigen op drop-off; gang-integriteit; tijdlijn = engine-tijd; scenario's vergelijken identieke taken
kwaliteit.test.mjs (5)Projectafsprakenengines puur (geen UI-code); alle modules importeerbaar; elke parameter gedocumenteerd; documentatie vermeldt werkelijk testaantal; deploy = bron
heatmap.test.mjs (8)Intensiteiten, kleurschaalbereik [0,1]; drukste locatie het warmst; live-update verschuift waarden
analytics.test.mjs (13)KPI's, what-ifperfecte slotting = 100; lege locaties in ideaal; batchfactor lineair; advies capaciteitsbewust
mockdata.test.mjs (7)TestdataABC-volume 80/15/5 ±5%; deterministisch per seed

Zelf valideren

node --test "tests/*.test.mjs" → verwacht: 85 pass, 0 fail node tests/ui-testserver.mjs → open http://localhost:8124/tests/ui-test.html (klikt alle modules aan en logt de resultaten)

Daarnaast: alle steekproeven zijn seeded — een demonstratierun is dus exact reproduceerbaar, en wijzigingen in resultaten zijn altijd herleidbaar tot wijzigingen in data of parameters, nooit tot toeval.

13. Parameters

Geen enkele rekenwaarde is hardcoded: alles staat in js/config.js (CONFIG_SCHEMA), is instelbaar via de UI (sidebar → Instellingen, met uitleg per veld) en gedocumenteerd in KLANT_CONFIG.md. De belangrijkste:

ParameterStandaardWerkt door in
Loopsnelheid picker1,2 m/sTijden picksimulatie, verticale meter-equivalenten
Picktijd per orderregel12 sTijden picksimulatie
Rijsnelheid combitruck2,5 m/sAlle combitruck-tijden en de animatie
Handelingstijden combitruck30/30/10 sPick, inslag, drop/pickup-punt (+ heftijd 10 s/niveau)
Doorrijhoogte doorsteken3 niveausDoorsteekdetectie → routenetwerk → alle afstanden
ABC-zonebanden25% / 35%Wegzetregels, what-if, herslotting
Golden zoneverdieping 1–2Wegzetregels, herslotting
Batchfactor0,5Alle besparingen in what-if en herslotting (lineair)
Werkdagen per jaar250Jaarprojecties
Drop-off / pick-up punten, zones, doorsteek-schakelaarsper gangCombitruck — visueel instelbaar in 3D

Per-gang instellingen (punten, doorsteken aan/uit, zones, trucks) worden per browser bewaard in localStorage; de defaults staan in code en zijn per klantuitrol aanpasbaar volgens NABOUWGIDS.md.