@flowselections/logistiek-engine 1.0.110 → 1.0.112

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 (34) hide show
  1. package/dist-lib/components/MinuutrondeCard.d.ts.map +1 -1
  2. package/dist-lib/components/MinuutrondeCard.js +9 -1
  3. package/dist-lib/hooks/useShellAdres.d.ts +20 -0
  4. package/dist-lib/hooks/useShellAdres.d.ts.map +1 -0
  5. package/dist-lib/hooks/useShellAdres.js +60 -0
  6. package/dist-lib/index.d.ts +2 -0
  7. package/dist-lib/index.d.ts.map +1 -1
  8. package/dist-lib/index.js +2 -0
  9. package/dist-lib/integrations/supabase/client.server.d.ts +2 -32181
  10. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  11. package/dist-lib/integrations/supabase/moduleClient.d.ts +1 -32181
  12. package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
  13. package/dist-lib/integrations/supabase/types.d.ts +1317 -4
  14. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  15. package/dist-lib/lib/handlers/index.d.ts +1 -0
  16. package/dist-lib/lib/handlers/index.d.ts.map +1 -1
  17. package/dist-lib/lib/handlers/index.js +1 -0
  18. package/dist-lib/lib/handlers/logistics-ping.server.d.ts +4 -0
  19. package/dist-lib/lib/handlers/logistics-ping.server.d.ts.map +1 -0
  20. package/dist-lib/lib/handlers/logistics-ping.server.js +28 -0
  21. package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
  22. package/dist-lib/lib/handlers/logistics-tick.server.js +2 -1
  23. package/dist-lib/lib/modulePrompts.d.ts +2 -0
  24. package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
  25. package/dist-lib/lib/modulePrompts.js +72 -1
  26. package/dist-lib/lib/moduleVersion.d.ts +1 -1
  27. package/dist-lib/lib/moduleVersion.js +1 -1
  28. package/dist-lib/lib/shellAdres.d.ts +15 -0
  29. package/dist-lib/lib/shellAdres.d.ts.map +1 -0
  30. package/dist-lib/lib/shellAdres.functions.d.ts +15 -0
  31. package/dist-lib/lib/shellAdres.functions.d.ts.map +1 -0
  32. package/dist-lib/lib/shellAdres.functions.js +41 -0
  33. package/dist-lib/lib/shellAdres.js +50 -0
  34. package/package.json +13 -3
@@ -1,3 +1,4 @@
1
1
  export { handleLogisticsTick } from "./logistics-tick.server.js";
2
2
  export { handleShippingNoteNow } from "./logistics-shipping-note-now.server.js";
3
+ export { handleLogisticsPing } from "./logistics-ping.server.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -3,3 +3,4 @@
3
3
  // ============================================================================
4
4
  export { handleLogisticsTick } from "./logistics-tick.server.js";
5
5
  export { handleShippingNoteNow } from "./logistics-shipping-note-now.server.js";
6
+ export { handleLogisticsPing } from "./logistics-ping.server.js";
@@ -0,0 +1,4 @@
1
+ export declare function handleLogisticsPing(request: Request, opts?: {
2
+ moduleProject?: boolean;
3
+ }): Promise<Response>;
4
+ //# sourceMappingURL=logistics-ping.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logistics-ping.server.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/logistics-ping.server.ts"],"names":[],"mappings":"AAiBA,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,QAAQ,CAAC,CAiBnB"}
@@ -0,0 +1,28 @@
1
+ // ============================================================================
2
+ // src/lib/handlers/logistics-ping.server.ts — testroute "bedient de Shell mij?"
3
+ // ============================================================================
4
+ // /api/public/hooks/logistics-ping. Doet niets in de database. Geeft altijd een
5
+ // eigen, herkenbaar antwoord (engine = "logistiek-engine"): 200 met geldige
6
+ // sleutel, 401 zonder. Zo is een 404 of websitepagina altijd te onderscheiden.
7
+ // Sleutel komt uit de omgeving (fail closed: ontbreekt hij, dan 401).
8
+ // ============================================================================
9
+ import { engineIdent } from "./logistics-tick.server.js";
10
+ const CORS_HEADERS = {
11
+ "Access-Control-Allow-Origin": "*",
12
+ "Access-Control-Allow-Headers": "apikey, authorization, content-type",
13
+ "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
14
+ };
15
+ export async function handleLogisticsPing(request, opts) {
16
+ if (request.method === "OPTIONS") {
17
+ return new Response(null, { status: 204, headers: CORS_HEADERS });
18
+ }
19
+ const ident = engineIdent(opts);
20
+ const apikey = request.headers.get("apikey") ??
21
+ request.headers.get("authorization")?.replace(/^Bearer /i, "") ??
22
+ "";
23
+ const expected = (process.env["SUPABASE_PUBLISHABLE_KEY"] ?? process.env["SUPABASE_ANON_KEY"] ?? "").replace(/^["']|["']$/g, "");
24
+ if (!expected || apikey !== expected) {
25
+ return Response.json({ ...ident, ok: false, error: "Unauthorized" }, { status: 401, headers: CORS_HEADERS });
26
+ }
27
+ return Response.json({ ...ident, ok: true, ping: true }, { status: 200, headers: CORS_HEADERS });
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"logistics-tick.server.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/logistics-tick.server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE;;;;EAE7D;AAQD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,QAAQ,CAAC,CA4EnB;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
1
+ {"version":3,"file":"logistics-tick.server.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/logistics-tick.server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE;;;;EAE7D;AAQD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,QAAQ,CAAC,CA6EnB;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
@@ -31,7 +31,8 @@ export async function handleLogisticsTick(request, supabase, opts) {
31
31
  process.env["SUPABASE_ANON_KEY"] ??
32
32
  "").replace(/^["']|["']$/g, "");
33
33
  if (!expected || apikey !== expected) {
34
- return new Response(JSON.stringify({ error: "Unauthorized" }), {
34
+ // Eigen, herkenbare weigering: de Shell-adrescontrole telt dit als "route aanwezig".
35
+ return new Response(JSON.stringify({ ...ident, ok: false, error: "Unauthorized" }), {
35
36
  status: 401,
36
37
  headers: { "Content-Type": "application/json", ...CORS_HEADERS },
37
38
  });
@@ -27,6 +27,8 @@ export interface ModulePromptRevision {
27
27
  summary: string;
28
28
  /** Het gedeelde contract meesturen (alleen bij de eerste prompt). */
29
29
  withSharedContract?: boolean;
30
+ /** De module heeft deze prompt uitgevoerd; de tekst blijft ongewijzigd staan. */
31
+ resolved?: boolean;
30
32
  /** De inhoud van de prompt. */
31
33
  body: string;
32
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"modulePrompts.d.ts","sourceRoot":"","sources":["../../src/lib/modulePrompts.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;CAIvB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAm1ID,eAAO,MAAM,cAAc,EAAE,YAAY,EAUL,CAAC;AAErC,gEAAgE;AAChE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,oBAAoB,GAC7B,MAAM,CAeR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,IAAI,MAAM,CAiB9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAIR"}
1
+ {"version":3,"file":"modulePrompts.d.ts","sourceRoot":"","sources":["../../src/lib/modulePrompts.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;CAIvB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAy5ID,eAAO,MAAM,cAAc,EAAE,YAAY,EAUL,CAAC;AAErC,gEAAgE;AAChE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,oBAAoB,GAC7B,MAAM,CAmBR;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,IAAI,MAAM,CAiB9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAIR"}
@@ -3794,6 +3794,74 @@ CONTROLELIJST
3794
3794
  [ ] Onbekende actie wordt geweigerd, niet toegestaan.
3795
3795
  [ ] Geen URL's, sleutels, project-refs, klantnamen of vaste id's in code.`,
3796
3796
  },
3797
+ {
3798
+ number: 6,
3799
+ title: "Bestaande voorraadsleutel ook zonder Floriday-koppeling teruggeven",
3800
+ date: "2026-10-08",
3801
+ withSharedContract: false,
3802
+ resolved: true,
3803
+ summary: "ensure_trade_item_stock_row_key geeft nu NULL zonder actieve Floriday-koppeling, ook als de rij al bestaat. Geef dan de bestaande canonieke sleutel terug.",
3804
+ body: `WAAROM
3805
+ In een shell zonder actieve Floriday-koppeling geeft
3806
+ public.ensure_trade_item_stock_row_key(p_key) altijd NULL, omdat de controle op
3807
+ de koppeling vóór het opzoeken staat. De reserveringsherberekening van de Engine
3808
+ kan dan geen enkele sleutel bepalen; zonder extra opvang zou de reservering daar
3809
+ nooit worden berekend (risico op oververkoop). De Engine vangt het nu op met een
3810
+ alleen-lezende terugval, maar de juiste plek is deze functie.
3811
+
3812
+ WAT JE AANPAST (alleen in de Voorraad-module)
3813
+ 1. Bepaal eerst de canonieke sleutel (zoals nu).
3814
+ 2. Bestaat er al een rij met die sleutel, geef de sleutel terug — ook zonder
3815
+ actieve koppeling.
3816
+ 3. Alleen als er een NIEUWE rij nodig is en er geen koppeling is: NULL
3817
+ teruggeven (geen rij aanmaken, geen terugvalwaarde verzinnen).
3818
+ Naam, parameters en returntype blijven exact gelijk.
3819
+
3820
+ CONTROLELIJST
3821
+ [ ] Zonder koppeling: bestaande sleutel komt terug, er wordt niets ingevoegd.
3822
+ [ ] Zonder koppeling en zonder rij: NULL, geen rij.
3823
+ [ ] Met koppeling: gedrag ongewijzigd.
3824
+ [ ] Fysiek, minimum en inkomend worden nooit geraakt.
3825
+ [ ] Geen URL's, sleutels, project-refs, klantnamen of vaste id's in code of migratie.`,
3826
+ },
3827
+ {
3828
+ number: 7,
3829
+ title: "Afboeken van sets en groepen op onderdelen en leden",
3830
+ date: "2026-10-09",
3831
+ withSharedContract: false,
3832
+ summary: "Boek bij levering af op dezelfde onderdelen en leden als de reservering, via logistics_order_line_allocation, met change_source op elke update.",
3833
+ body: `WAAROM
3834
+ De Engine reserveert sets nu op hun onderdelen en groepen op hun leden (nooit op
3835
+ de set of de groepssleutel). De afboekfuncties zijn van de Voorraad-module en
3836
+ boeken nog af op het bestelde artikel (karrencontrole) of zonder sets
3837
+ (statuswissel). Dan klopt de voorraad na levering niet.
3838
+
3839
+ Let op: de karrencontrole (trg_cart_session_consume_fn) heeft nu GEEN controle
3840
+ op dubbel afboeken. Elke afgeronde karsessie boekt alle regels van de order
3841
+ opnieuw af.
3842
+
3843
+ WAT JE AANPAST (alleen in de Voorraad-module)
3844
+ 1. In trg_orders_consume_on_complete_fn en trg_cart_session_consume_fn: per
3845
+ orderregel de rijen uit public.logistics_order_line_allocation(order_item_id)
3846
+ halen en per rij apply_stock_consumption(trade_item_key, qty, ...) aanroepen.
3847
+ Rijen met source = 'error' niet afboeken, wel vastleggen (consumption_blocked).
3848
+ 2. Eén controle op dubbel afboeken per orderregel in BEIDE triggers (de
3849
+ karrencontrole heeft die nu niet).
3850
+ 3. apply_stock_consumption: change_source in dezelfde update zetten
3851
+ (ORDER_DELIVERY, of FLORIDAY_ORDER voor Floriday-orders).
3852
+ 4. Zet vóór elke update set_config('stock.change_source', '<bron>', true),
3853
+ zodat de logtrigger de bron leest.
3854
+ 5. Structuur niet zelf uitklappen; de Engine levert onderdelen en leden.
3855
+
3856
+ CONTROLELIJST
3857
+ [ ] Set van 2x X + 1x groep, levering 3: X -6, gekozen lid -3, set 0.
3858
+ [ ] Groep: dezelfde leden als de reservering, groepssleutel nooit geraakt.
3859
+ [ ] Tweede keer afboeken doet niets.
3860
+ [ ] Een tweede afgeronde karsessie voor dezelfde order boekt niets af.
3861
+ [ ] Elke update heeft een change_source.
3862
+ [ ] Test met synthetische artikelen in een teruggedraaide transactie.
3863
+ [ ] Geen URL's, sleutels, project-refs, klantnamen of vaste id's in code of migratie.`,
3864
+ },
3797
3865
  ],
3798
3866
  },
3799
3867
  klanten: {
@@ -4321,10 +4389,13 @@ export function buildRevisionPrompt(prompt, revision) {
4321
4389
  ? `\n## Gedeeld contract\n\n${sharedBlock(prompt.moduleKey)}\n`
4322
4390
  : `\n(Deze prompt is een aanvulling. Het gedeelde contract uit koppelprompt 1 blijft
4323
4391
  onverkort gelden — niets terugdraaien.)\n`;
4392
+ const resolvedNote = revision.resolved
4393
+ ? `(AFGEHANDELD — uitgevoerd door de module op ${revision.date}; blijft geldig, niets terugdraaien.)\n`
4394
+ : "";
4324
4395
  return `# Koppelprompt ${revision.number} — ${prompt.label}
4325
4396
  ## ${revision.title} (${revision.date})
4326
4397
 
4327
- ${revision.summary}
4398
+ ${resolvedNote}${revision.summary}
4328
4399
  ${shared}
4329
4400
  ## Wat deze module moet doen
4330
4401
 
@@ -1,2 +1,2 @@
1
- export declare const MODULE_VERSION = "1.0.110";
1
+ export declare const MODULE_VERSION = "1.0.112";
2
2
  //# sourceMappingURL=moduleVersion.d.ts.map
@@ -1,2 +1,2 @@
1
1
  // Automatisch gegenereerd door prebuild:lib; niet handmatig aanpassen.
2
- export const MODULE_VERSION = "1.0.110";
2
+ export const MODULE_VERSION = "1.0.112";
@@ -0,0 +1,15 @@
1
+ export declare const SHELL_ADRES_STATUSSEN: readonly ["wachtend", "geslaagd", "al_actueel", "shell_adres_onbekend", "sleutel_ontbreekt", "route_ontbreekt", "oud_adres_geweigerd"];
2
+ export type ShellAdresStatus = (typeof SHELL_ADRES_STATUSSEN)[number];
3
+ /** Gedeelde sleutel in module_runtime_config; eigenaar: Floriday-authenticatiemodule. */
4
+ export declare const SHELL_BASE_URL_KEY = "shell_base_url";
5
+ export declare const LOGISTICS_PING_PATH = "/api/public/hooks/logistics-ping";
6
+ export declare const SHELL_ADRES_TEKST: Record<ShellAdresStatus, string>;
7
+ export declare function isShellAdresStatus(v: unknown): v is ShellAdresStatus;
8
+ /**
9
+ * Telt een antwoord als "eigen antwoord of weigering van de Engine"?
10
+ * Zelfde regel als in logistics_base_url_checks_resolve(): status 200 of 401
11
+ * én JSON met engine = "logistiek-engine". 404, HTML, time-out of een ander
12
+ * JSON-antwoord telt niet.
13
+ */
14
+ export declare function isEngineAntwoord(status: number | null | undefined, body: string | null | undefined): boolean;
15
+ //# sourceMappingURL=shellAdres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellAdres.d.ts","sourceRoot":"","sources":["../../src/lib/shellAdres.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,qBAAqB,wIAQxB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AACnD,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AAEtE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAQ9D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,gBAAgB,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAS5G"}
@@ -0,0 +1,15 @@
1
+ export declare const getShellAdresStand: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, undefined, undefined, undefined, undefined>, import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
2
+ supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
3
+ userId: string;
4
+ claims: import("@supabase/auth-js").User;
5
+ }, undefined, undefined, undefined>], undefined, Promise<{
6
+ json: string;
7
+ }>>;
8
+ export declare const startShellAdresControle: import("@tanstack/start-client-core").OptionalFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, undefined, undefined, undefined, undefined>, import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
9
+ supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
10
+ userId: string;
11
+ claims: import("@supabase/auth-js").User;
12
+ }, undefined, undefined, undefined>], undefined, Promise<{
13
+ status: string;
14
+ }>>;
15
+ //# sourceMappingURL=shellAdres.functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellAdres.functions.d.ts","sourceRoot":"","sources":["../../src/lib/shellAdres.functions.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,kBAAkB;;;;;UAEM,MAAM;GAKvC,CAAC;AAEL,eAAO,MAAM,uBAAuB;;;;;YAEc,MAAM;GAUpD,CAAC"}
@@ -0,0 +1,41 @@
1
+ // ============================================================================
2
+ // src/lib/shellAdres.functions.ts — knop "Shell-adres controleren" + stand
3
+ // ============================================================================
4
+ // Rol wordt eerst gecontroleerd als de gebruiker zelf (admin, superadmin of
5
+ // developer); pas daarna roept de server de databasefunctie aan.
6
+ // ============================================================================
7
+ import { createServerFn } from "@tanstack/react-start";
8
+ import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware.js";
9
+ import { readableServerErrors } from "./readableServerErrors.js";
10
+ const ROLLEN = ["admin", "superadmin", "developer"];
11
+ async function magBeheren(sb, userId) {
12
+ for (const rol of ROLLEN) {
13
+ const { data, error } = await sb.rpc("has_role", { _user_id: userId, _role: rol });
14
+ if (!error && data === true)
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+ export const getShellAdresStand = createServerFn({ method: "GET" })
20
+ .middleware([readableServerErrors, requireSupabaseAuth])
21
+ .handler(async () => {
22
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
23
+ const { data, error } = await supabaseAdmin.rpc("logistics_base_url_check_status");
24
+ if (error)
25
+ throw new Error(error.message);
26
+ return { json: JSON.stringify(data ?? {}) };
27
+ });
28
+ export const startShellAdresControle = createServerFn({ method: "POST" })
29
+ .middleware([readableServerErrors, requireSupabaseAuth])
30
+ .handler(async ({ context }) => {
31
+ const { supabase, userId } = context;
32
+ if (!(await magBeheren(supabase, userId))) {
33
+ throw new Error("Alleen admin, superadmin of developer mag het Shell-adres controleren");
34
+ }
35
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
36
+ const { data, error } = await supabaseAdmin.rpc("logistics_tick_base_url_check");
37
+ if (error)
38
+ throw new Error(error.message);
39
+ const status = data?.status;
40
+ return { status: typeof status === "string" ? status : "onbekend" };
41
+ });
@@ -0,0 +1,50 @@
1
+ // ============================================================================
2
+ // src/lib/shellAdres.ts — controle van het Shell-adres voor de minuutronde
3
+ // ============================================================================
4
+ // Vastgelegde, toegestane waarden (gelijk aan de CHECK in de database,
5
+ // tabel logistics_base_url_checks). Nieuwe waarde? Eerst hier én in het
6
+ // contractdocument vastleggen, dan pas in een migratie.
7
+ // ============================================================================
8
+ export const SHELL_ADRES_STATUSSEN = [
9
+ "wachtend",
10
+ "geslaagd",
11
+ "al_actueel",
12
+ "shell_adres_onbekend",
13
+ "sleutel_ontbreekt",
14
+ "route_ontbreekt",
15
+ "oud_adres_geweigerd",
16
+ ];
17
+ /** Gedeelde sleutel in module_runtime_config; eigenaar: Floriday-authenticatiemodule. */
18
+ export const SHELL_BASE_URL_KEY = "shell_base_url";
19
+ export const LOGISTICS_PING_PATH = "/api/public/hooks/logistics-ping";
20
+ export const SHELL_ADRES_TEKST = {
21
+ wachtend: "Controle loopt, wacht op antwoord",
22
+ geslaagd: "Overgestapt naar het Shell-adres",
23
+ al_actueel: "Het adres wijst al naar de Shell",
24
+ shell_adres_onbekend: "Shell-adres onbekend",
25
+ sleutel_ontbreekt: "Sleutel voor de minuutronde ontbreekt (logistics_tick_apikey)",
26
+ route_ontbreekt: "Route ontbreekt in de Shell, module opnieuw uitbrengen en installeren",
27
+ oud_adres_geweigerd: "Shell-adres is een eerder gebruikt adres; niet teruggezet",
28
+ };
29
+ export function isShellAdresStatus(v) {
30
+ return typeof v === "string" && SHELL_ADRES_STATUSSEN.includes(v);
31
+ }
32
+ /**
33
+ * Telt een antwoord als "eigen antwoord of weigering van de Engine"?
34
+ * Zelfde regel als in logistics_base_url_checks_resolve(): status 200 of 401
35
+ * én JSON met engine = "logistiek-engine". 404, HTML, time-out of een ander
36
+ * JSON-antwoord telt niet.
37
+ */
38
+ export function isEngineAntwoord(status, body) {
39
+ if (status !== 200 && status !== 401)
40
+ return false;
41
+ if (!body)
42
+ return false;
43
+ try {
44
+ const j = JSON.parse(body);
45
+ return !!j && typeof j === "object" && j["engine"] === "logistiek-engine";
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/logistiek-engine",
3
- "version": "1.0.110",
3
+ "version": "1.0.112",
4
4
  "flowselections": {
5
5
  "moduleId": "logistiek-engine",
6
6
  "pages": [
@@ -67,6 +67,16 @@
67
67
  "POST",
68
68
  "OPTIONS"
69
69
  ]
70
+ },
71
+ {
72
+ "routePath": "/api/public/hooks/logistics-ping",
73
+ "import": "@flowselections/logistiek-engine/hooks",
74
+ "handler": "handleLogisticsPing",
75
+ "methods": [
76
+ "POST",
77
+ "GET",
78
+ "OPTIONS"
79
+ ]
70
80
  }
71
81
  ]
72
82
  },
@@ -123,8 +133,8 @@
123
133
  "devDependencies": {
124
134
  "@cloudflare/vite-plugin": "^1.25.5",
125
135
  "@eslint/js": "^9.32.0",
126
- "@flowselections/core": "1.0.28",
127
- "@lovable.dev/vite-tanstack-config": "2.23.1",
136
+ "@flowselections/core": "1.0.29",
137
+ "@lovable.dev/vite-tanstack-config": "2.25.3",
128
138
  "@rsbuild/core": "^1.0.0",
129
139
  "@tailwindcss/vite": "^4.2.1",
130
140
  "@tanstack/react-query": "^5.83.0",