@flowselections/floriday-authenticatie-module 1.0.69 → 1.0.74

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 (51) hide show
  1. package/dist-lib/integrations/supabase/types.d.ts +159 -0
  2. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  3. package/dist-lib/lib/floriday-gateway-auth.js +5 -5
  4. package/dist-lib/lib/floriday-gateway-hmac.d.ts +10 -0
  5. package/dist-lib/lib/floriday-gateway-hmac.d.ts.map +1 -1
  6. package/dist-lib/lib/floriday-gateway-hmac.js +53 -44
  7. package/dist-lib/lib/floriday-order-stage.d.ts +13 -2
  8. package/dist-lib/lib/floriday-order-stage.d.ts.map +1 -1
  9. package/dist-lib/lib/floriday-order-stage.js +16 -3
  10. package/dist-lib/lib/floriday-sync.functions.d.ts +64 -0
  11. package/dist-lib/lib/floriday-sync.functions.d.ts.map +1 -1
  12. package/dist-lib/lib/floriday-sync.functions.js +19 -0
  13. package/dist-lib/lib/floriday.functions.d.ts +7 -0
  14. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  15. package/dist-lib/lib/floriday.functions.js +9 -1
  16. package/dist-lib/lib/gateway/active-environment.js +1 -1
  17. package/dist-lib/lib/gateway/auto-process.js +1 -1
  18. package/dist-lib/lib/gateway/cached-list.js +1 -1
  19. package/dist-lib/lib/gateway/code-list.js +1 -1
  20. package/dist-lib/lib/gateway/cron-scan.js +1 -1
  21. package/dist-lib/lib/gateway/diagnostics.js +1 -1
  22. package/dist-lib/lib/gateway/floricode-records.js +1 -1
  23. package/dist-lib/lib/gateway/floriday-get.js +1 -1
  24. package/dist-lib/lib/gateway/fulfillment-order-body.d.ts +3 -0
  25. package/dist-lib/lib/gateway/fulfillment-order-body.d.ts.map +1 -1
  26. package/dist-lib/lib/gateway/fulfillment-order-body.js +32 -6
  27. package/dist-lib/lib/gateway/fulfillment-order-send.d.ts.map +1 -1
  28. package/dist-lib/lib/gateway/fulfillment-order-send.js +8 -1
  29. package/dist-lib/lib/gateway/fulfillment-order-status.d.ts +10 -4
  30. package/dist-lib/lib/gateway/fulfillment-order-status.d.ts.map +1 -1
  31. package/dist-lib/lib/gateway/fulfillment-order-status.js +195 -68
  32. package/dist-lib/lib/gateway/load-carrier-checks.d.ts +54 -0
  33. package/dist-lib/lib/gateway/load-carrier-checks.d.ts.map +1 -0
  34. package/dist-lib/lib/gateway/load-carrier-checks.js +72 -0
  35. package/dist-lib/lib/gateway/media-upload.js +1 -1
  36. package/dist-lib/lib/gateway/media.js +1 -1
  37. package/dist-lib/lib/gateway/pdf-bulk-merged.js +1 -1
  38. package/dist-lib/lib/gateway/pdf-bulk.js +1 -1
  39. package/dist-lib/lib/gateway/pdf.js +1 -1
  40. package/dist-lib/lib/gateway/product-characteristics.js +1 -1
  41. package/dist-lib/lib/gateway/schema.js +1 -1
  42. package/dist-lib/lib/gateway/supply-line.js +1 -1
  43. package/dist-lib/lib/gateway/trade-item-version.js +1 -1
  44. package/dist-lib/lib/gateway/write.js +1 -1
  45. package/dist-lib/lib/module-version.d.ts +2 -0
  46. package/dist-lib/lib/module-version.d.ts.map +1 -0
  47. package/dist-lib/lib/module-version.js +2 -0
  48. package/dist-lib/lib/status-overview.d.ts +77 -0
  49. package/dist-lib/lib/status-overview.d.ts.map +1 -0
  50. package/dist-lib/lib/status-overview.js +141 -0
  51. package/package.json +2 -2
@@ -68,19 +68,19 @@ async function verifySupabaseBearer(request, supabase) {
68
68
  try {
69
69
  const { data, error } = await supabase.auth.getUser(token);
70
70
  if (error || !data?.user?.id) {
71
- return { ok: false, status: 401, error: "Ongeldige of verlopen sessie" };
71
+ return { ok: false, status: 401, code: "invalid_session", error: "Ongeldige of verlopen sessie" };
72
72
  }
73
73
  return { ok: true, userId: String(data.user.id) };
74
74
  }
75
75
  catch {
76
- return { ok: false, status: 401, error: "Sessie kon niet worden geverifieerd" };
76
+ return { ok: false, status: 401, code: "invalid_session", error: "Sessie kon niet worden geverifieerd" };
77
77
  }
78
78
  }
79
79
  // Standalone Lovable-deploy: publishable key uit env (backwards-compat).
80
80
  const SUPABASE_URL = process.env.SUPABASE_URL;
81
81
  const SUPABASE_PUBLISHABLE_KEY = process.env.SUPABASE_PUBLISHABLE_KEY;
82
82
  if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) {
83
- return { ok: false, status: 500, error: "Supabase niet geconfigureerd op gateway" };
83
+ return { ok: false, status: 500, code: "gateway_not_configured", error: "Supabase niet geconfigureerd op gateway" };
84
84
  }
85
85
  const client = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
86
86
  auth: { storage: undefined, persistSession: false, autoRefreshToken: false },
@@ -88,12 +88,12 @@ async function verifySupabaseBearer(request, supabase) {
88
88
  try {
89
89
  const { data, error } = await client.auth.getClaims(token);
90
90
  if (error || !data?.claims?.sub) {
91
- return { ok: false, status: 401, error: "Ongeldige of verlopen sessie" };
91
+ return { ok: false, status: 401, code: "invalid_session", error: "Ongeldige of verlopen sessie" };
92
92
  }
93
93
  return { ok: true, userId: String(data.claims.sub) };
94
94
  }
95
95
  catch {
96
- return { ok: false, status: 401, error: "Sessie kon niet worden geverifieerd" };
96
+ return { ok: false, status: 401, code: "invalid_session", error: "Sessie kon niet worden geverifieerd" };
97
97
  }
98
98
  }
99
99
  /**
@@ -8,11 +8,21 @@ export interface GatewayAuthOk {
8
8
  caller: string;
9
9
  rawBody: string;
10
10
  }
11
+ export type GatewayAuthErrorCode = "gateway_not_configured" | "missing_signature" | "invalid_timestamp" | "timestamp_out_of_range" | "invalid_signature" | "invalid_session";
11
12
  export interface GatewayAuthFail {
12
13
  ok: false;
13
14
  status: number;
15
+ code: GatewayAuthErrorCode;
14
16
  error: string;
15
17
  }
18
+ /**
19
+ * Leest de tijd uit x-floriday-timestamp. Geaccepteerd:
20
+ * - alleen cijfers, 13+ cijfers = epoch-milliseconden
21
+ * - alleen cijfers, 10 cijfers = epoch-seconden
22
+ * - anders ISO-8601 via Date.parse
23
+ * Retourneert epoch-ms of null. De HMAC blijft over de letterlijke headerwaarde.
24
+ */
25
+ export declare function parseGatewayTimestamp(raw: string | null | undefined): number | null;
16
26
  /**
17
27
  * Verifieer een gateway-request. Bij succes geeft het de raw body terug
18
28
  * (kant-en-klaar voor `JSON.parse`). Bij falen krijgt de caller een
@@ -1 +1 @@
1
- {"version":3,"file":"floriday-gateway-hmac.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-gateway-hmac.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAczD,MAAM,MAAM,yBAAyB,GAAG,MACpC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAClC,MAAM,GACN,IAAI,GACJ,SAAS,CAAC;AAId,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,GACzC,IAAI,CAKN;AAkDD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AA0BD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC,CAwC1C;AAQD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,UAAU,CAAC;CACvB;AAaD,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,mBAAmB,GAAG,eAAe,CAAC,CAyChD"}
1
+ {"version":3,"file":"floriday-gateway-hmac.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-gateway-hmac.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAczD,MAAM,MAAM,yBAAyB,GAAG,MACpC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAClC,MAAM,GACN,IAAI,GACJ,SAAS,CAAC;AAId,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,GACzC,IAAI,CAKN;AAkDD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,mBAAmB,GACnB,mBAAmB,GACnB,wBAAwB,GACxB,mBAAmB,GACnB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAUnF;AAsDD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC,CAqB1C;AAQD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,UAAU,CAAC;CACvB;AAaD,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,mBAAmB,GAAG,eAAe,CAAC,CAsBhD"}
@@ -69,6 +69,47 @@ async function resolveGatewaySecret() {
69
69
  })());
70
70
  return _inflightCentral;
71
71
  }
72
+ /**
73
+ * Leest de tijd uit x-floriday-timestamp. Geaccepteerd:
74
+ * - alleen cijfers, 13+ cijfers = epoch-milliseconden
75
+ * - alleen cijfers, 10 cijfers = epoch-seconden
76
+ * - anders ISO-8601 via Date.parse
77
+ * Retourneert epoch-ms of null. De HMAC blijft over de letterlijke headerwaarde.
78
+ */
79
+ export function parseGatewayTimestamp(raw) {
80
+ const v = (raw ?? "").trim();
81
+ if (!v)
82
+ return null;
83
+ if (/^\d+$/.test(v)) {
84
+ if (v.length === 10)
85
+ return Number(v) * 1000;
86
+ if (v.length >= 12 && v.length <= 14)
87
+ return Number(v);
88
+ return null;
89
+ }
90
+ const t = Date.parse(v);
91
+ return Number.isFinite(t) ? t : null;
92
+ }
93
+ function checkHeaders(timestampHeader, signatureHeader, now) {
94
+ if (!timestampHeader || !signatureHeader) {
95
+ return { ok: false, status: 401, code: "missing_signature", error: "Ontbrekende handtekening-headers" };
96
+ }
97
+ const ts = parseGatewayTimestamp(timestampHeader);
98
+ if (ts === null) {
99
+ return { ok: false, status: 400, code: "invalid_timestamp", error: "Ongeldig timestamp (gebruik epoch-milliseconden, epoch-seconden of ISO-8601)" };
100
+ }
101
+ if (Math.abs(now - ts) > MAX_CLOCK_SKEW_MS) {
102
+ return { ok: false, status: 400, code: "timestamp_out_of_range", error: "Timestamp valt buiten de toegestane marge (±5 min)" };
103
+ }
104
+ return { ok: true };
105
+ }
106
+ const NOT_CONFIGURED = {
107
+ ok: false,
108
+ status: 500,
109
+ code: "gateway_not_configured",
110
+ error: "Gateway niet geconfigureerd (FLORIDAY_GATEWAY_SECRET ontbreekt)",
111
+ };
112
+ const BAD_SIGNATURE = { ok: false, status: 401, code: "invalid_signature", error: "Ongeldige handtekening" };
72
113
  async function hmacSha256Hex(secret, payload) {
73
114
  const enc = new TextEncoder();
74
115
  const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
@@ -96,35 +137,19 @@ function timingSafeEqualHex(a, b) {
96
137
  */
97
138
  export async function verifyGatewayRequest(request) {
98
139
  const secret = await resolveGatewaySecret();
99
- if (!secret) {
100
- return {
101
- ok: false,
102
- status: 500,
103
- error: "Gateway niet geconfigureerd (FLORIDAY_GATEWAY_SECRET ontbreekt)",
104
- };
105
- }
140
+ if (!secret)
141
+ return NOT_CONFIGURED;
106
142
  const timestampHeader = request.headers.get(GATEWAY_HEADER_TIMESTAMP);
107
143
  const signatureHeader = request.headers.get(GATEWAY_HEADER_SIGNATURE);
108
144
  const callerHeader = request.headers.get(GATEWAY_HEADER_CALLER);
109
- if (!timestampHeader || !signatureHeader) {
110
- return { ok: false, status: 401, error: "Ontbrekende handtekening-headers" };
111
- }
112
- const ts = Number(timestampHeader);
113
- if (!Number.isFinite(ts)) {
114
- return { ok: false, status: 400, error: "Ongeldig timestamp" };
115
- }
116
- if (Math.abs(Date.now() - ts) > MAX_CLOCK_SKEW_MS) {
117
- return {
118
- ok: false,
119
- status: 400,
120
- error: "Timestamp valt buiten de toegestane marge (±5 min)",
121
- };
122
- }
145
+ const pre = checkHeaders(timestampHeader, signatureHeader, Date.now());
146
+ if (!pre.ok)
147
+ return pre;
123
148
  const rawBody = await request.text();
124
149
  const expected = await hmacSha256Hex(secret, `${timestampHeader}.${rawBody}`);
125
150
  const presented = signatureHeader.replace(/^sha256=/i, "").toLowerCase();
126
151
  if (!timingSafeEqualHex(expected, presented)) {
127
- return { ok: false, status: 401, error: "Ongeldige handtekening" };
152
+ return BAD_SIGNATURE;
128
153
  }
129
154
  const caller = (callerHeader ?? "").trim().slice(0, 64) || "external";
130
155
  return { ok: true, caller, rawBody };
@@ -138,36 +163,20 @@ async function sha256Hex(bytes) {
138
163
  }
139
164
  export async function verifyGatewayBinaryRequest(request) {
140
165
  const secret = await resolveGatewaySecret();
141
- if (!secret) {
142
- return {
143
- ok: false,
144
- status: 500,
145
- error: "Gateway niet geconfigureerd (FLORIDAY_GATEWAY_SECRET ontbreekt)",
146
- };
147
- }
166
+ if (!secret)
167
+ return NOT_CONFIGURED;
148
168
  const timestampHeader = request.headers.get(GATEWAY_HEADER_TIMESTAMP);
149
169
  const signatureHeader = request.headers.get(GATEWAY_HEADER_SIGNATURE);
150
170
  const callerHeader = request.headers.get(GATEWAY_HEADER_CALLER);
151
- if (!timestampHeader || !signatureHeader) {
152
- return { ok: false, status: 401, error: "Ontbrekende handtekening-headers" };
153
- }
154
- const ts = Number(timestampHeader);
155
- if (!Number.isFinite(ts)) {
156
- return { ok: false, status: 400, error: "Ongeldig timestamp" };
157
- }
158
- if (Math.abs(Date.now() - ts) > MAX_CLOCK_SKEW_MS) {
159
- return {
160
- ok: false,
161
- status: 400,
162
- error: "Timestamp valt buiten de toegestane marge (±5 min)",
163
- };
164
- }
171
+ const pre = checkHeaders(timestampHeader, signatureHeader, Date.now());
172
+ if (!pre.ok)
173
+ return pre;
165
174
  const bodyBytes = new Uint8Array(await request.arrayBuffer());
166
175
  const bodyHash = await sha256Hex(bodyBytes);
167
176
  const expected = await hmacSha256Hex(secret, `${timestampHeader}.${bodyHash}`);
168
177
  const presented = signatureHeader.replace(/^sha256=/i, "").toLowerCase();
169
178
  if (!timingSafeEqualHex(expected, presented)) {
170
- return { ok: false, status: 401, error: "Ongeldige handtekening" };
179
+ return BAD_SIGNATURE;
171
180
  }
172
181
  const caller = (callerHeader ?? "").trim().slice(0, 64) || "external";
173
182
  return { ok: true, caller, bodyBytes };
@@ -1,5 +1,16 @@
1
- export type FloridayStage = "open" | "fulfilled" | "cancelled" | "expired" | "unknown";
2
- export declare function deriveFloridayStage(salesOrderStatus: string | null | undefined, fulfillmentStatuses: Array<string | null | undefined>): FloridayStage;
1
+ export type FloridayStage = "open" | "partially_fulfilled" | "fulfilled" | "cancelled" | "expired" | "unknown";
2
+ /**
3
+ * Afleiding per order. `requests` bevat per fulfillmentRequest de statussen
4
+ * van de uitleveringen die hem claimen. Voorrang (eerste die past wint):
5
+ * 1. geen orderstatus -> unknown
6
+ * 2. CANCELLED / REJECTED / UNFULFILLABLE -> cancelled
7
+ * 3. EXPIRED -> expired
8
+ * 4. alle requests gedekt (ACCEPTED/DELIVERED), >= 1 -> fulfilled
9
+ * 5. minstens één gedekt, niet alle -> partially_fulfilled
10
+ * 6. anders -> open
11
+ * Een geannuleerde of mislukte uitlevering dekt nooit een request.
12
+ */
13
+ export declare function deriveFloridayStage(salesOrderStatus: string | null | undefined, requests: Array<Array<string | null | undefined>>): FloridayStage;
3
14
  /** Incoterm: lege waarde = niet opgegeven (in 2026v2 altijd aanwezig). */
4
15
  export declare function readIncoterm(salesOrder: any): string | null;
5
16
  export type LoadIssue = {
@@ -1 +1 @@
1
- {"version":3,"file":"floriday-order-stage.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-order-stage.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAIvF,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC3C,mBAAmB,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GACpD,aAAa,CAQf;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EACA,8BAA8B,GAC9B,gCAAgC,GAChC,8BAA8B,GAC9B,uBAAuB,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,CAyB9F;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,GAChB,IAAI,GAAG,MAAM,GAAG,QAAQ,CAG1B;AAED,sEAAsE;AACtE,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,GAAG,qBAAqB,GAAG,kBAAkB,GAAG,qBAAqB,GACtF,IAAI,GAAG,sBAAsB,GAAG,wBAAwB,CAI1D"}
1
+ {"version":3,"file":"floriday-order-stage.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-order-stage.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,qBAAqB,GACrB,WAAW,GACX,WAAW,GACX,SAAS,GACT,SAAS,CAAC;AAId;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC3C,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,GAChD,aAAa,CAWf;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EACA,8BAA8B,GAC9B,gCAAgC,GAChC,8BAA8B,GAC9B,uBAAuB,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAA;CAAE,CAyB9F;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,GAChB,IAAI,GAAG,MAAM,GAAG,QAAQ,CAG1B;AAED,sEAAsE;AACtE,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,GAAG,qBAAqB,GAAG,kBAAkB,GAAG,qBAAqB,GACtF,IAAI,GAAG,sBAAsB,GAAG,wBAAwB,CAI1D"}
@@ -5,7 +5,18 @@
5
5
  // fulfillmentRequests van de order claimt. Daarom kijken we naar beide.
6
6
  // Bron: Suppliers API 2026v1 Swagger (SalesOrderStatus, FulfillmentStatus).
7
7
  const FULFILLED = new Set(["ACCEPTED", "DELIVERED"]);
8
- export function deriveFloridayStage(salesOrderStatus, fulfillmentStatuses) {
8
+ /**
9
+ * Afleiding per order. `requests` bevat per fulfillmentRequest de statussen
10
+ * van de uitleveringen die hem claimen. Voorrang (eerste die past wint):
11
+ * 1. geen orderstatus -> unknown
12
+ * 2. CANCELLED / REJECTED / UNFULFILLABLE -> cancelled
13
+ * 3. EXPIRED -> expired
14
+ * 4. alle requests gedekt (ACCEPTED/DELIVERED), >= 1 -> fulfilled
15
+ * 5. minstens één gedekt, niet alle -> partially_fulfilled
16
+ * 6. anders -> open
17
+ * Een geannuleerde of mislukte uitlevering dekt nooit een request.
18
+ */
19
+ export function deriveFloridayStage(salesOrderStatus, requests) {
9
20
  const so = String(salesOrderStatus ?? "").toUpperCase();
10
21
  if (!so)
11
22
  return "unknown";
@@ -13,9 +24,11 @@ export function deriveFloridayStage(salesOrderStatus, fulfillmentStatuses) {
13
24
  return "cancelled";
14
25
  if (so === "EXPIRED")
15
26
  return "expired";
16
- const fo = fulfillmentStatuses.map((s) => String(s ?? "").toUpperCase()).filter(Boolean);
17
- if (fo.some((s) => FULFILLED.has(s)))
27
+ const covered = requests.filter((statuses) => statuses.some((s) => FULFILLED.has(String(s ?? "").toUpperCase()))).length;
28
+ if (requests.length > 0 && covered === requests.length)
18
29
  return "fulfilled";
30
+ if (covered > 0)
31
+ return "partially_fulfilled";
19
32
  return "open";
20
33
  }
21
34
  /** Incoterm: lege waarde = niet opgegeven (in 2026v2 altijd aanwezig). */
@@ -34,6 +34,7 @@ export declare function runFloridayResourceSync(supabase: SupabaseClient, env: F
34
34
  toSequence: number;
35
35
  durationMs: number;
36
36
  backfillNeeded?: boolean;
37
+ partial?: boolean;
37
38
  } | {
38
39
  tradeSettingsError: string;
39
40
  synced: number;
@@ -41,6 +42,23 @@ export declare function runFloridayResourceSync(supabase: SupabaseClient, env: F
41
42
  toSequence: number;
42
43
  durationMs: number;
43
44
  backfillNeeded?: boolean;
45
+ partial?: boolean;
46
+ }>;
47
+ /**
48
+ * Begrensde inhaalronde voor het statusoverzicht: dezelfde sequence-sync als
49
+ * de cron (zelfde cursor, tabel en upsert), maar met een maximum aantal
50
+ * pagina's en een tijdsgrens. Alleen voor sequence-bronnen.
51
+ */
52
+ export declare function runBoundedSequenceSync(supabase: SupabaseClient, connectionId: string, env: FlorydayEnvironment, resource: "sales-orders" | "fulfillment-orders" | "delivery-orders", bounds: {
53
+ maxBatches: number;
54
+ deadlineMs: number;
55
+ }): Promise<{
56
+ synced: number;
57
+ fromSequence: number;
58
+ toSequence: number;
59
+ durationMs: number;
60
+ backfillNeeded?: boolean;
61
+ partial?: boolean;
44
62
  }>;
45
63
  export declare const syncFlorydayTradeItems: import("@tanstack/start-client-core").RequiredFetcher<readonly [import("@tanstack/start-client-core").FunctionMiddlewareAfterServer<{}, unknown, undefined, {
46
64
  supabase: import("../integrations/supabase/auth-middleware.js").AuthedSupabaseClient;
@@ -71,6 +89,7 @@ export declare const syncFlorydayTradeItems: import("@tanstack/start-client-core
71
89
  toSequence: number;
72
90
  durationMs: number;
73
91
  backfillNeeded?: boolean;
92
+ partial?: boolean;
74
93
  ok: true;
75
94
  resource: FlorydayResource;
76
95
  error?: undefined;
@@ -81,6 +100,7 @@ export declare const syncFlorydayTradeItems: import("@tanstack/start-client-core
81
100
  toSequence: number;
82
101
  durationMs: number;
83
102
  backfillNeeded?: boolean;
103
+ partial?: boolean;
84
104
  ok: true;
85
105
  resource: FlorydayResource;
86
106
  error?: undefined;
@@ -118,6 +138,7 @@ export declare const syncFlorydaySalesOrders: import("@tanstack/start-client-cor
118
138
  toSequence: number;
119
139
  durationMs: number;
120
140
  backfillNeeded?: boolean;
141
+ partial?: boolean;
121
142
  ok: true;
122
143
  resource: FlorydayResource;
123
144
  error?: undefined;
@@ -128,6 +149,7 @@ export declare const syncFlorydaySalesOrders: import("@tanstack/start-client-cor
128
149
  toSequence: number;
129
150
  durationMs: number;
130
151
  backfillNeeded?: boolean;
152
+ partial?: boolean;
131
153
  ok: true;
132
154
  resource: FlorydayResource;
133
155
  error?: undefined;
@@ -165,6 +187,7 @@ export declare const syncFlorydayCustomerOrganizations: import("@tanstack/start-
165
187
  toSequence: number;
166
188
  durationMs: number;
167
189
  backfillNeeded?: boolean;
190
+ partial?: boolean;
168
191
  ok: true;
169
192
  resource: FlorydayResource;
170
193
  error?: undefined;
@@ -175,6 +198,7 @@ export declare const syncFlorydayCustomerOrganizations: import("@tanstack/start-
175
198
  toSequence: number;
176
199
  durationMs: number;
177
200
  backfillNeeded?: boolean;
201
+ partial?: boolean;
178
202
  ok: true;
179
203
  resource: FlorydayResource;
180
204
  error?: undefined;
@@ -212,6 +236,7 @@ export declare const syncFlorydayCarriers: import("@tanstack/start-client-core")
212
236
  toSequence: number;
213
237
  durationMs: number;
214
238
  backfillNeeded?: boolean;
239
+ partial?: boolean;
215
240
  ok: true;
216
241
  resource: FlorydayResource;
217
242
  error?: undefined;
@@ -222,6 +247,7 @@ export declare const syncFlorydayCarriers: import("@tanstack/start-client-core")
222
247
  toSequence: number;
223
248
  durationMs: number;
224
249
  backfillNeeded?: boolean;
250
+ partial?: boolean;
225
251
  ok: true;
226
252
  resource: FlorydayResource;
227
253
  error?: undefined;
@@ -259,6 +285,7 @@ export declare const syncFlorydayFulfillmentOrders: import("@tanstack/start-clie
259
285
  toSequence: number;
260
286
  durationMs: number;
261
287
  backfillNeeded?: boolean;
288
+ partial?: boolean;
262
289
  ok: true;
263
290
  resource: FlorydayResource;
264
291
  error?: undefined;
@@ -269,6 +296,7 @@ export declare const syncFlorydayFulfillmentOrders: import("@tanstack/start-clie
269
296
  toSequence: number;
270
297
  durationMs: number;
271
298
  backfillNeeded?: boolean;
299
+ partial?: boolean;
272
300
  ok: true;
273
301
  resource: FlorydayResource;
274
302
  error?: undefined;
@@ -306,6 +334,7 @@ export declare const syncFlorydayCustomerStickers: import("@tanstack/start-clien
306
334
  toSequence: number;
307
335
  durationMs: number;
308
336
  backfillNeeded?: boolean;
337
+ partial?: boolean;
309
338
  ok: true;
310
339
  resource: FlorydayResource;
311
340
  error?: undefined;
@@ -316,6 +345,7 @@ export declare const syncFlorydayCustomerStickers: import("@tanstack/start-clien
316
345
  toSequence: number;
317
346
  durationMs: number;
318
347
  backfillNeeded?: boolean;
348
+ partial?: boolean;
319
349
  ok: true;
320
350
  resource: FlorydayResource;
321
351
  error?: undefined;
@@ -353,6 +383,7 @@ export declare const syncFlorydayWarehouses: import("@tanstack/start-client-core
353
383
  toSequence: number;
354
384
  durationMs: number;
355
385
  backfillNeeded?: boolean;
386
+ partial?: boolean;
356
387
  ok: true;
357
388
  resource: FlorydayResource;
358
389
  error?: undefined;
@@ -363,6 +394,7 @@ export declare const syncFlorydayWarehouses: import("@tanstack/start-client-core
363
394
  toSequence: number;
364
395
  durationMs: number;
365
396
  backfillNeeded?: boolean;
397
+ partial?: boolean;
366
398
  ok: true;
367
399
  resource: FlorydayResource;
368
400
  error?: undefined;
@@ -400,6 +432,7 @@ export declare const syncFlorydayPackings: import("@tanstack/start-client-core")
400
432
  toSequence: number;
401
433
  durationMs: number;
402
434
  backfillNeeded?: boolean;
435
+ partial?: boolean;
403
436
  ok: true;
404
437
  resource: FlorydayResource;
405
438
  error?: undefined;
@@ -410,6 +443,7 @@ export declare const syncFlorydayPackings: import("@tanstack/start-client-core")
410
443
  toSequence: number;
411
444
  durationMs: number;
412
445
  backfillNeeded?: boolean;
446
+ partial?: boolean;
413
447
  ok: true;
414
448
  resource: FlorydayResource;
415
449
  error?: undefined;
@@ -447,6 +481,7 @@ export declare const syncFlorydayDeliveryLocations: import("@tanstack/start-clie
447
481
  toSequence: number;
448
482
  durationMs: number;
449
483
  backfillNeeded?: boolean;
484
+ partial?: boolean;
450
485
  ok: true;
451
486
  resource: FlorydayResource;
452
487
  error?: undefined;
@@ -457,6 +492,7 @@ export declare const syncFlorydayDeliveryLocations: import("@tanstack/start-clie
457
492
  toSequence: number;
458
493
  durationMs: number;
459
494
  backfillNeeded?: boolean;
495
+ partial?: boolean;
460
496
  ok: true;
461
497
  resource: FlorydayResource;
462
498
  error?: undefined;
@@ -494,6 +530,7 @@ export declare const syncFlorydayClockSupplies: import("@tanstack/start-client-c
494
530
  toSequence: number;
495
531
  durationMs: number;
496
532
  backfillNeeded?: boolean;
533
+ partial?: boolean;
497
534
  ok: true;
498
535
  resource: FlorydayResource;
499
536
  error?: undefined;
@@ -504,6 +541,7 @@ export declare const syncFlorydayClockSupplies: import("@tanstack/start-client-c
504
541
  toSequence: number;
505
542
  durationMs: number;
506
543
  backfillNeeded?: boolean;
544
+ partial?: boolean;
507
545
  ok: true;
508
546
  resource: FlorydayResource;
509
547
  error?: undefined;
@@ -541,6 +579,7 @@ export declare const syncFlorydayDeliveryOrders: import("@tanstack/start-client-
541
579
  toSequence: number;
542
580
  durationMs: number;
543
581
  backfillNeeded?: boolean;
582
+ partial?: boolean;
544
583
  ok: true;
545
584
  resource: FlorydayResource;
546
585
  error?: undefined;
@@ -551,6 +590,7 @@ export declare const syncFlorydayDeliveryOrders: import("@tanstack/start-client-
551
590
  toSequence: number;
552
591
  durationMs: number;
553
592
  backfillNeeded?: boolean;
593
+ partial?: boolean;
554
594
  ok: true;
555
595
  resource: FlorydayResource;
556
596
  error?: undefined;
@@ -588,6 +628,7 @@ export declare const syncFlorydayClockPresales: import("@tanstack/start-client-c
588
628
  toSequence: number;
589
629
  durationMs: number;
590
630
  backfillNeeded?: boolean;
631
+ partial?: boolean;
591
632
  ok: true;
592
633
  resource: FlorydayResource;
593
634
  error?: undefined;
@@ -598,6 +639,7 @@ export declare const syncFlorydayClockPresales: import("@tanstack/start-client-c
598
639
  toSequence: number;
599
640
  durationMs: number;
600
641
  backfillNeeded?: boolean;
642
+ partial?: boolean;
601
643
  ok: true;
602
644
  resource: FlorydayResource;
603
645
  error?: undefined;
@@ -635,6 +677,7 @@ export declare const syncFlorydayContracts: import("@tanstack/start-client-core"
635
677
  toSequence: number;
636
678
  durationMs: number;
637
679
  backfillNeeded?: boolean;
680
+ partial?: boolean;
638
681
  ok: true;
639
682
  resource: FlorydayResource;
640
683
  error?: undefined;
@@ -645,6 +688,7 @@ export declare const syncFlorydayContracts: import("@tanstack/start-client-core"
645
688
  toSequence: number;
646
689
  durationMs: number;
647
690
  backfillNeeded?: boolean;
691
+ partial?: boolean;
648
692
  ok: true;
649
693
  resource: FlorydayResource;
650
694
  error?: undefined;
@@ -682,6 +726,7 @@ export declare const syncFlorydayBlanketOrders: import("@tanstack/start-client-c
682
726
  toSequence: number;
683
727
  durationMs: number;
684
728
  backfillNeeded?: boolean;
729
+ partial?: boolean;
685
730
  ok: true;
686
731
  resource: FlorydayResource;
687
732
  error?: undefined;
@@ -692,6 +737,7 @@ export declare const syncFlorydayBlanketOrders: import("@tanstack/start-client-c
692
737
  toSequence: number;
693
738
  durationMs: number;
694
739
  backfillNeeded?: boolean;
740
+ partial?: boolean;
695
741
  ok: true;
696
742
  resource: FlorydayResource;
697
743
  error?: undefined;
@@ -831,6 +877,7 @@ export declare const syncFlorydayAdditionalServices: import("@tanstack/start-cli
831
877
  toSequence: number;
832
878
  durationMs: number;
833
879
  backfillNeeded?: boolean;
880
+ partial?: boolean;
834
881
  ok: true;
835
882
  resource: FlorydayResource;
836
883
  error?: undefined;
@@ -841,6 +888,7 @@ export declare const syncFlorydayAdditionalServices: import("@tanstack/start-cli
841
888
  toSequence: number;
842
889
  durationMs: number;
843
890
  backfillNeeded?: boolean;
891
+ partial?: boolean;
844
892
  ok: true;
845
893
  resource: FlorydayResource;
846
894
  error?: undefined;
@@ -878,6 +926,7 @@ export declare const syncFlorydayCommercialServiceTypes: import("@tanstack/start
878
926
  toSequence: number;
879
927
  durationMs: number;
880
928
  backfillNeeded?: boolean;
929
+ partial?: boolean;
881
930
  ok: true;
882
931
  resource: FlorydayResource;
883
932
  error?: undefined;
@@ -888,6 +937,7 @@ export declare const syncFlorydayCommercialServiceTypes: import("@tanstack/start
888
937
  toSequence: number;
889
938
  durationMs: number;
890
939
  backfillNeeded?: boolean;
940
+ partial?: boolean;
891
941
  ok: true;
892
942
  resource: FlorydayResource;
893
943
  error?: undefined;
@@ -925,6 +975,7 @@ export declare const syncFlorydayCollections: import("@tanstack/start-client-cor
925
975
  toSequence: number;
926
976
  durationMs: number;
927
977
  backfillNeeded?: boolean;
978
+ partial?: boolean;
928
979
  ok: true;
929
980
  resource: FlorydayResource;
930
981
  error?: undefined;
@@ -935,6 +986,7 @@ export declare const syncFlorydayCollections: import("@tanstack/start-client-cor
935
986
  toSequence: number;
936
987
  durationMs: number;
937
988
  backfillNeeded?: boolean;
989
+ partial?: boolean;
938
990
  ok: true;
939
991
  resource: FlorydayResource;
940
992
  error?: undefined;
@@ -972,6 +1024,7 @@ export declare const syncFlorydayPriceGroups: import("@tanstack/start-client-cor
972
1024
  toSequence: number;
973
1025
  durationMs: number;
974
1026
  backfillNeeded?: boolean;
1027
+ partial?: boolean;
975
1028
  ok: true;
976
1029
  resource: FlorydayResource;
977
1030
  error?: undefined;
@@ -982,6 +1035,7 @@ export declare const syncFlorydayPriceGroups: import("@tanstack/start-client-cor
982
1035
  toSequence: number;
983
1036
  durationMs: number;
984
1037
  backfillNeeded?: boolean;
1038
+ partial?: boolean;
985
1039
  ok: true;
986
1040
  resource: FlorydayResource;
987
1041
  error?: undefined;
@@ -1019,6 +1073,7 @@ export declare const syncFlorydayCatalogPrices: import("@tanstack/start-client-c
1019
1073
  toSequence: number;
1020
1074
  durationMs: number;
1021
1075
  backfillNeeded?: boolean;
1076
+ partial?: boolean;
1022
1077
  ok: true;
1023
1078
  resource: FlorydayResource;
1024
1079
  error?: undefined;
@@ -1029,6 +1084,7 @@ export declare const syncFlorydayCatalogPrices: import("@tanstack/start-client-c
1029
1084
  toSequence: number;
1030
1085
  durationMs: number;
1031
1086
  backfillNeeded?: boolean;
1087
+ partial?: boolean;
1032
1088
  ok: true;
1033
1089
  resource: FlorydayResource;
1034
1090
  error?: undefined;
@@ -1077,6 +1133,7 @@ export declare const syncFlorydayDeliveryConditionSets: import("@tanstack/start-
1077
1133
  toSequence: number;
1078
1134
  durationMs: number;
1079
1135
  backfillNeeded?: boolean;
1136
+ partial?: boolean;
1080
1137
  ok: true;
1081
1138
  resource: FlorydayResource;
1082
1139
  error?: undefined;
@@ -1087,6 +1144,7 @@ export declare const syncFlorydayDeliveryConditionSets: import("@tanstack/start-
1087
1144
  toSequence: number;
1088
1145
  durationMs: number;
1089
1146
  backfillNeeded?: boolean;
1147
+ partial?: boolean;
1090
1148
  ok: true;
1091
1149
  resource: FlorydayResource;
1092
1150
  error?: undefined;
@@ -1124,6 +1182,7 @@ export declare const syncFlorydaySalesStrategies: import("@tanstack/start-client
1124
1182
  toSequence: number;
1125
1183
  durationMs: number;
1126
1184
  backfillNeeded?: boolean;
1185
+ partial?: boolean;
1127
1186
  ok: true;
1128
1187
  resource: FlorydayResource;
1129
1188
  error?: undefined;
@@ -1134,6 +1193,7 @@ export declare const syncFlorydaySalesStrategies: import("@tanstack/start-client
1134
1193
  toSequence: number;
1135
1194
  durationMs: number;
1136
1195
  backfillNeeded?: boolean;
1196
+ partial?: boolean;
1137
1197
  ok: true;
1138
1198
  resource: FlorydayResource;
1139
1199
  error?: undefined;
@@ -1171,6 +1231,7 @@ export declare const syncFlorydayBaseItems: import("@tanstack/start-client-core"
1171
1231
  toSequence: number;
1172
1232
  durationMs: number;
1173
1233
  backfillNeeded?: boolean;
1234
+ partial?: boolean;
1174
1235
  ok: true;
1175
1236
  resource: FlorydayResource;
1176
1237
  error?: undefined;
@@ -1181,6 +1242,7 @@ export declare const syncFlorydayBaseItems: import("@tanstack/start-client-core"
1181
1242
  toSequence: number;
1182
1243
  durationMs: number;
1183
1244
  backfillNeeded?: boolean;
1245
+ partial?: boolean;
1184
1246
  ok: true;
1185
1247
  resource: FlorydayResource;
1186
1248
  error?: undefined;
@@ -1218,6 +1280,7 @@ export declare const syncFlorydayContractTradeItemGroups: import("@tanstack/star
1218
1280
  toSequence: number;
1219
1281
  durationMs: number;
1220
1282
  backfillNeeded?: boolean;
1283
+ partial?: boolean;
1221
1284
  ok: true;
1222
1285
  resource: FlorydayResource;
1223
1286
  error?: undefined;
@@ -1228,6 +1291,7 @@ export declare const syncFlorydayContractTradeItemGroups: import("@tanstack/star
1228
1291
  toSequence: number;
1229
1292
  durationMs: number;
1230
1293
  backfillNeeded?: boolean;
1294
+ partial?: boolean;
1231
1295
  ok: true;
1232
1296
  resource: FlorydayResource;
1233
1297
  error?: undefined;