@flowselections/floriday-authenticatie-module 1.0.23 → 1.0.25
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.
- package/dist-lib/components/settings/FloricodeSettingsCard.js +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -0
- package/dist-lib/lib/central-auth.server.d.ts +17 -0
- package/dist-lib/lib/central-auth.server.d.ts.map +1 -1
- package/dist-lib/lib/central-auth.server.js +40 -0
- package/dist-lib/lib/floricode-credentials.server.d.ts.map +1 -1
- package/dist-lib/lib/floricode-credentials.server.js +94 -26
- package/dist-lib/lib/floricode.functions.d.ts +1 -0
- package/dist-lib/lib/floricode.functions.d.ts.map +1 -1
- package/dist-lib/lib/floricode.functions.js +13 -0
- package/dist-lib/lib/floriday-sync.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday-sync.functions.js +2 -1
- package/dist-lib/lib/floriday.functions.d.ts +144 -19
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday.functions.js +24 -14
- package/dist-lib/lib/gateway/active-environment.d.ts +7 -0
- package/dist-lib/lib/gateway/active-environment.d.ts.map +1 -0
- package/dist-lib/lib/gateway/active-environment.js +8 -0
- package/dist-lib/lib/gateway/code-list.d.ts +16 -0
- package/dist-lib/lib/gateway/code-list.d.ts.map +1 -0
- package/dist-lib/lib/gateway/code-list.js +28 -0
- package/dist-lib/lib/gateway/diagnostics.d.ts +13 -0
- package/dist-lib/lib/gateway/diagnostics.d.ts.map +1 -0
- package/dist-lib/lib/gateway/diagnostics.js +66 -0
- package/dist-lib/lib/gateway/floricode-records.d.ts +22 -0
- package/dist-lib/lib/gateway/floricode-records.d.ts.map +1 -0
- package/dist-lib/lib/gateway/floricode-records.js +32 -0
- package/dist-lib/lib/gateway/fulfillment-order-send.d.ts +7 -0
- package/dist-lib/lib/gateway/fulfillment-order-send.d.ts.map +1 -0
- package/dist-lib/lib/gateway/fulfillment-order-send.js +123 -0
- package/dist-lib/lib/gateway/index.d.ts +14 -0
- package/dist-lib/lib/gateway/index.d.ts.map +1 -1
- package/dist-lib/lib/gateway/index.js +14 -0
- package/dist-lib/lib/gateway/media-upload.d.ts +21 -0
- package/dist-lib/lib/gateway/media-upload.d.ts.map +1 -0
- package/dist-lib/lib/gateway/media-upload.js +96 -0
- package/dist-lib/lib/gateway/media.d.ts +19 -0
- package/dist-lib/lib/gateway/media.d.ts.map +1 -0
- package/dist-lib/lib/gateway/media.js +96 -0
- package/dist-lib/lib/gateway/pdf-bulk-merged.d.ts +34 -0
- package/dist-lib/lib/gateway/pdf-bulk-merged.d.ts.map +1 -0
- package/dist-lib/lib/gateway/pdf-bulk-merged.js +80 -0
- package/dist-lib/lib/gateway/pdf-bulk.d.ts +31 -0
- package/dist-lib/lib/gateway/pdf-bulk.d.ts.map +1 -0
- package/dist-lib/lib/gateway/pdf-bulk.js +65 -0
- package/dist-lib/lib/gateway/pdf.d.ts +24 -0
- package/dist-lib/lib/gateway/pdf.d.ts.map +1 -0
- package/dist-lib/lib/gateway/pdf.js +64 -0
- package/dist-lib/lib/gateway/product-characteristics.d.ts +18 -0
- package/dist-lib/lib/gateway/product-characteristics.d.ts.map +1 -0
- package/dist-lib/lib/gateway/product-characteristics.js +8 -0
- package/dist-lib/lib/gateway/schema.d.ts +28 -0
- package/dist-lib/lib/gateway/schema.d.ts.map +1 -0
- package/dist-lib/lib/gateway/schema.js +102 -0
- package/dist-lib/lib/gateway/shared.d.ts +5 -1
- package/dist-lib/lib/gateway/shared.d.ts.map +1 -1
- package/dist-lib/lib/gateway/shared.js +7 -3
- package/dist-lib/lib/gateway/supply-line.d.ts +11 -0
- package/dist-lib/lib/gateway/supply-line.d.ts.map +1 -0
- package/dist-lib/lib/gateway/supply-line.js +261 -0
- package/dist-lib/lib/gateway/write.d.ts +18 -0
- package/dist-lib/lib/gateway/write.d.ts.map +1 -0
- package/dist-lib/lib/gateway/write.js +32 -0
- package/package.json +1 -1
|
@@ -93,7 +93,8 @@ function toPublic(row) {
|
|
|
93
93
|
}
|
|
94
94
|
// ─── Reusable internals (importable by other server fns) ────────────────────
|
|
95
95
|
export async function getActiveFlorydayCredentials(supabase, env) {
|
|
96
|
-
const {
|
|
96
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
97
|
+
const { data, error } = await supabaseAdmin
|
|
97
98
|
.from("floriday_connections")
|
|
98
99
|
.select("*")
|
|
99
100
|
.eq("environment", env)
|
|
@@ -104,6 +105,7 @@ export async function getActiveFlorydayCredentials(supabase, env) {
|
|
|
104
105
|
return data;
|
|
105
106
|
}
|
|
106
107
|
export async function getFlorydayAccessToken(supabase, env, options = {}) {
|
|
108
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
107
109
|
const row = await getActiveFlorydayCredentials(supabase, env);
|
|
108
110
|
if (!row)
|
|
109
111
|
throw new Error(`Geen actieve Floriday-koppeling voor ${env}`);
|
|
@@ -117,7 +119,7 @@ export async function getFlorydayAccessToken(supabase, env, options = {}) {
|
|
|
117
119
|
// Concurrency-guard: vlak voor de tokenrequest opnieuw lezen — een parallelle worker
|
|
118
120
|
// kan zojuist een fresh token hebben geschreven en dan hoeven we niet nóg eens te refreshen.
|
|
119
121
|
if (canReuseStoredToken && !options.forceRefresh) {
|
|
120
|
-
const { data: fresh } = await
|
|
122
|
+
const { data: fresh } = await supabaseAdmin
|
|
121
123
|
.from("floriday_connections")
|
|
122
124
|
.select("access_token, token_expires_at")
|
|
123
125
|
.eq("id", row.id)
|
|
@@ -138,7 +140,7 @@ export async function getFlorydayAccessToken(supabase, env, options = {}) {
|
|
|
138
140
|
accessToken = result.access_token;
|
|
139
141
|
newExpiresAt = result.expires_at;
|
|
140
142
|
if (canReuseStoredToken) {
|
|
141
|
-
await
|
|
143
|
+
await supabaseAdmin
|
|
142
144
|
.from("floriday_connections")
|
|
143
145
|
.update({ access_token: accessToken, token_expires_at: newExpiresAt })
|
|
144
146
|
.eq("id", row.id);
|
|
@@ -182,6 +184,7 @@ function createFlorydayTokenError(status, body, scope) {
|
|
|
182
184
|
return new Error(`Floriday token-aanvraag mislukt [${status}]: ${body.slice(0, 300)}`);
|
|
183
185
|
}
|
|
184
186
|
async function fetchAndStoreFlorydayOrganizationName(supabase, env, connectionId) {
|
|
187
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
185
188
|
try {
|
|
186
189
|
// Stap 1: bepaal de eigen organizationId via trade-settings.
|
|
187
190
|
const tsRes = await florydayFetch(supabase, env, `/${SUPPLIERS_API_VERSION}/trade-settings/supplier/current-organization`);
|
|
@@ -207,7 +210,7 @@ async function fetchAndStoreFlorydayOrganizationName(supabase, env, connectionId
|
|
|
207
210
|
if (!name)
|
|
208
211
|
return null;
|
|
209
212
|
// Lees huidige rij om gln_code niet te overschrijven als die al gezet is.
|
|
210
|
-
const { data: existing } = await
|
|
213
|
+
const { data: existing } = await supabaseAdmin
|
|
211
214
|
.from("floriday_connections")
|
|
212
215
|
.select("gln_code")
|
|
213
216
|
.eq("id", connectionId)
|
|
@@ -216,7 +219,7 @@ async function fetchAndStoreFlorydayOrganizationName(supabase, env, connectionId
|
|
|
216
219
|
if (gln && !existing?.gln_code) {
|
|
217
220
|
update.gln_code = gln;
|
|
218
221
|
}
|
|
219
|
-
await
|
|
222
|
+
await supabaseAdmin.from("floriday_connections").update(update).eq("id", connectionId);
|
|
220
223
|
return name;
|
|
221
224
|
}
|
|
222
225
|
catch (e) {
|
|
@@ -299,7 +302,8 @@ export async function florydayFetch(supabase, pathOrEnv, pathOrInit, maybeInit =
|
|
|
299
302
|
export const listFlorydayConnections = createServerFn({ method: "GET" })
|
|
300
303
|
.middleware([requireSupabaseAuth])
|
|
301
304
|
.handler(async ({ context }) => {
|
|
302
|
-
const {
|
|
305
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
306
|
+
const { data, error } = await supabaseAdmin
|
|
303
307
|
.from("floriday_connections")
|
|
304
308
|
.select("*")
|
|
305
309
|
.order("environment", { ascending: true });
|
|
@@ -310,7 +314,8 @@ export const listFlorydayConnections = createServerFn({ method: "GET" })
|
|
|
310
314
|
export const getFlorydayTokenHealth = createServerFn({ method: "GET" })
|
|
311
315
|
.middleware([requireSupabaseAuth])
|
|
312
316
|
.handler(async ({ context }) => {
|
|
313
|
-
const {
|
|
317
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
318
|
+
const { data: conns } = await supabaseAdmin
|
|
314
319
|
.from("floriday_connections")
|
|
315
320
|
.select("id, environment, token_expires_at, is_active")
|
|
316
321
|
.eq("is_active", true);
|
|
@@ -333,8 +338,9 @@ export const forceRefreshFlorydayToken = createServerFn({ method: "POST" })
|
|
|
333
338
|
return input;
|
|
334
339
|
})
|
|
335
340
|
.handler(async ({ data, context }) => {
|
|
341
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
336
342
|
await getFlorydayAccessToken(context.supabase, data.environment, { forceRefresh: true });
|
|
337
|
-
const { data: row } = await
|
|
343
|
+
const { data: row } = await supabaseAdmin
|
|
338
344
|
.from("floriday_connections")
|
|
339
345
|
.select("token_expires_at")
|
|
340
346
|
.eq("environment", data.environment)
|
|
@@ -354,12 +360,13 @@ export const upsertFlorydayConnection = createServerFn({ method: "POST" })
|
|
|
354
360
|
return input;
|
|
355
361
|
})
|
|
356
362
|
.handler(async ({ data, context }) => {
|
|
363
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
357
364
|
// Update-in-place op (environment, is_active=true) — geen DELETE meer,
|
|
358
365
|
// anders zou ON DELETE CASCADE alle cache-data voor deze connection wissen
|
|
359
366
|
// bij een gewone credential-wijziging. SELECT-filter matcht exact de
|
|
360
367
|
// partiële unieke index floriday_connections_env_active_uniq
|
|
361
368
|
// (environment) WHERE is_active = true.
|
|
362
|
-
const { data: existing, error: selectError } = await
|
|
369
|
+
const { data: existing, error: selectError } = await supabaseAdmin
|
|
363
370
|
.from("floriday_connections")
|
|
364
371
|
.select("id")
|
|
365
372
|
.eq("environment", data.environment)
|
|
@@ -380,7 +387,7 @@ export const upsertFlorydayConnection = createServerFn({ method: "POST" })
|
|
|
380
387
|
};
|
|
381
388
|
let inserted;
|
|
382
389
|
if (existing?.id) {
|
|
383
|
-
const { data: updated, error } = await
|
|
390
|
+
const { data: updated, error } = await supabaseAdmin
|
|
384
391
|
.from("floriday_connections")
|
|
385
392
|
.update(payload)
|
|
386
393
|
.eq("id", existing.id)
|
|
@@ -395,7 +402,7 @@ export const upsertFlorydayConnection = createServerFn({ method: "POST" })
|
|
|
395
402
|
// de partiële unieke index vangt de tweede insert luid af met een
|
|
396
403
|
// constraint-error. Credentials opslaan is een handmatige, zeldzame
|
|
397
404
|
// actie — geen extra locking nodig.
|
|
398
|
-
const { data: created, error } = await
|
|
405
|
+
const { data: created, error } = await supabaseAdmin
|
|
399
406
|
.from("floriday_connections")
|
|
400
407
|
.insert({ environment: data.environment, ...payload })
|
|
401
408
|
.select("*")
|
|
@@ -479,7 +486,8 @@ export const deleteFlorydayConnection = createServerFn({ method: "POST" })
|
|
|
479
486
|
return input;
|
|
480
487
|
})
|
|
481
488
|
.handler(async ({ data, context }) => {
|
|
482
|
-
const {
|
|
489
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
490
|
+
const { error } = await supabaseAdmin
|
|
483
491
|
.from("floriday_connections")
|
|
484
492
|
.delete()
|
|
485
493
|
.eq("id", data.id);
|
|
@@ -681,10 +689,11 @@ export const updateFlorydayPublishingSettings = createServerFn({ method: "POST"
|
|
|
681
689
|
return { ...input, gln_code: trimmed || null };
|
|
682
690
|
})
|
|
683
691
|
.handler(async ({ data, context }) => {
|
|
692
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
684
693
|
const row = await getActiveFlorydayCredentials(context.supabase, data.environment);
|
|
685
694
|
if (!row)
|
|
686
695
|
throw new Error(`Geen actieve Floriday-koppeling voor ${data.environment}`);
|
|
687
|
-
const { error } = await
|
|
696
|
+
const { error } = await supabaseAdmin
|
|
688
697
|
.from("floriday_connections")
|
|
689
698
|
.update({
|
|
690
699
|
gln_code: data.gln_code?.trim() || null,
|
|
@@ -731,6 +740,7 @@ async function fetchBySequence(supabase, env, bySequenceEndpointBase, fromSequen
|
|
|
731
740
|
}
|
|
732
741
|
export async function syncFloridayEntityBySequence(supabase, env, connectionId, opts) {
|
|
733
742
|
const t0 = Date.now();
|
|
743
|
+
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
734
744
|
const { data: stateRow } = await supabase
|
|
735
745
|
.from("floriday_sync_state")
|
|
736
746
|
.select("last_sequence_number")
|
|
@@ -742,7 +752,7 @@ export async function syncFloridayEntityBySequence(supabase, env, connectionId,
|
|
|
742
752
|
// Debug-logging: helpt 401's onderscheid maken tussen scope-issue,
|
|
743
753
|
// expired token en wrong env. Token zelf wordt NIET gelogd.
|
|
744
754
|
try {
|
|
745
|
-
const { data: connRow } = await
|
|
755
|
+
const { data: connRow } = await supabaseAdmin
|
|
746
756
|
.from("floriday_connections")
|
|
747
757
|
.select("token_expires_at")
|
|
748
758
|
.eq("id", connectionId)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface ActiveEnvironmentResult {
|
|
3
|
+
ok: true;
|
|
4
|
+
environment: "staging" | "live";
|
|
5
|
+
}
|
|
6
|
+
export declare function runActiveEnvironment(supabase: SupabaseClient): Promise<ActiveEnvironmentResult>;
|
|
7
|
+
//# sourceMappingURL=active-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-environment.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/active-environment.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;CACjC;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAGlC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Gateway business-logica voor /api/public/gateway/active-environment.
|
|
2
|
+
// Verplaatst uit de route; gedrag byte-identiek.
|
|
3
|
+
// Throw uit resolveGatewayEnvironment bubbelt naar de adapter → 409.
|
|
4
|
+
import { resolveGatewayEnvironment } from "./shared";
|
|
5
|
+
export async function runActiveEnvironment(supabase) {
|
|
6
|
+
const environment = await resolveGatewayEnvironment(supabase);
|
|
7
|
+
return { ok: true, environment };
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface CodeListInput {
|
|
3
|
+
environment: "staging" | "live";
|
|
4
|
+
listName: string;
|
|
5
|
+
/** Optioneel filter voor grote lijsten, bijvoorbeeld "101123:%". */
|
|
6
|
+
codeLike?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function runCodeList(supabase: SupabaseClient, parsed: CodeListInput): Promise<{
|
|
9
|
+
ok: true;
|
|
10
|
+
values: Array<{
|
|
11
|
+
code: string;
|
|
12
|
+
label: string | null;
|
|
13
|
+
payload: any;
|
|
14
|
+
}>;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=code-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-list.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/code-list.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA4BD,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAQ5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Gateway business-logica voor /api/public/gateway/code-list.
|
|
2
|
+
// Verplaatst uit de route; byte-identiek gedrag.
|
|
3
|
+
async function fetchAllCodeListRows(supabaseAdmin, environment, listName, codeLike) {
|
|
4
|
+
const pageSize = 1000;
|
|
5
|
+
const rows = [];
|
|
6
|
+
for (let from = 0;; from += pageSize) {
|
|
7
|
+
let query = supabaseAdmin
|
|
8
|
+
.from("floriday_code_lists_cache")
|
|
9
|
+
.select("code, label, payload")
|
|
10
|
+
.eq("environment", environment)
|
|
11
|
+
.eq("list_name", listName)
|
|
12
|
+
.order("code", { ascending: true })
|
|
13
|
+
.range(from, from + pageSize - 1);
|
|
14
|
+
if (codeLike && typeof codeLike === "string")
|
|
15
|
+
query = query.like("code", codeLike);
|
|
16
|
+
const { data, error } = await query;
|
|
17
|
+
if (error)
|
|
18
|
+
throw error;
|
|
19
|
+
rows.push(...(data ?? []));
|
|
20
|
+
if (!data || data.length < pageSize)
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
return rows;
|
|
24
|
+
}
|
|
25
|
+
export async function runCodeList(supabase, parsed) {
|
|
26
|
+
const rows = await fetchAllCodeListRows(supabase, parsed.environment, parsed.listName, parsed.codeLike);
|
|
27
|
+
return { ok: true, values: rows ?? [] };
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface DiagnosticsInput {
|
|
3
|
+
rawBody: string;
|
|
4
|
+
callerHeader: string | null;
|
|
5
|
+
callerAuth: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DiagnosticsResult {
|
|
8
|
+
stored: boolean;
|
|
9
|
+
attemptId: string | null;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runDiagnostics(supabase: SupabaseClient, input: DiagnosticsInput): Promise<DiagnosticsResult>;
|
|
13
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/diagnostics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA4B5D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CA4D5B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Gateway module: diagnostics-log endpoint (fail-soft).
|
|
2
|
+
// Spiegel van src/routes/api/public/gateway/diagnostics.ts.
|
|
3
|
+
const MAX_STRING_LEN = 4 * 1024;
|
|
4
|
+
function truncate(value) {
|
|
5
|
+
if (typeof value === "string") {
|
|
6
|
+
return value.length > MAX_STRING_LEN
|
|
7
|
+
? value.slice(0, MAX_STRING_LEN) + "…[truncated]"
|
|
8
|
+
: value;
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
export async function runDiagnostics(supabase, input) {
|
|
13
|
+
let body;
|
|
14
|
+
try {
|
|
15
|
+
body = input.rawBody ? JSON.parse(input.rawBody) : {};
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Fail-soft: ongeldige JSON niet hard afwijzen — log raw en bevestig.
|
|
19
|
+
body = { summary: "invalid-json", context: { raw: truncate(input.rawBody) } };
|
|
20
|
+
}
|
|
21
|
+
const caller = (input.callerHeader ?? body.caller ?? input.callerAuth ?? "external")
|
|
22
|
+
.trim()
|
|
23
|
+
.slice(0, 64) || "external";
|
|
24
|
+
const summary = typeof body.summary === "string" && body.summary.trim()
|
|
25
|
+
? body.summary.slice(0, MAX_STRING_LEN)
|
|
26
|
+
: "diagnostics-report";
|
|
27
|
+
const safeRequest = {
|
|
28
|
+
summary,
|
|
29
|
+
environment: body.environment ?? null,
|
|
30
|
+
fileName: body.fileName ? String(body.fileName).slice(0, 512) : null,
|
|
31
|
+
contentType: body.contentType ? String(body.contentType).slice(0, 128) : null,
|
|
32
|
+
bytes: typeof body.bytes === "number" ? body.bytes : null,
|
|
33
|
+
httpStatus: typeof body.httpStatus === "number" ? body.httpStatus : null,
|
|
34
|
+
attemptId: body.attemptId ? String(body.attemptId).slice(0, 128) : null,
|
|
35
|
+
referenceId: body.referenceId ? String(body.referenceId).slice(0, 256) : null,
|
|
36
|
+
florydayError: truncate(body.florydayError ?? null),
|
|
37
|
+
stack: truncate(body.stack ?? null),
|
|
38
|
+
context: body.context ?? null,
|
|
39
|
+
};
|
|
40
|
+
const { data: inserted, error } = await supabase
|
|
41
|
+
.from("floriday_write_log")
|
|
42
|
+
.insert({
|
|
43
|
+
connection_id: null,
|
|
44
|
+
module: caller,
|
|
45
|
+
action: "diagnostics-report",
|
|
46
|
+
resource: "diagnostics",
|
|
47
|
+
floriday_id: safeRequest.referenceId,
|
|
48
|
+
request: safeRequest,
|
|
49
|
+
response: null,
|
|
50
|
+
http_status: safeRequest.httpStatus ?? 0,
|
|
51
|
+
ok: true,
|
|
52
|
+
error: summary,
|
|
53
|
+
idempotency_key: null,
|
|
54
|
+
caller,
|
|
55
|
+
})
|
|
56
|
+
.select("id")
|
|
57
|
+
.maybeSingle();
|
|
58
|
+
if (error) {
|
|
59
|
+
console.error("[gateway/diagnostics] insert failed:", error.message);
|
|
60
|
+
return { stored: false, attemptId: null, error: "diagnostics-not-stored" };
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
stored: true,
|
|
64
|
+
attemptId: inserted?.id ?? null,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface FloricodeRecordsInput {
|
|
3
|
+
resource: string;
|
|
4
|
+
recordIds?: string[];
|
|
5
|
+
since?: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
offset?: number;
|
|
8
|
+
}
|
|
9
|
+
export type FloricodeRecordsResult = {
|
|
10
|
+
ok: true;
|
|
11
|
+
resource: string;
|
|
12
|
+
rows: unknown[];
|
|
13
|
+
count: number | null;
|
|
14
|
+
offset: number;
|
|
15
|
+
limit: number;
|
|
16
|
+
nextOffset: number | null;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function runFloricodeRecords(supabase: SupabaseClient, body: FloricodeRecordsInput): Promise<FloricodeRecordsResult>;
|
|
22
|
+
//# sourceMappingURL=floricode-records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floricode-records.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/floricode-records.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,sBAAsB,CAAC,CA8BjC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Gateway business-logica voor /api/public/gateway/floricode-records.
|
|
2
|
+
// Read-only access tot floricode_records; gedrag byte-identiek t.o.v. HEAD.
|
|
3
|
+
export async function runFloricodeRecords(supabase, body) {
|
|
4
|
+
if (!body.resource) {
|
|
5
|
+
return { ok: false, error: "resource is verplicht" };
|
|
6
|
+
}
|
|
7
|
+
const limit = Math.min(Math.max(body.limit ?? 500, 1), 5000);
|
|
8
|
+
const offset = Math.max(body.offset ?? 0, 0);
|
|
9
|
+
let q = supabase
|
|
10
|
+
.from("floricode_records")
|
|
11
|
+
.select("resource, record_id, payload, updated_at, last_seen_at", { count: "exact" })
|
|
12
|
+
.eq("resource", body.resource);
|
|
13
|
+
if (body.recordIds && body.recordIds.length > 0) {
|
|
14
|
+
q = q.in("record_id", body.recordIds);
|
|
15
|
+
}
|
|
16
|
+
if (body.since) {
|
|
17
|
+
q = q.gte("updated_at", body.since);
|
|
18
|
+
}
|
|
19
|
+
q = q.order("updated_at", { ascending: true }).range(offset, offset + limit - 1);
|
|
20
|
+
const { data, error, count } = await q;
|
|
21
|
+
if (error)
|
|
22
|
+
return { ok: false, error: error.message };
|
|
23
|
+
return {
|
|
24
|
+
ok: true,
|
|
25
|
+
resource: body.resource,
|
|
26
|
+
rows: data ?? [],
|
|
27
|
+
count: count ?? null,
|
|
28
|
+
offset,
|
|
29
|
+
limit,
|
|
30
|
+
nextOffset: (data?.length ?? 0) === limit ? offset + limit : null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface FulfillmentOrderSendResult {
|
|
3
|
+
status: number;
|
|
4
|
+
payload: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare function runFulfillmentOrderSend(supabase: SupabaseClient, body: any, caller: string): Promise<FulfillmentOrderSendResult>;
|
|
7
|
+
//# sourceMappingURL=fulfillment-order-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fulfillment-order-send.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/fulfillment-order-send.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAkB5D,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,0BAA0B,CAAC,CA8GrC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Gateway module: verstuur fulfillment-order (2026v1).
|
|
2
|
+
// Spiegel van src/routes/api/public/gateway/fulfillment-order.send.ts.
|
|
3
|
+
import { resolveGatewayEnvironment } from "./shared";
|
|
4
|
+
import { florydayWrite, getActiveFlorydayCredentials } from "../floriday.functions";
|
|
5
|
+
function extractPackageCount(req) {
|
|
6
|
+
const candidates = [
|
|
7
|
+
req?.numberOfPackages,
|
|
8
|
+
req?.packageCount,
|
|
9
|
+
req?.numberOfLoadCarriers,
|
|
10
|
+
req?.quantity,
|
|
11
|
+
];
|
|
12
|
+
for (const c of candidates) {
|
|
13
|
+
const n = Number(c);
|
|
14
|
+
if (Number.isFinite(n) && n > 0)
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
export async function runFulfillmentOrderSend(supabase, body, caller) {
|
|
20
|
+
const deliveryOrderId = String(body?.deliveryOrderId ?? "").trim();
|
|
21
|
+
const explicitLoadCarrierItems = Array.isArray(body?.loadCarrierItems)
|
|
22
|
+
? body.loadCarrierItems
|
|
23
|
+
: null;
|
|
24
|
+
const env = await resolveGatewayEnvironment(supabase, body?.environment);
|
|
25
|
+
const conn = await getActiveFlorydayCredentials(supabase, env);
|
|
26
|
+
if (!conn) {
|
|
27
|
+
return {
|
|
28
|
+
status: 400,
|
|
29
|
+
payload: { ok: false, error: `Geen actieve Floriday-koppeling voor ${env}` },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// Idempotency: is er al een fulfillment-order voor deze delivery?
|
|
33
|
+
if (deliveryOrderId) {
|
|
34
|
+
const { data: existing } = await supabase
|
|
35
|
+
.from("floriday_fulfillment_orders_cache")
|
|
36
|
+
.select("floriday_id")
|
|
37
|
+
.eq("connection_id", conn.id)
|
|
38
|
+
.eq("delivery_order_id", deliveryOrderId)
|
|
39
|
+
.maybeSingle();
|
|
40
|
+
if (existing?.floriday_id) {
|
|
41
|
+
return {
|
|
42
|
+
status: 200,
|
|
43
|
+
payload: {
|
|
44
|
+
ok: true,
|
|
45
|
+
skipped: true,
|
|
46
|
+
fulfillmentOrderId: existing.floriday_id,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Body opbouwen — hetzij passthrough, hetzij vanuit cache.
|
|
52
|
+
let loadCarrierItems = explicitLoadCarrierItems;
|
|
53
|
+
if (!loadCarrierItems) {
|
|
54
|
+
const { data: doRow } = await supabase
|
|
55
|
+
.from("floriday_delivery_orders_cache")
|
|
56
|
+
.select("floriday_id, data")
|
|
57
|
+
.eq("connection_id", conn.id)
|
|
58
|
+
.eq("floriday_id", deliveryOrderId)
|
|
59
|
+
.maybeSingle();
|
|
60
|
+
if (!doRow) {
|
|
61
|
+
return {
|
|
62
|
+
status: 404,
|
|
63
|
+
payload: { ok: false, error: "Delivery-order niet in cache — sync eerst" },
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const allRequests = Array.isArray(doRow.data?.fulfillmentRequests)
|
|
67
|
+
? doRow.data.fulfillmentRequests
|
|
68
|
+
: [];
|
|
69
|
+
const filterIds = Array.isArray(body?.fulfillmentRequestIds)
|
|
70
|
+
? body.fulfillmentRequestIds.map((s) => String(s))
|
|
71
|
+
: null;
|
|
72
|
+
const requests = allRequests
|
|
73
|
+
.filter((r) => {
|
|
74
|
+
const id = r?.fulfillmentRequestId ?? r?.id;
|
|
75
|
+
return !filterIds || filterIds.includes(String(id));
|
|
76
|
+
})
|
|
77
|
+
.map((r) => {
|
|
78
|
+
const id = r?.fulfillmentRequestId ?? r?.id;
|
|
79
|
+
if (!id)
|
|
80
|
+
return null;
|
|
81
|
+
return {
|
|
82
|
+
deliveryOrderId,
|
|
83
|
+
fulfillmentRequestId: id,
|
|
84
|
+
numberOfPackages: extractPackageCount(r),
|
|
85
|
+
};
|
|
86
|
+
})
|
|
87
|
+
.filter(Boolean);
|
|
88
|
+
if (requests.length === 0) {
|
|
89
|
+
return {
|
|
90
|
+
status: 400,
|
|
91
|
+
payload: {
|
|
92
|
+
ok: false,
|
|
93
|
+
error: "Geen fulfillmentRequests gevonden in delivery-order",
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
loadCarrierItems = [{ fulfillmentRequests: requests }];
|
|
98
|
+
}
|
|
99
|
+
const result = await florydayWrite(supabase, env, {
|
|
100
|
+
module: "auto-process",
|
|
101
|
+
action: "send-fulfillment-order",
|
|
102
|
+
method: "POST",
|
|
103
|
+
path: "/fulfillment-orders",
|
|
104
|
+
body: { loadCarrierItems },
|
|
105
|
+
referenceId: deliveryOrderId || "batch",
|
|
106
|
+
idempotencyKey: deliveryOrderId
|
|
107
|
+
? `do:${deliveryOrderId}:fulfillment-order`
|
|
108
|
+
: undefined,
|
|
109
|
+
caller,
|
|
110
|
+
});
|
|
111
|
+
const fulfillmentOrderId = result.data?.fulfillmentOrderId ??
|
|
112
|
+
result.data?.id ??
|
|
113
|
+
result.data?.floridayId;
|
|
114
|
+
return {
|
|
115
|
+
status: result.ok ? 200 : 502,
|
|
116
|
+
payload: {
|
|
117
|
+
ok: result.ok,
|
|
118
|
+
skipped: false,
|
|
119
|
+
fulfillmentOrderId,
|
|
120
|
+
error: result.error,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
export * from "./shared";
|
|
2
2
|
export * from "./cache-tables";
|
|
3
3
|
export * from "./cached-list";
|
|
4
|
+
export * from "./active-environment";
|
|
5
|
+
export * from "./floricode-records";
|
|
6
|
+
export * from "./product-characteristics";
|
|
7
|
+
export * from "./code-list";
|
|
8
|
+
export * from "./schema";
|
|
9
|
+
export * from "./pdf";
|
|
10
|
+
export * from "./pdf-bulk";
|
|
11
|
+
export * from "./pdf-bulk-merged";
|
|
12
|
+
export * from "./write";
|
|
13
|
+
export * from "./fulfillment-order-send";
|
|
14
|
+
export * from "./diagnostics";
|
|
15
|
+
export * from "./media";
|
|
16
|
+
export * from "./media-upload";
|
|
17
|
+
export * from "./supply-line";
|
|
4
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
1
|
export * from "./shared";
|
|
2
2
|
export * from "./cache-tables";
|
|
3
3
|
export * from "./cached-list";
|
|
4
|
+
export * from "./active-environment";
|
|
5
|
+
export * from "./floricode-records";
|
|
6
|
+
export * from "./product-characteristics";
|
|
7
|
+
export * from "./code-list";
|
|
8
|
+
export * from "./schema";
|
|
9
|
+
export * from "./pdf";
|
|
10
|
+
export * from "./pdf-bulk";
|
|
11
|
+
export * from "./pdf-bulk-merged";
|
|
12
|
+
export * from "./write";
|
|
13
|
+
export * from "./fulfillment-order-send";
|
|
14
|
+
export * from "./diagnostics";
|
|
15
|
+
export * from "./media";
|
|
16
|
+
export * from "./media-upload";
|
|
17
|
+
export * from "./supply-line";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { type FlorydayEnvironment } from "../floriday.functions";
|
|
3
|
+
export interface MediaUploadInput {
|
|
4
|
+
bytes: Uint8Array;
|
|
5
|
+
environment: FlorydayEnvironment;
|
|
6
|
+
path: string;
|
|
7
|
+
method: "POST" | "PUT";
|
|
8
|
+
fileName: string;
|
|
9
|
+
contentType: string;
|
|
10
|
+
formField: string;
|
|
11
|
+
referenceId: string | null;
|
|
12
|
+
idempotencyKey: string | null;
|
|
13
|
+
extraFields: Record<string, string> | null;
|
|
14
|
+
caller: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MediaUploadResult {
|
|
17
|
+
status: number;
|
|
18
|
+
payload: unknown;
|
|
19
|
+
}
|
|
20
|
+
export declare function runMediaUpload(supabase: SupabaseClient, input: MediaUploadInput): Promise<MediaUploadResult>;
|
|
21
|
+
//# sourceMappingURL=media-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-upload.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/media-upload.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,mBAAmB,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAyG5B"}
|