@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.
Files changed (65) hide show
  1. package/dist-lib/components/settings/FloricodeSettingsCard.js +1 -1
  2. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  3. package/dist-lib/integrations/supabase/client.server.js +1 -0
  4. package/dist-lib/lib/central-auth.server.d.ts +17 -0
  5. package/dist-lib/lib/central-auth.server.d.ts.map +1 -1
  6. package/dist-lib/lib/central-auth.server.js +40 -0
  7. package/dist-lib/lib/floricode-credentials.server.d.ts.map +1 -1
  8. package/dist-lib/lib/floricode-credentials.server.js +94 -26
  9. package/dist-lib/lib/floricode.functions.d.ts +1 -0
  10. package/dist-lib/lib/floricode.functions.d.ts.map +1 -1
  11. package/dist-lib/lib/floricode.functions.js +13 -0
  12. package/dist-lib/lib/floriday-sync.functions.d.ts.map +1 -1
  13. package/dist-lib/lib/floriday-sync.functions.js +2 -1
  14. package/dist-lib/lib/floriday.functions.d.ts +144 -19
  15. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  16. package/dist-lib/lib/floriday.functions.js +24 -14
  17. package/dist-lib/lib/gateway/active-environment.d.ts +7 -0
  18. package/dist-lib/lib/gateway/active-environment.d.ts.map +1 -0
  19. package/dist-lib/lib/gateway/active-environment.js +8 -0
  20. package/dist-lib/lib/gateway/code-list.d.ts +16 -0
  21. package/dist-lib/lib/gateway/code-list.d.ts.map +1 -0
  22. package/dist-lib/lib/gateway/code-list.js +28 -0
  23. package/dist-lib/lib/gateway/diagnostics.d.ts +13 -0
  24. package/dist-lib/lib/gateway/diagnostics.d.ts.map +1 -0
  25. package/dist-lib/lib/gateway/diagnostics.js +66 -0
  26. package/dist-lib/lib/gateway/floricode-records.d.ts +22 -0
  27. package/dist-lib/lib/gateway/floricode-records.d.ts.map +1 -0
  28. package/dist-lib/lib/gateway/floricode-records.js +32 -0
  29. package/dist-lib/lib/gateway/fulfillment-order-send.d.ts +7 -0
  30. package/dist-lib/lib/gateway/fulfillment-order-send.d.ts.map +1 -0
  31. package/dist-lib/lib/gateway/fulfillment-order-send.js +123 -0
  32. package/dist-lib/lib/gateway/index.d.ts +14 -0
  33. package/dist-lib/lib/gateway/index.d.ts.map +1 -1
  34. package/dist-lib/lib/gateway/index.js +14 -0
  35. package/dist-lib/lib/gateway/media-upload.d.ts +21 -0
  36. package/dist-lib/lib/gateway/media-upload.d.ts.map +1 -0
  37. package/dist-lib/lib/gateway/media-upload.js +96 -0
  38. package/dist-lib/lib/gateway/media.d.ts +19 -0
  39. package/dist-lib/lib/gateway/media.d.ts.map +1 -0
  40. package/dist-lib/lib/gateway/media.js +96 -0
  41. package/dist-lib/lib/gateway/pdf-bulk-merged.d.ts +34 -0
  42. package/dist-lib/lib/gateway/pdf-bulk-merged.d.ts.map +1 -0
  43. package/dist-lib/lib/gateway/pdf-bulk-merged.js +80 -0
  44. package/dist-lib/lib/gateway/pdf-bulk.d.ts +31 -0
  45. package/dist-lib/lib/gateway/pdf-bulk.d.ts.map +1 -0
  46. package/dist-lib/lib/gateway/pdf-bulk.js +65 -0
  47. package/dist-lib/lib/gateway/pdf.d.ts +24 -0
  48. package/dist-lib/lib/gateway/pdf.d.ts.map +1 -0
  49. package/dist-lib/lib/gateway/pdf.js +64 -0
  50. package/dist-lib/lib/gateway/product-characteristics.d.ts +18 -0
  51. package/dist-lib/lib/gateway/product-characteristics.d.ts.map +1 -0
  52. package/dist-lib/lib/gateway/product-characteristics.js +8 -0
  53. package/dist-lib/lib/gateway/schema.d.ts +28 -0
  54. package/dist-lib/lib/gateway/schema.d.ts.map +1 -0
  55. package/dist-lib/lib/gateway/schema.js +102 -0
  56. package/dist-lib/lib/gateway/shared.d.ts +5 -1
  57. package/dist-lib/lib/gateway/shared.d.ts.map +1 -1
  58. package/dist-lib/lib/gateway/shared.js +7 -3
  59. package/dist-lib/lib/gateway/supply-line.d.ts +11 -0
  60. package/dist-lib/lib/gateway/supply-line.d.ts.map +1 -0
  61. package/dist-lib/lib/gateway/supply-line.js +261 -0
  62. package/dist-lib/lib/gateway/write.d.ts +18 -0
  63. package/dist-lib/lib/gateway/write.d.ts.map +1 -0
  64. package/dist-lib/lib/gateway/write.js +32 -0
  65. package/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ // Gateway module: multipart binary media-upload (streaming bytes).
2
+ // Spiegel van src/routes/api/public/gateway/media-upload.ts.
3
+ import { florydayFetch, getActiveFlorydayCredentials, } from "../floriday.functions";
4
+ export async function runMediaUpload(supabase, input) {
5
+ const conn = await getActiveFlorydayCredentials(supabase, input.environment);
6
+ if (!conn) {
7
+ return {
8
+ status: 200,
9
+ payload: {
10
+ ok: false,
11
+ error: `Geen actieve Floriday-koppeling voor ${input.environment}`,
12
+ },
13
+ };
14
+ }
15
+ const blob = new Blob([
16
+ input.bytes.buffer.slice(input.bytes.byteOffset, input.bytes.byteOffset + input.bytes.byteLength),
17
+ ], { type: input.contentType });
18
+ const form = new FormData();
19
+ form.append(input.formField, blob, input.fileName);
20
+ if (input.extraFields) {
21
+ for (const [k, v] of Object.entries(input.extraFields)) {
22
+ form.append(k, String(v));
23
+ }
24
+ }
25
+ let status = 0;
26
+ let parsed = null;
27
+ let ok = false;
28
+ let errMsg;
29
+ try {
30
+ const res = await florydayFetch(supabase, input.environment, input.path, {
31
+ method: input.method,
32
+ body: form,
33
+ // Géén Content-Type meegeven: fetch genereert zelf de
34
+ // multipart-boundary.
35
+ });
36
+ status = res.status;
37
+ const text = await res.text().catch(() => "");
38
+ try {
39
+ parsed = text ? JSON.parse(text) : null;
40
+ }
41
+ catch {
42
+ parsed = text;
43
+ }
44
+ ok = res.ok;
45
+ if (!ok) {
46
+ errMsg = `Floriday ${status}: ${text.slice(0, 300)}`;
47
+ }
48
+ }
49
+ catch (e) {
50
+ errMsg = String(e?.message ?? e);
51
+ // Best-effort: trek de upstream-status uit foutboodschappen als
52
+ // "Floriday 403: ..." of "Floriday weigert POST /x (403 Forbidden)"
53
+ // zodat http_status in de log niet altijd 0 is.
54
+ const m = errMsg.match(/\b(\d{3})\b/);
55
+ if (m) {
56
+ const n = Number(m[1]);
57
+ if (n >= 400 && n < 600)
58
+ status = n;
59
+ }
60
+ }
61
+ const { data: inserted } = await supabase
62
+ .from("floriday_write_log")
63
+ .insert({
64
+ connection_id: conn.id,
65
+ module: input.caller,
66
+ action: "upload-media",
67
+ resource: "media",
68
+ floriday_id: input.referenceId ?? null,
69
+ request: {
70
+ fileName: input.fileName,
71
+ contentType: input.contentType,
72
+ bytes: input.bytes.byteLength,
73
+ path: input.path,
74
+ method: input.method,
75
+ extraFields: input.extraFields,
76
+ },
77
+ response: parsed,
78
+ http_status: status,
79
+ ok,
80
+ error: errMsg ?? null,
81
+ idempotency_key: input.idempotencyKey,
82
+ caller: input.caller,
83
+ })
84
+ .select("id")
85
+ .maybeSingle();
86
+ return {
87
+ status: 200,
88
+ payload: {
89
+ ok,
90
+ status,
91
+ data: parsed,
92
+ attemptId: inserted?.id ?? null,
93
+ error: errMsg,
94
+ },
95
+ };
96
+ }
@@ -0,0 +1,19 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ import { type FlorydayEnvironment } from "../floriday.functions";
3
+ export interface MediaBody {
4
+ environment: FlorydayEnvironment;
5
+ path: string;
6
+ method?: "POST" | "PUT";
7
+ fileName: string;
8
+ contentType: string;
9
+ dataBase64: string;
10
+ formField?: string;
11
+ extraFields?: Record<string, string>;
12
+ referenceId?: string;
13
+ }
14
+ export interface MediaResult {
15
+ status: number;
16
+ payload: unknown;
17
+ }
18
+ export declare function runMedia(supabase: SupabaseClient, body: MediaBody, caller: string): Promise<MediaResult>;
19
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/media.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,SAAS;IACxB,WAAW,EAAE,mBAAmB,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,CA6FtB"}
@@ -0,0 +1,96 @@
1
+ // Gateway module: media-upload via JSON+Base64.
2
+ // Spiegel van src/routes/api/public/gateway/media.ts.
3
+ import { florydayFetch, getActiveFlorydayCredentials, } from "../floriday.functions";
4
+ function decodeBase64(b64) {
5
+ const clean = b64.includes(",") ? b64.split(",", 2)[1] ?? "" : b64;
6
+ const binary = atob(clean);
7
+ const out = new Uint8Array(binary.length);
8
+ for (let i = 0; i < binary.length; i++)
9
+ out[i] = binary.charCodeAt(i);
10
+ return out;
11
+ }
12
+ export async function runMedia(supabase, body, caller) {
13
+ const method = body.method ?? "POST";
14
+ const fieldName = body.formField ?? "file";
15
+ const conn = await getActiveFlorydayCredentials(supabase, body.environment);
16
+ if (!conn) {
17
+ return {
18
+ status: 200,
19
+ payload: {
20
+ ok: false,
21
+ error: `Geen actieve Floriday-koppeling voor ${body.environment}`,
22
+ },
23
+ };
24
+ }
25
+ const bytes = decodeBase64(body.dataBase64);
26
+ const blob = new Blob([bytes.buffer], { type: body.contentType });
27
+ const form = new FormData();
28
+ form.append(fieldName, blob, body.fileName);
29
+ if (body.extraFields) {
30
+ for (const [k, v] of Object.entries(body.extraFields)) {
31
+ form.append(k, String(v));
32
+ }
33
+ }
34
+ let status = 0;
35
+ let parsed = null;
36
+ let ok = false;
37
+ let errMsg;
38
+ try {
39
+ const res = await florydayFetch(supabase, body.environment, body.path, {
40
+ method,
41
+ body: form,
42
+ // Belangrijk: géén Content-Type meegeven, anders ontbreekt de
43
+ // multipart-boundary die fetch automatisch genereert.
44
+ });
45
+ status = res.status;
46
+ const text = await res.text().catch(() => "");
47
+ try {
48
+ parsed = text ? JSON.parse(text) : null;
49
+ }
50
+ catch {
51
+ parsed = text;
52
+ }
53
+ ok = res.ok;
54
+ if (!ok) {
55
+ errMsg = `Floriday ${status}: ${text.slice(0, 300)}`;
56
+ }
57
+ }
58
+ catch (e) {
59
+ errMsg = String(e?.message ?? e);
60
+ }
61
+ const { data: inserted } = await supabase
62
+ .from("floriday_write_log")
63
+ .insert({
64
+ connection_id: conn.id,
65
+ module: "media",
66
+ action: `${method} ${body.path}`,
67
+ resource: "media",
68
+ floriday_id: body.referenceId ?? null,
69
+ request: {
70
+ fileName: body.fileName,
71
+ contentType: body.contentType,
72
+ bytes: bytes.byteLength,
73
+ path: body.path,
74
+ method,
75
+ extraFields: body.extraFields ?? null,
76
+ },
77
+ response: parsed,
78
+ http_status: status,
79
+ ok,
80
+ error: errMsg ?? null,
81
+ idempotency_key: null,
82
+ caller,
83
+ })
84
+ .select("id")
85
+ .maybeSingle();
86
+ return {
87
+ status: 200,
88
+ payload: {
89
+ ok,
90
+ status,
91
+ data: parsed,
92
+ attemptId: inserted?.id ?? null,
93
+ error: errMsg,
94
+ },
95
+ };
96
+ }
@@ -0,0 +1,34 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ export interface PdfBulkMergedItem {
3
+ id?: string;
4
+ fulfillmentOrderId?: string;
5
+ deliveryOrderId?: string;
6
+ salesOrderId?: string;
7
+ logisticLabelCode?: string;
8
+ }
9
+ export interface PdfBulkMergedInput {
10
+ environment?: "staging" | "live";
11
+ items: PdfBulkMergedItem[];
12
+ onError?: "skip" | "fail";
13
+ }
14
+ export interface PdfBulkMergedSkipped {
15
+ index: number;
16
+ id: string | null;
17
+ error: string;
18
+ }
19
+ export type PdfBulkMergedResult = {
20
+ ok: true;
21
+ contentType: "application/pdf";
22
+ included: number;
23
+ skipped: PdfBulkMergedSkipped[];
24
+ pdfBase64: string;
25
+ } | {
26
+ ok: false;
27
+ status: 502;
28
+ error: string;
29
+ failedIndex?: number;
30
+ id?: string | null;
31
+ skipped?: PdfBulkMergedSkipped[];
32
+ };
33
+ export declare function runPdfBulkMerged(supabase: SupabaseClient, parsed: PdfBulkMergedInput, environment: "staging" | "live"): Promise<PdfBulkMergedResult>;
34
+ //# sourceMappingURL=pdf-bulk-merged.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-bulk-merged.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/pdf-bulk-merged.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,mBAAmB,GAC3B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,iBAAiB,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,GAAG,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClC,CAAC;AASN,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,SAAS,GAAG,MAAM,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAwE9B"}
@@ -0,0 +1,80 @@
1
+ // Gateway business-logica voor /api/public/gateway/pdf/bulk-merged.
2
+ // Verplaatst uit de route; byte-identiek gedrag.
3
+ // Adapter resolvet environment vooraf (409-catch) en geeft die mee.
4
+ import { PDFDocument } from "pdf-lib";
5
+ import { resolveFulfillmentOrderIds, resolveLogisticLabel } from "./shared";
6
+ async function downloadPdfBytes(url) {
7
+ const res = await fetch(url);
8
+ if (!res.ok)
9
+ throw new Error(`download mislukt (${res.status})`);
10
+ const buf = await res.arrayBuffer();
11
+ return new Uint8Array(buf);
12
+ }
13
+ export async function runPdfBulkMerged(supabase, parsed, environment) {
14
+ const onError = parsed.onError ?? "skip";
15
+ const merged = await PDFDocument.create();
16
+ const skipped = [];
17
+ let included = 0;
18
+ // Sequentieel om de rate-limit en cache-hits netjes te benutten.
19
+ for (let i = 0; i < parsed.items.length; i++) {
20
+ const item = parsed.items[i];
21
+ const clientId = item.id ?? null;
22
+ try {
23
+ // 1) Resolve fulfillmentOrderId(s)
24
+ let fulfillmentIds = [];
25
+ if (item.fulfillmentOrderId?.trim()) {
26
+ fulfillmentIds = [item.fulfillmentOrderId.trim()];
27
+ }
28
+ else {
29
+ const lookup = await resolveFulfillmentOrderIds(supabase, {
30
+ environment,
31
+ deliveryOrderId: item.deliveryOrderId,
32
+ salesOrderId: item.salesOrderId,
33
+ });
34
+ fulfillmentIds = lookup.fulfillmentOrderIds;
35
+ }
36
+ if (fulfillmentIds.length === 0) {
37
+ throw new Error("geen fulfillmentOrderId gevonden");
38
+ }
39
+ // 2) Per fulfillment-order het label ophalen en pagina's mergen
40
+ for (const fid of fulfillmentIds) {
41
+ const label = await resolveLogisticLabel(supabase, {
42
+ environment,
43
+ fulfillmentOrderId: fid,
44
+ logisticLabelCode: item.logisticLabelCode ?? null,
45
+ });
46
+ const bytes = await downloadPdfBytes(label.url);
47
+ const src = await PDFDocument.load(bytes, { ignoreEncryption: true });
48
+ const pages = await merged.copyPages(src, src.getPageIndices());
49
+ for (const p of pages)
50
+ merged.addPage(p);
51
+ included++;
52
+ }
53
+ }
54
+ catch (e) {
55
+ const error = String(e?.message ?? e);
56
+ if (onError === "fail") {
57
+ return { ok: false, status: 502, error, failedIndex: i, id: clientId };
58
+ }
59
+ skipped.push({ index: i, id: clientId, error });
60
+ }
61
+ }
62
+ if (included === 0) {
63
+ return {
64
+ ok: false,
65
+ status: 502,
66
+ error: "geen afleverbrieven kunnen ophalen",
67
+ skipped,
68
+ };
69
+ }
70
+ const bytes = await merged.save();
71
+ // Base64 encode (Worker: Buffer is beschikbaar via nodejs_compat)
72
+ const pdfBase64 = Buffer.from(bytes).toString("base64");
73
+ return {
74
+ ok: true,
75
+ contentType: "application/pdf",
76
+ included,
77
+ skipped,
78
+ pdfBase64,
79
+ };
80
+ }
@@ -0,0 +1,31 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ export interface PdfBulkItem {
3
+ id?: string;
4
+ fulfillmentOrderId?: string;
5
+ deliveryOrderId?: string;
6
+ salesOrderId?: string;
7
+ logisticLabelCode?: string;
8
+ }
9
+ export interface PdfBulkInput {
10
+ environment?: "staging" | "live";
11
+ items: PdfBulkItem[];
12
+ }
13
+ export interface PdfBulkItemResult {
14
+ id: string | null;
15
+ ok: boolean;
16
+ url?: string;
17
+ expiresAt?: string;
18
+ contentType?: string;
19
+ fulfillmentOrderId?: string;
20
+ logisticLabelCode?: string;
21
+ error?: string;
22
+ }
23
+ export interface PdfBulkResult {
24
+ ok: true;
25
+ total: number;
26
+ success: number;
27
+ failed: number;
28
+ results: PdfBulkItemResult[];
29
+ }
30
+ export declare function runPdfBulk(supabase: SupabaseClient, parsed: PdfBulkInput, environment: "staging" | "live"): Promise<PdfBulkResult>;
31
+ //# sourceMappingURL=pdf-bulk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-bulk.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/pdf-bulk.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,SAAS,GAAG,MAAM,GAC9B,OAAO,CAAC,aAAa,CAAC,CA4DxB"}
@@ -0,0 +1,65 @@
1
+ // Gateway business-logica voor /api/public/gateway/pdf/bulk.
2
+ // Verplaatst uit de route; byte-identiek gedrag.
3
+ // Adapter resolvet environment vooraf (409-catch) en geeft die mee.
4
+ import { resolveFulfillmentOrderIds, resolveLogisticLabel } from "./shared";
5
+ export async function runPdfBulk(supabase, parsed, environment) {
6
+ const results = [];
7
+ for (const item of parsed.items) {
8
+ const clientId = item.id ?? null;
9
+ try {
10
+ let fulfillmentOrderId = item.fulfillmentOrderId?.trim() ?? "";
11
+ if (!fulfillmentOrderId) {
12
+ const lookup = await resolveFulfillmentOrderIds(supabase, {
13
+ environment,
14
+ deliveryOrderId: item.deliveryOrderId,
15
+ salesOrderId: item.salesOrderId,
16
+ });
17
+ // Bij meerdere fulfillment-orders per delivery-order: alle
18
+ // labels ophalen; we voegen elke variant apart toe.
19
+ if (lookup.fulfillmentOrderIds.length > 1) {
20
+ for (const fid of lookup.fulfillmentOrderIds) {
21
+ try {
22
+ const r = await resolveLogisticLabel(supabase, {
23
+ environment,
24
+ fulfillmentOrderId: fid,
25
+ logisticLabelCode: item.logisticLabelCode ?? null,
26
+ });
27
+ results.push({ id: clientId, ok: true, ...r });
28
+ }
29
+ catch (e) {
30
+ results.push({
31
+ id: clientId,
32
+ ok: false,
33
+ fulfillmentOrderId: fid,
34
+ error: String(e?.message ?? e),
35
+ });
36
+ }
37
+ }
38
+ continue;
39
+ }
40
+ fulfillmentOrderId = lookup.fulfillmentOrderIds[0];
41
+ }
42
+ const r = await resolveLogisticLabel(supabase, {
43
+ environment,
44
+ fulfillmentOrderId,
45
+ logisticLabelCode: item.logisticLabelCode ?? null,
46
+ });
47
+ results.push({ id: clientId, ok: true, ...r });
48
+ }
49
+ catch (e) {
50
+ results.push({
51
+ id: clientId,
52
+ ok: false,
53
+ error: String(e?.message ?? e),
54
+ });
55
+ }
56
+ }
57
+ const okCount = results.filter((r) => r.ok).length;
58
+ return {
59
+ ok: true,
60
+ total: results.length,
61
+ success: okCount,
62
+ failed: results.length - okCount,
63
+ results,
64
+ };
65
+ }
@@ -0,0 +1,24 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ type Kind = "logistic-label" | "delivery-note" | "auction-letter" | "customer-sticker";
3
+ export interface PdfInput {
4
+ environment?: "staging" | "live";
5
+ kind: Kind;
6
+ fulfillmentOrderId?: string;
7
+ deliveryOrderId?: string;
8
+ salesOrderId?: string;
9
+ logisticLabelCode?: string;
10
+ clockSupplyId?: string;
11
+ auctionLetterCode?: string;
12
+ stickerId?: string;
13
+ }
14
+ export type PdfResult = ({
15
+ ok: true;
16
+ } & Record<string, any>) | {
17
+ ok: false;
18
+ status?: number;
19
+ error: string;
20
+ fulfillmentOrderIds?: string[];
21
+ };
22
+ export declare function runPdf(supabase: SupabaseClient, parsed: PdfInput, environment: "staging" | "live"): Promise<PdfResult>;
23
+ export {};
24
+ //# sourceMappingURL=pdf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/pdf.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,KAAK,IAAI,GACL,gBAAgB,GAChB,eAAe,GACf,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,QAAQ;IACvB,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GACjB,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GACpC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC;AAEN,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,QAAQ,EAChB,WAAW,EAAE,SAAS,GAAG,MAAM,GAC9B,OAAO,CAAC,SAAS,CAAC,CAoEpB"}
@@ -0,0 +1,64 @@
1
+ // Gateway business-logica voor /api/public/gateway/pdf.
2
+ // Verplaatst uit de route; byte-identiek gedrag.
3
+ // De adapter resolvet environment vooraf (409-catch) en geeft die mee.
4
+ import { resolveFulfillmentOrderIds, resolveLogisticLabel } from "./shared";
5
+ export async function runPdf(supabase, parsed, environment) {
6
+ if (parsed.kind === "logistic-label" || parsed.kind === "delivery-note") {
7
+ // Voor "delivery-note" mag de caller ook via deliveryOrderId of
8
+ // salesOrderId komen; we lossen die dan hier centraal op.
9
+ let fulfillmentOrderId = parsed.fulfillmentOrderId?.trim() ?? "";
10
+ if (!fulfillmentOrderId) {
11
+ if (!parsed.deliveryOrderId && !parsed.salesOrderId) {
12
+ return {
13
+ ok: false,
14
+ status: 400,
15
+ error: "Geef ten minste één van fulfillmentOrderId, deliveryOrderId of salesOrderId op",
16
+ };
17
+ }
18
+ const lookup = await resolveFulfillmentOrderIds(supabase, {
19
+ environment,
20
+ deliveryOrderId: parsed.deliveryOrderId,
21
+ salesOrderId: parsed.salesOrderId,
22
+ });
23
+ if (lookup.fulfillmentOrderIds.length > 1) {
24
+ return {
25
+ ok: false,
26
+ status: 409,
27
+ error: `Meerdere fulfillment-orders gevonden (${lookup.fulfillmentOrderIds.length}); gebruik /gateway/pdf/bulk of geef een specifieke fulfillmentOrderId op`,
28
+ fulfillmentOrderIds: lookup.fulfillmentOrderIds,
29
+ };
30
+ }
31
+ fulfillmentOrderId = lookup.fulfillmentOrderIds[0];
32
+ }
33
+ const result = await resolveLogisticLabel(supabase, {
34
+ environment,
35
+ fulfillmentOrderId,
36
+ logisticLabelCode: parsed.logisticLabelCode ?? null,
37
+ });
38
+ return { ok: true, ...result };
39
+ }
40
+ if (parsed.kind === "auction-letter") {
41
+ if (!parsed.clockSupplyId) {
42
+ return { ok: false, status: 400, error: "clockSupplyId is verplicht" };
43
+ }
44
+ const { resolveAuctionLetter } = await import("../floriday-auction-letters.functions");
45
+ const result = await resolveAuctionLetter(supabase, {
46
+ environment,
47
+ clockSupplyId: parsed.clockSupplyId,
48
+ auctionLetterCode: parsed.auctionLetterCode ?? null,
49
+ });
50
+ return { ok: true, ...result };
51
+ }
52
+ if (parsed.kind === "customer-sticker") {
53
+ if (!parsed.stickerId) {
54
+ return { ok: false, status: 400, error: "stickerId is verplicht" };
55
+ }
56
+ const { resolveCustomerSticker } = await import("../floriday-stickers.functions");
57
+ const result = await resolveCustomerSticker(supabase, {
58
+ environment,
59
+ stickerId: parsed.stickerId,
60
+ });
61
+ return { ok: true, ...result };
62
+ }
63
+ return { ok: false, status: 400, error: `Onbekend kind: ${parsed.kind}` };
64
+ }
@@ -0,0 +1,18 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ import type { FlorydayEnvironment } from "./shared";
3
+ export interface ProductCharacteristicsInput {
4
+ environment: FlorydayEnvironment;
5
+ productCode?: string | number;
6
+ vbnProductCode?: string | number;
7
+ forceRefresh?: boolean;
8
+ }
9
+ export declare function runProductCharacteristics(supabase: SupabaseClient, parsed: ProductCharacteristicsInput): Promise<{
10
+ ok: true;
11
+ productCode: string;
12
+ productGroupId: string | null;
13
+ productName: string | null;
14
+ source: "cache" | "floricode-live";
15
+ codeListName: "vbn-product-characteristic";
16
+ characteristics: import("../floricode-product-features").ProductCharacteristic[];
17
+ }>;
18
+ //# sourceMappingURL=product-characteristics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-characteristics.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/product-characteristics.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,mBAAmB,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,2BAA2B;;;;;;;;GAYpC"}
@@ -0,0 +1,8 @@
1
+ // Gateway business-logica voor /api/public/gateway/product-characteristics.
2
+ // Optie B: validatie-guards + statuscodes blijven in de adapter (byte-identiek
3
+ // aan HEAD). Deze module doet alleen de resolve-call.
4
+ export async function runProductCharacteristics(supabase, parsed) {
5
+ const { getProductCharacteristicsForVbnCode } = await import("../floricode-product-features");
6
+ const productCode = parsed.productCode ?? parsed.vbnProductCode;
7
+ return await getProductCharacteristicsForVbnCode(supabase, parsed.environment, productCode, { forceRefresh: parsed.forceRefresh === true });
8
+ }
@@ -0,0 +1,28 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ export interface SchemaInput {
3
+ resource: string;
4
+ version?: string;
5
+ includeCodeLists?: string[];
6
+ environment?: "staging" | "live";
7
+ }
8
+ export type SchemaResult = {
9
+ ok: true;
10
+ resource: string;
11
+ version: string;
12
+ schema: any;
13
+ enums: any;
14
+ requiredFields: string[];
15
+ fields: Array<Record<string, any>>;
16
+ fetched_at: string;
17
+ codeLists?: Record<string, Array<{
18
+ code: string;
19
+ label: string | null;
20
+ payload: any;
21
+ }>>;
22
+ } | {
23
+ ok: false;
24
+ error: string;
25
+ status?: number;
26
+ };
27
+ export declare function runSchema(supabase: SupabaseClient, parsed: SchemaInput): Promise<SchemaResult>;
28
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAClC;AAkCD,MAAM,MAAM,YAAY,GACpB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC;IACZ,KAAK,EAAE,GAAG,CAAC;IACX,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC,CAAC;CACzF,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,CAAC,CAwEvB"}