@flowselections/logistiek-engine 1.0.34 → 1.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +24 -24
  2. package/dist-lib/components/FlowCanvas.d.ts +28 -0
  3. package/dist-lib/components/FlowCanvas.d.ts.map +1 -0
  4. package/dist-lib/components/FlowCanvas.js +429 -0
  5. package/dist-lib/components/FlowOrders.d.ts +8 -0
  6. package/dist-lib/components/FlowOrders.d.ts.map +1 -0
  7. package/dist-lib/components/FlowOrders.js +125 -0
  8. package/dist-lib/components/FlowPage.d.ts +2 -0
  9. package/dist-lib/components/FlowPage.d.ts.map +1 -0
  10. package/dist-lib/components/FlowPage.js +141 -0
  11. package/dist-lib/components/InklapbaarVenster.d.ts +9 -0
  12. package/dist-lib/components/InklapbaarVenster.d.ts.map +1 -0
  13. package/dist-lib/components/InklapbaarVenster.js +10 -0
  14. package/dist-lib/components/LogistiekEnginePage.d.ts.map +1 -1
  15. package/dist-lib/components/LogistiekEnginePage.js +9 -3
  16. package/dist-lib/components/LogistiekEngineQueuePage.d.ts +2 -0
  17. package/dist-lib/components/LogistiekEngineQueuePage.d.ts.map +1 -0
  18. package/dist-lib/components/LogistiekEngineQueuePage.js +11 -0
  19. package/dist-lib/components/NodeTracePanel.d.ts +11 -0
  20. package/dist-lib/components/NodeTracePanel.d.ts.map +1 -0
  21. package/dist-lib/components/NodeTracePanel.js +40 -0
  22. package/dist-lib/components/OrderJourneyBar.d.ts +9 -0
  23. package/dist-lib/components/OrderJourneyBar.d.ts.map +1 -0
  24. package/dist-lib/components/OrderJourneyBar.js +26 -0
  25. package/dist-lib/components/OrderLogboek.d.ts +10 -0
  26. package/dist-lib/components/OrderLogboek.d.ts.map +1 -0
  27. package/dist-lib/components/OrderLogboek.js +92 -0
  28. package/dist-lib/components/OrderStopBanner.d.ts +5 -0
  29. package/dist-lib/components/OrderStopBanner.d.ts.map +1 -0
  30. package/dist-lib/components/OrderStopBanner.js +22 -0
  31. package/dist-lib/components/OrderTraceDetails.d.ts +22 -0
  32. package/dist-lib/components/OrderTraceDetails.d.ts.map +1 -0
  33. package/dist-lib/components/OrderTraceDetails.js +87 -0
  34. package/dist-lib/components/RegiePage.d.ts.map +1 -1
  35. package/dist-lib/components/RegiePage.js +11 -69
  36. package/dist-lib/components/WerktijdenCard.d.ts +2 -0
  37. package/dist-lib/components/WerktijdenCard.d.ts.map +1 -0
  38. package/dist-lib/components/WerktijdenCard.js +37 -0
  39. package/dist-lib/components/WerkwijzeHerindelingCard.d.ts.map +1 -1
  40. package/dist-lib/components/WerkwijzeHerindelingCard.js +100 -6
  41. package/dist-lib/hooks/useLogisticsTrace.d.ts +78 -0
  42. package/dist-lib/hooks/useLogisticsTrace.d.ts.map +1 -0
  43. package/dist-lib/hooks/useLogisticsTrace.js +152 -0
  44. package/dist-lib/hooks/useOrderNodeTrace.d.ts +11 -0
  45. package/dist-lib/hooks/useOrderNodeTrace.d.ts.map +1 -0
  46. package/dist-lib/hooks/useOrderNodeTrace.js +26 -0
  47. package/dist-lib/hooks/useOrderTrace.d.ts +74 -0
  48. package/dist-lib/hooks/useOrderTrace.d.ts.map +1 -0
  49. package/dist-lib/hooks/useOrderTrace.js +134 -0
  50. package/dist-lib/hooks/useOrderVersies.d.ts +47 -0
  51. package/dist-lib/hooks/useOrderVersies.d.ts.map +1 -0
  52. package/dist-lib/hooks/useOrderVersies.js +180 -0
  53. package/dist-lib/hooks/useRuleEngine.d.ts +1 -0
  54. package/dist-lib/hooks/useRuleEngine.d.ts.map +1 -1
  55. package/dist-lib/hooks/useRuleEngine.js +1 -0
  56. package/dist-lib/hooks/useShippingNoteStatus.d.ts +29 -0
  57. package/dist-lib/hooks/useShippingNoteStatus.d.ts.map +1 -0
  58. package/dist-lib/hooks/useShippingNoteStatus.js +107 -0
  59. package/dist-lib/hooks/useWerktijden.d.ts +33 -0
  60. package/dist-lib/hooks/useWerktijden.d.ts.map +1 -0
  61. package/dist-lib/hooks/useWerktijden.js +88 -0
  62. package/dist-lib/hooks/useWerkwijzeStatus.d.ts +12 -1
  63. package/dist-lib/hooks/useWerkwijzeStatus.d.ts.map +1 -1
  64. package/dist-lib/hooks/useWerkwijzeStatus.js +60 -4
  65. package/dist-lib/index.d.ts +13 -0
  66. package/dist-lib/index.d.ts.map +1 -1
  67. package/dist-lib/index.js +13 -0
  68. package/dist-lib/integrations/supabase/auth-middleware.d.ts +1600 -54
  69. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  70. package/dist-lib/integrations/supabase/client.server.d.ts +1600 -54
  71. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  72. package/dist-lib/integrations/supabase/client.server.js +1 -1
  73. package/dist-lib/integrations/supabase/moduleClient.d.ts +1600 -54
  74. package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
  75. package/dist-lib/integrations/supabase/types.d.ts +1618 -50
  76. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  77. package/dist-lib/lib/cartPlanRequests.server.d.ts +1 -1
  78. package/dist-lib/lib/cartPlanRequests.server.d.ts.map +1 -1
  79. package/dist-lib/lib/cartPlanRequests.server.js +49 -8
  80. package/dist-lib/lib/floridayDocuments.functions.d.ts +4644 -6
  81. package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -1
  82. package/dist-lib/lib/floridayDocuments.functions.js +1 -1
  83. package/dist-lib/lib/floridayDocuments.server.d.ts +14 -0
  84. package/dist-lib/lib/floridayDocuments.server.d.ts.map +1 -1
  85. package/dist-lib/lib/floridayDocuments.server.js +58 -0
  86. package/dist-lib/lib/floridayGuard.server.d.ts +1 -1
  87. package/dist-lib/lib/floridayGuard.server.d.ts.map +1 -1
  88. package/dist-lib/lib/floridayGuard.server.js +6 -3
  89. package/dist-lib/lib/floridayPush.functions.d.ts +1600 -54
  90. package/dist-lib/lib/floridayPush.functions.d.ts.map +1 -1
  91. package/dist-lib/lib/floridayPush.functions.js +1 -1
  92. package/dist-lib/lib/flowGraph.d.ts +43 -0
  93. package/dist-lib/lib/flowGraph.d.ts.map +1 -0
  94. package/dist-lib/lib/flowGraph.js +153 -0
  95. package/dist-lib/lib/flowNodes.d.ts +23 -0
  96. package/dist-lib/lib/flowNodes.d.ts.map +1 -0
  97. package/dist-lib/lib/flowNodes.js +58 -0
  98. package/dist-lib/lib/flowRoute.d.ts +107 -0
  99. package/dist-lib/lib/flowRoute.d.ts.map +1 -0
  100. package/dist-lib/lib/flowRoute.js +280 -0
  101. package/dist-lib/lib/flowTree.d.ts +64 -0
  102. package/dist-lib/lib/flowTree.d.ts.map +1 -0
  103. package/dist-lib/lib/flowTree.js +519 -0
  104. package/dist-lib/lib/handlers/index.d.ts +1 -0
  105. package/dist-lib/lib/handlers/index.d.ts.map +1 -1
  106. package/dist-lib/lib/handlers/index.js +1 -0
  107. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts +3 -0
  108. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.d.ts.map +1 -0
  109. package/dist-lib/lib/handlers/logistics-shipping-note-now.server.js +100 -0
  110. package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
  111. package/dist-lib/lib/handlers/logistics-tick.server.js +97 -2
  112. package/dist-lib/lib/loadCarrierPlanner.d.ts +2 -0
  113. package/dist-lib/lib/loadCarrierPlanner.d.ts.map +1 -1
  114. package/dist-lib/lib/loadCarrierPlanner.js +18 -0
  115. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +7740 -10
  116. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -1
  117. package/dist-lib/lib/loadCarrierPlanning.functions.js +1 -1
  118. package/dist-lib/lib/loadCarrierPlanning.server.d.ts +9 -0
  119. package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
  120. package/dist-lib/lib/loadCarrierPlanning.server.js +44 -17
  121. package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -1
  122. package/dist-lib/lib/logisticsPlanner.js +14 -2
  123. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +3096 -4
  124. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -1
  125. package/dist-lib/lib/logisticsRecalcJob.functions.js +1 -1
  126. package/dist-lib/lib/logisticsRecalculate.functions.d.ts +1600 -54
  127. package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -1
  128. package/dist-lib/lib/logisticsRecalculate.functions.js +1 -1
  129. package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
  130. package/dist-lib/lib/modulePrompts.js +3459 -2677
  131. package/dist-lib/lib/nodeTrace.d.ts +61 -0
  132. package/dist-lib/lib/nodeTrace.d.ts.map +1 -0
  133. package/dist-lib/lib/nodeTrace.js +191 -0
  134. package/dist-lib/lib/pickQueueCleanup.server.d.ts +14 -0
  135. package/dist-lib/lib/pickQueueCleanup.server.d.ts.map +1 -0
  136. package/dist-lib/lib/pickQueueCleanup.server.js +80 -0
  137. package/dist-lib/lib/planQueue.server.d.ts.map +1 -1
  138. package/dist-lib/lib/planQueue.server.js +140 -0
  139. package/dist-lib/lib/ruleEngineImpact.d.ts.map +1 -1
  140. package/dist-lib/lib/ruleEngineImpact.js +11 -4
  141. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
  142. package/dist-lib/lib/ruleEngineSchema.js +50 -6
  143. package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -1
  144. package/dist-lib/lib/ruleEngineWizard.js +3 -1
  145. package/dist-lib/lib/shippingNoteQueue.server.d.ts +18 -0
  146. package/dist-lib/lib/shippingNoteQueue.server.d.ts.map +1 -0
  147. package/dist-lib/lib/shippingNoteQueue.server.js +304 -0
  148. package/dist-lib/lib/trace.server.d.ts +75 -0
  149. package/dist-lib/lib/trace.server.d.ts.map +1 -0
  150. package/dist-lib/lib/trace.server.js +75 -0
  151. package/dist-lib/lib/vakUitleg.d.ts +19 -0
  152. package/dist-lib/lib/vakUitleg.d.ts.map +1 -0
  153. package/dist-lib/lib/vakUitleg.js +132 -0
  154. package/package.json +26 -2
  155. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +0 -2
  156. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +0 -1
  157. package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +0 -41
  158. package/dist-lib/integrations/supabase/client.d.ts +0 -20293
  159. package/dist-lib/integrations/supabase/client.d.ts.map +0 -1
  160. package/dist-lib/integrations/supabase/client.js +0 -13
@@ -0,0 +1,280 @@
1
+ // ============================================================================
2
+ // src/lib/flowRoute.ts — de route van één herberekening (versie) van een order
3
+ // over de flowkaart
4
+ // ============================================================================
5
+ // Uit de logboekgegevens van één versie leiden we af tot welke stap de order
6
+ // is gekomen en waar hij eventueel is vastgelopen. Die informatie leggen we als
7
+ // laag over de flowkaart: de gelopen route wordt blauw, de rest licht, en het
8
+ // vastgelopen vakje krijgt een rode markering.
9
+ //
10
+ // Belangrijk: de kaart zelf blijft de actuele werkwijze. Welke keuze binnen een
11
+ // stap gold, komt uit de instellingen van nú; het logboek bewaart (nog) geen
12
+ // momentopname van de werkwijze per herberekening. Dat melden we in de kaart.
13
+ // ============================================================================
14
+ import { WIZARD_STEPS } from "./ruleEngineWizard";
15
+ import { FLOW_NODE, bronNodeVoor } from "./flowNodes";
16
+ import { vakUitleg } from "./vakUitleg";
17
+ const STEP_IDS = WIZARD_STEPS.map((s) => s.id);
18
+ const STAP = {
19
+ combineren: STEP_IDS[0] ?? "orders_combineren",
20
+ indeling: STEP_IDS[1] ?? "beladingindeling",
21
+ picken: STEP_IDS[2] ?? "picken",
22
+ drukte: STEP_IDS[3] ?? "drukte_vertraging",
23
+ stations: STEP_IDS[4] ?? "pickstations",
24
+ controle: STEP_IDS[5] ?? "controle",
25
+ };
26
+ export const REASON_LABEL = {
27
+ afmetingen_onbekend: "Afmetingen van fust/product onbekend",
28
+ kargrens_overschreden: "Kargrens overschreden (te veel lagen/karren)",
29
+ bufferdekking_onvolledig: "Buffer nog niet compleet: niet alle orders binnen",
30
+ werktijden_ontbreken: "Werktijden van de klant ontbreken",
31
+ fust_onbekend: "Fusttype onbekend",
32
+ geen_regels: "Order heeft geen regels",
33
+ };
34
+ export function redenTekst(code, error) {
35
+ const label = code ? REASON_LABEL[code] ?? code.replace(/_/g, " ") : null;
36
+ if (label && error && !error.includes(code ?? ""))
37
+ return `${label} — ${error}`;
38
+ return label ?? error ?? "Onbekende reden";
39
+ }
40
+ const AFGEROND = new Set(["verzonden", "gereed voor facturatie", "afgehandeld", "gefactureerd", "afgemeld"]);
41
+ /** Leidt uit één versie + de huidige stand van de order de gelopen route af. */
42
+ export function bepaalRoute(versie, order, carts, isLaatste) {
43
+ const bron = order?.orderSource ? bronNodeVoor(order.orderSource) : null;
44
+ const source = bron === FLOW_NODE.bronFloriday
45
+ ? "floriday"
46
+ : bron === FLOW_NODE.bronMail
47
+ ? "mail"
48
+ : bron === FLOW_NODE.bronActiemail
49
+ ? "actiemail"
50
+ : bron === FLOW_NODE.bronHandmatig
51
+ ? "handmatig"
52
+ : null;
53
+ const reached = [];
54
+ let stuck = null;
55
+ let busy = null;
56
+ let finished = false;
57
+ if (!versie) {
58
+ return {
59
+ source,
60
+ reached,
61
+ stuck: null,
62
+ busy: { stepId: STAP.combineren, reason: "Order is binnen, maar nog nooit ingedeeld" },
63
+ finished: false,
64
+ summary: "Nog geen herberekening bekend voor deze order.",
65
+ };
66
+ }
67
+ // 1. Ontvangen en combineren: zodra er een wachtrijrij is, is de order binnen.
68
+ reached.push(STAP.combineren);
69
+ // 2. Karindeling: de uitkomst van de planwachtrij.
70
+ const status = (versie.status ?? "pending").toLowerCase();
71
+ if (status === "pending") {
72
+ busy = { stepId: STAP.indeling, reason: "Wacht op de planronde" };
73
+ }
74
+ else if (status === "running") {
75
+ reached.push(STAP.indeling);
76
+ busy = { stepId: STAP.indeling, reason: "Karindeling wordt nu berekend" };
77
+ }
78
+ else if (status === "failed" || status === "geblokkeerd") {
79
+ reached.push(STAP.indeling);
80
+ stuck = {
81
+ stepId: STAP.indeling,
82
+ reason: (status === "geblokkeerd" ? "Geblokkeerd: " : "Mislukt: ") +
83
+ redenTekst(versie.reasonCode, versie.error ?? versie.lastError),
84
+ };
85
+ }
86
+ else {
87
+ reached.push(STAP.indeling);
88
+ }
89
+ if (!stuck && !busy) {
90
+ // 3–5. Picken, vrijgave en pickstations: pakbonnen/printopdrachten.
91
+ if (versie.printJobs > 0) {
92
+ reached.push(STAP.picken, STAP.drukte, STAP.stations);
93
+ if (versie.printFailed > 0 && versie.printFailed >= versie.printJobs) {
94
+ stuck = { stepId: STAP.stations, reason: "Printopdracht mislukt of geannuleerd" };
95
+ }
96
+ }
97
+ else if (versie.lastErrorStep && versie.errors > 0 && (versie.lastPhase ?? "").includes("verzendbrief")) {
98
+ reached.push(STAP.picken, STAP.drukte, STAP.stations);
99
+ stuck = { stepId: STAP.stations, reason: `Verzendbrief: ${versie.lastError ?? "fout"}` };
100
+ }
101
+ else {
102
+ reached.push(STAP.picken);
103
+ busy = { stepId: STAP.drukte, reason: "Ingedeeld; wacht op vrijgave/aanmeldmoment" };
104
+ }
105
+ const ship = (versie.shippingStatus ?? "").toLowerCase();
106
+ if (!stuck && (ship === "mislukt" || ship === "geblokkeerd")) {
107
+ stuck = { stepId: STAP.stations, reason: `Verzendbrief ${ship}${versie.lastError ? `: ${versie.lastError}` : ""}` };
108
+ }
109
+ // 6. Controle en afronding: alleen aantoonbaar voor de laatste versie
110
+ // (de karrenstand is een stand van nú).
111
+ if (!stuck && isLaatste && carts && carts.total > 0) {
112
+ if (carts.printed > 0) {
113
+ if (!reached.includes(STAP.stations))
114
+ reached.push(STAP.drukte, STAP.stations);
115
+ busy = null;
116
+ if (carts.controlled >= carts.total) {
117
+ reached.push(STAP.controle);
118
+ finished = true;
119
+ }
120
+ else {
121
+ reached.push(STAP.controle);
122
+ busy = {
123
+ stepId: STAP.controle,
124
+ reason: `${carts.controlled} van ${carts.total} karren gecontroleerd`,
125
+ };
126
+ }
127
+ }
128
+ }
129
+ if (isLaatste && order?.status && AFGEROND.has(order.status.toLowerCase())) {
130
+ if (!reached.includes(STAP.controle))
131
+ reached.push(STAP.drukte, STAP.stations, STAP.controle);
132
+ busy = null;
133
+ finished = true;
134
+ }
135
+ }
136
+ if (isLaatste && order?.cancelledAt) {
137
+ stuck = { stepId: stuck?.stepId ?? busy?.stepId ?? STAP.combineren, reason: "Order is geannuleerd" };
138
+ busy = null;
139
+ finished = false;
140
+ }
141
+ const uniek = [...new Set(reached)];
142
+ const summary = finished
143
+ ? "Route volledig doorlopen: order is gecontroleerd en afgemeld."
144
+ : stuck
145
+ ? `Vastgelopen bij "${stapLabel(stuck.stepId)}": ${stuck.reason}`
146
+ : busy
147
+ ? `Nu bij "${stapLabel(busy.stepId)}": ${busy.reason}`
148
+ : `Gekomen tot "${stapLabel(uniek[uniek.length - 1] ?? STAP.combineren)}".`;
149
+ return { source, reached: uniek, stuck, busy, finished, summary };
150
+ }
151
+ export function stapLabel(stepId) {
152
+ return WIZARD_STEPS.find((s) => s.id === stepId)?.label ?? stepId;
153
+ }
154
+ // ── Route over de kaart leggen ──────────────────────────────────────────────
155
+ /** Stapvolgorde-index van een knoop; -1 = vóór de eerste stap; 99 = einde. */
156
+ function stapIndex(node, byId) {
157
+ if (!node)
158
+ return -1;
159
+ if (node.id === "__eind")
160
+ return 99;
161
+ if (node.id.startsWith("__"))
162
+ return -1;
163
+ const m = /^(?:samen:)?stap:(.+)$/.exec(node.id);
164
+ if (m)
165
+ return STEP_IDS.indexOf(m[1]);
166
+ if (node.stepId)
167
+ return STEP_IDS.indexOf(node.stepId);
168
+ for (const a of [...node.ancestors].reverse()) {
169
+ const anc = byId.get(a);
170
+ if (anc?.stepId)
171
+ return STEP_IDS.indexOf(anc.stepId);
172
+ }
173
+ return -1;
174
+ }
175
+ /**
176
+ * Maakt een kopie van de kaart waarin alleen de gelopen route "active" is.
177
+ * Knopen/pijlen die de order (nog) niet heeft bereikt worden "possible".
178
+ *
179
+ * Zijn er echte gebeurtenissen per vakje (`groepen`), dan winnen die: de reis
180
+ * komt dan uit wat de Engine heeft vastgelegd. De heuristiek hieronder blijft
181
+ * de terugval voor oudere gebeurtenissen zonder vakje.
182
+ */
183
+ export function applyRoute(tree, route, groepen) {
184
+ const markers = new Map();
185
+ const nodes = Array.isArray(tree?.nodes) ? tree.nodes : [];
186
+ const edges = Array.isArray(tree?.edges) ? tree.edges : [];
187
+ if (!route)
188
+ return { tree: { nodes, edges }, markers };
189
+ const echt = groepen && groepen.size > 0 ? groepen : null;
190
+ const byId = new Map(nodes.map((n) => [n.id, n]));
191
+ const maxIdx = route.reached.reduce((m, id) => Math.max(m, STEP_IDS.indexOf(id)), -1);
192
+ const bereikt = (idx) => (idx === 99 ? route.finished : idx <= maxIdx);
193
+ // Het bronvakje van deze order (Floriday, mail, actiemail of handmatig).
194
+ const bronNode = route.source === "floriday"
195
+ ? FLOW_NODE.bronFloriday
196
+ : route.source === "mail"
197
+ ? FLOW_NODE.bronMail
198
+ : route.source === "actiemail"
199
+ ? FLOW_NODE.bronActiemail
200
+ : route.source === "handmatig"
201
+ ? FLOW_NODE.bronHandmatig
202
+ : null;
203
+ const bronTak = (id) => id === FLOW_NODE.bronFloriday ||
204
+ id === FLOW_NODE.bronMail ||
205
+ id === FLOW_NODE.bronActiemail ||
206
+ id === FLOW_NODE.bronHandmatig;
207
+ /** Hoort dit bronvakje (of de samenvoegstap erna) bij deze order? */
208
+ const bronOk = (id) => {
209
+ if (bronTak(id))
210
+ return id === bronNode;
211
+ if (id === FLOW_NODE.samenvoegen)
212
+ return bronNode === FLOW_NODE.bronFloriday;
213
+ return true;
214
+ };
215
+ /** Ligt dit vakje op de reis? Echte gebeurtenissen gaan vóór de heuristiek. */
216
+ const opReis = (n) => {
217
+ if (bronTak(n.id) || n.id === FLOW_NODE.samenvoegen) {
218
+ return bronOk(n.id) && (echt ? true : bereikt(-1));
219
+ }
220
+ if (echt) {
221
+ if (echt.has(n.id))
222
+ return true;
223
+ if (n.ancestors.some((a) => echt.has(a)))
224
+ return true;
225
+ if (n.stepId && echt.has(`stap:${n.stepId}`))
226
+ return true;
227
+ if (n.id === "__start" || n.id === "__bron" || n.id === "__bron_merge")
228
+ return true;
229
+ return false;
230
+ }
231
+ return bereikt(stapIndex(n, byId));
232
+ };
233
+ const demote = (s) => (s === "active" ? "possible" : s);
234
+ const newNodes = nodes.map((n) => {
235
+ const ok = n.state === "active" && opReis(n);
236
+ return ok ? { ...n, route: true } : { ...n, state: demote(n.state), route: false };
237
+ });
238
+ const nodeState = new Map(newNodes.map((n) => [n.id, n.state]));
239
+ const newEdges = edges.map((e) => {
240
+ if (e.state !== "active")
241
+ return e;
242
+ const to = byId.get(e.to);
243
+ const from = byId.get(e.from);
244
+ const ok = nodeState.get(e.from) === "active" &&
245
+ nodeState.get(e.to) === "active" &&
246
+ (echt
247
+ ? !!(from && to && opReis(from) && opReis(to))
248
+ : bereikt(Math.max(stapIndex(from, byId), stapIndex(to, byId)))) &&
249
+ bronOk(e.from) &&
250
+ bronOk(e.to);
251
+ return ok ? { ...e, route: true } : { ...e, state: "possible", route: false };
252
+ });
253
+ if (echt) {
254
+ for (const g of echt.values()) {
255
+ const kind = g.status === "mislukt" ? "stuck" : g.status === "wachtend" || g.status === "waarschuwing" ? "busy" : "done";
256
+ const uitleg = vakUitleg(g);
257
+ markers.set(g.nodeId, {
258
+ kind,
259
+ text: uitleg.beslissing,
260
+ beslissing: uitleg.beslissing,
261
+ waarom: uitleg.waarom,
262
+ feiten: uitleg.feiten,
263
+ at: g.laatste,
264
+ durationMs: g.duurMs,
265
+ count: g.aantal,
266
+ attempts: g.pogingen,
267
+ errorClass: g.errorClass,
268
+ nextStep: g.volgendeStap,
269
+ });
270
+ }
271
+ return { tree: { nodes: newNodes, edges: newEdges }, markers };
272
+ }
273
+ if (route.stuck)
274
+ markers.set(`stap:${route.stuck.stepId}`, { kind: "stuck", text: route.stuck.reason });
275
+ else if (route.busy)
276
+ markers.set(`stap:${route.busy.stepId}`, { kind: "busy", text: route.busy.reason });
277
+ if (route.finished)
278
+ markers.set("__eind", { kind: "done", text: "Afgehandeld" });
279
+ return { tree: { nodes: newNodes, edges: newEdges }, markers };
280
+ }
@@ -0,0 +1,64 @@
1
+ import { type RuleEngineSettings, type RuleField } from "./ruleEngineSchema";
2
+ export type FlowState = "active" | "possible" | "disabled";
3
+ export type TreeNodeKind = "start" | "end" | "source" | "step" | "decision" | "setting" | "option" | "merge";
4
+ export interface TreeOption {
5
+ value: string;
6
+ label: string;
7
+ }
8
+ export interface TreeNode {
9
+ id: string;
10
+ kind: TreeNodeKind;
11
+ label: string;
12
+ sublabel?: string;
13
+ state: FlowState;
14
+ /** Wizardstap waar deze knoop bij hoort (voor het zijpaneel). */
15
+ stepId?: string;
16
+ storeId?: string;
17
+ fieldKey?: string;
18
+ /** Alleen bij beslissingen: alle keuzes. */
19
+ options?: TreeOption[];
20
+ currentValue?: string;
21
+ isBoolean?: boolean;
22
+ /** Alleen bij beslissingen: de samenkomst-knoop van deze beslissing. */
23
+ mergeId?: string;
24
+ /** Beslissingen waar deze knoop onder hangt (voor inklappen). */
25
+ ancestors: string[];
26
+ help: string[];
27
+ /** Alleen bij instellingenblokken: één regel per instelling. */
28
+ lines?: string[];
29
+ /** Veldsleutels die in dit vakje bewerkt kunnen worden (dubbelklik). */
30
+ fieldKeys?: string[];
31
+ /** Ligt op de gelopen route van een gekozen order (blauwe lijn). */
32
+ route?: boolean;
33
+ w: number;
34
+ h: number;
35
+ }
36
+ export interface TreeEdge {
37
+ id: string;
38
+ from: string;
39
+ to: string;
40
+ label?: string;
41
+ state: FlowState;
42
+ /** flow = de route; ref = verwijzing naar een keuze uit een andere stap. */
43
+ kind: "flow" | "ref";
44
+ ancestors: string[];
45
+ /** Ligt op de gelopen route van een gekozen order (blauwe lijn). */
46
+ route?: boolean;
47
+ }
48
+ export interface FlowTree {
49
+ nodes: TreeNode[];
50
+ edges: TreeEdge[];
51
+ }
52
+ export declare const NODE_SIZE: Record<TreeNodeKind, {
53
+ w: number;
54
+ h: number;
55
+ }>;
56
+ /**
57
+ * Zoekt de schemavelden op die bij een vakje horen. Gebruikt dezelfde
58
+ * WIZARD_STEPS als het instelscherm, zodat er geen tweede definitie ontstaat.
59
+ */
60
+ export declare function fieldsFor(storeId?: string, keys?: string[]): RuleField[];
61
+ export declare function valueText(field: RuleField, value: unknown): string;
62
+ /** Bouwt de complete beslisboom van binnenkomst tot afgehandelde order. */
63
+ export declare function buildFlowTree(settings: RuleEngineSettings): FlowTree;
64
+ //# sourceMappingURL=flowTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowTree.d.ts","sourceRoot":"","sources":["../../src/lib/flowTree.ts"],"names":[],"mappings":"AAWA,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAC;AAG5B,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAE3D,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,UAAU,GACV,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CASpE,CAAC;AAwCF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAcxE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CA0BlE;AA6BD,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,kBAAkB,GAAG,QAAQ,CA+NpE"}