@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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Gateway business-logica voor /api/public/gateway/schema.
|
|
2
|
+
// Verplaatst uit de route; byte-identiek gedrag.
|
|
3
|
+
async function fetchAllIncludedCodeLists(supabaseAdmin, environment, names) {
|
|
4
|
+
const pageSize = 1000;
|
|
5
|
+
const codeLists = {};
|
|
6
|
+
for (const n of names)
|
|
7
|
+
codeLists[n] = [];
|
|
8
|
+
for (const listName of names) {
|
|
9
|
+
for (let from = 0;; from += pageSize) {
|
|
10
|
+
const { data, error } = await supabaseAdmin
|
|
11
|
+
.from("floriday_code_lists_cache")
|
|
12
|
+
.select("list_name, code, label, payload")
|
|
13
|
+
.eq("environment", environment)
|
|
14
|
+
.eq("list_name", listName)
|
|
15
|
+
.order("code", { ascending: true })
|
|
16
|
+
.range(from, from + pageSize - 1);
|
|
17
|
+
if (error)
|
|
18
|
+
throw error;
|
|
19
|
+
for (const r of (data ?? [])) {
|
|
20
|
+
codeLists[listName].push({
|
|
21
|
+
code: r.code,
|
|
22
|
+
label: r.label ?? null,
|
|
23
|
+
payload: r.payload ?? null,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (!data || data.length < pageSize)
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return codeLists;
|
|
31
|
+
}
|
|
32
|
+
export async function runSchema(supabase, parsed) {
|
|
33
|
+
const supabaseAdmin = supabase;
|
|
34
|
+
let query = supabaseAdmin
|
|
35
|
+
.from("floriday_resource_schemas")
|
|
36
|
+
.select("resource, version, schema, enums, fetched_at")
|
|
37
|
+
.eq("resource", parsed.resource);
|
|
38
|
+
if (parsed.version)
|
|
39
|
+
query = query.eq("version", parsed.version);
|
|
40
|
+
const { data: rows, error } = await query
|
|
41
|
+
.order("fetched_at", { ascending: false })
|
|
42
|
+
.limit(1);
|
|
43
|
+
if (error)
|
|
44
|
+
return { ok: false, error: error.message };
|
|
45
|
+
const row = (rows ?? [])[0];
|
|
46
|
+
if (!row) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
error: "Schema niet gevonden — draai eerst de referentiedata-refresh",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Plat de meest gebruikte metadata uit zodat consumers (Voorraad,
|
|
53
|
+
// Verkoop) niet zelf het JSON-schema hoeven door te parsen.
|
|
54
|
+
const schema = (row.schema ?? {});
|
|
55
|
+
const properties = schema.properties ?? {};
|
|
56
|
+
const requiredFields = Array.isArray(schema.required)
|
|
57
|
+
? schema.required
|
|
58
|
+
: [];
|
|
59
|
+
const fields = Object.entries(properties).map(([name, def]) => {
|
|
60
|
+
const d = (def ?? {});
|
|
61
|
+
return {
|
|
62
|
+
name,
|
|
63
|
+
type: d.type ?? null,
|
|
64
|
+
format: d.format ?? null,
|
|
65
|
+
description: d.description ?? null,
|
|
66
|
+
required: requiredFields.includes(name),
|
|
67
|
+
enum: Array.isArray(d.enum) ? d.enum : null,
|
|
68
|
+
minLength: d.minLength ?? null,
|
|
69
|
+
maxLength: d.maxLength ?? null,
|
|
70
|
+
minimum: d.minimum ?? null,
|
|
71
|
+
maximum: d.maximum ?? null,
|
|
72
|
+
pattern: d.pattern ?? null,
|
|
73
|
+
nullable: d.nullable ?? false,
|
|
74
|
+
ref: d.$ref ?? null,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
let codeLists;
|
|
78
|
+
if (Array.isArray(parsed.includeCodeLists) && parsed.includeCodeLists.length > 0) {
|
|
79
|
+
if (parsed.environment !== "staging" && parsed.environment !== "live") {
|
|
80
|
+
return {
|
|
81
|
+
ok: false,
|
|
82
|
+
status: 400,
|
|
83
|
+
error: "environment is verplicht wanneer includeCodeLists wordt gebruikt",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const names = parsed.includeCodeLists
|
|
87
|
+
.filter((n) => typeof n === "string" && n.length > 0)
|
|
88
|
+
.slice(0, 25);
|
|
89
|
+
codeLists = await fetchAllIncludedCodeLists(supabaseAdmin, parsed.environment, names);
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
resource: row.resource,
|
|
94
|
+
version: row.version,
|
|
95
|
+
schema: row.schema,
|
|
96
|
+
enums: row.enums ?? {},
|
|
97
|
+
requiredFields,
|
|
98
|
+
fields,
|
|
99
|
+
fetched_at: row.fetched_at,
|
|
100
|
+
...(codeLists ? { codeLists } : {}),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export { verifyGatewayCaller, corsPreflight, withCors, GATEWAY_CORS_HEADERS, } from "
|
|
1
|
+
export { verifyGatewayCaller, verifyGatewayBinaryCaller, corsPreflight, withCors, GATEWAY_CORS_HEADERS, resolveGatewayEnvironment, } from "../floriday-gateway-auth";
|
|
2
|
+
export { GATEWAY_HEADER_CALLER } from "../floriday-gateway-hmac";
|
|
3
|
+
export type { FlorydayEnvironment } from "../floriday.functions";
|
|
4
|
+
export { resolveFulfillmentOrderIds } from "../floriday-fulfillment-lookup.server";
|
|
5
|
+
export { resolveLogisticLabel } from "../floriday-labels.functions";
|
|
2
6
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/shared.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,oBAAoB,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/shared.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,aAAa,EACb,QAAQ,EACR,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
// Gateway shared re-exports
|
|
2
|
-
//
|
|
3
|
-
export { verifyGatewayCaller, corsPreflight, withCors, GATEWAY_CORS_HEADERS, } from "
|
|
1
|
+
// Gateway shared re-exports.
|
|
2
|
+
// Uitsluitend relatieve paden; consumers importeren via `./shared`.
|
|
3
|
+
export { verifyGatewayCaller, verifyGatewayBinaryCaller, corsPreflight, withCors, GATEWAY_CORS_HEADERS, resolveGatewayEnvironment, } from "../floriday-gateway-auth";
|
|
4
|
+
export { GATEWAY_HEADER_CALLER } from "../floriday-gateway-hmac";
|
|
5
|
+
// Multi-caller PDF-resolvers (pdf, pdf-bulk, pdf-bulk-merged).
|
|
6
|
+
export { resolveFulfillmentOrderIds } from "../floriday-fulfillment-lookup.server";
|
|
7
|
+
export { resolveLogisticLabel } from "../floriday-labels.functions";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface SupplyLineResult {
|
|
3
|
+
status: number;
|
|
4
|
+
payload: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare function runSupplyLine(supabase: SupabaseClient, input: {
|
|
7
|
+
raw: any;
|
|
8
|
+
environment?: string;
|
|
9
|
+
caller: string;
|
|
10
|
+
}): Promise<SupplyLineResult>;
|
|
11
|
+
//# sourceMappingURL=supply-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supply-line.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/supply-line.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiH5D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAAC,gBAAgB,CAAC,CAmK3B"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// Gateway module: catalogusaanbod / prijs publiceren voor een trade-item.
|
|
2
|
+
// Spiegel van src/routes/api/public/gateway/supply-line.ts.
|
|
3
|
+
import { resolveGatewayEnvironment } from "./shared";
|
|
4
|
+
import { florydayWrite, getActiveFlorydayCredentials } from "../floriday.functions";
|
|
5
|
+
function pickNumber(...vals) {
|
|
6
|
+
for (const v of vals) {
|
|
7
|
+
if (typeof v === "number" && isFinite(v))
|
|
8
|
+
return v;
|
|
9
|
+
if (typeof v === "string" && v.trim() !== "") {
|
|
10
|
+
const n = Number(v.replace(",", "."));
|
|
11
|
+
if (isFinite(n))
|
|
12
|
+
return n;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
function pickString(...vals) {
|
|
18
|
+
for (const v of vals)
|
|
19
|
+
if (typeof v === "string" && v.trim())
|
|
20
|
+
return v.trim();
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function weekOfYear(date = new Date()) {
|
|
24
|
+
const d = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
25
|
+
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
|
26
|
+
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
|
27
|
+
const week = Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
|
|
28
|
+
return { year: d.getUTCFullYear(), week };
|
|
29
|
+
}
|
|
30
|
+
function defaultPeriod() {
|
|
31
|
+
const start = new Date();
|
|
32
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
33
|
+
const end = new Date(start);
|
|
34
|
+
end.setUTCDate(end.getUTCDate() + 7);
|
|
35
|
+
return { startDateTime: start.toISOString(), endDateTime: end.toISOString() };
|
|
36
|
+
}
|
|
37
|
+
function toFloridayPacking(config) {
|
|
38
|
+
if (!config || typeof config !== "object")
|
|
39
|
+
return undefined;
|
|
40
|
+
return {
|
|
41
|
+
loadCarrier: config.loadCarrier,
|
|
42
|
+
vbnPackageCode: config.vbnPackageCode ?? config.package?.vbnPackageCode,
|
|
43
|
+
packagesPerLayer: config.packagesPerLayer,
|
|
44
|
+
piecesPerPackage: config.piecesPerPackage,
|
|
45
|
+
layersPerLoadCarrier: config.layersPerLoadCarrier,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function loadPrimaryPackingFromTradeItem(supabase, tradeItemId) {
|
|
49
|
+
const { data, error } = await supabase
|
|
50
|
+
.from("floriday_trade_items_cache")
|
|
51
|
+
.select("data")
|
|
52
|
+
.eq("floriday_id", tradeItemId)
|
|
53
|
+
.maybeSingle();
|
|
54
|
+
if (error || !data?.data)
|
|
55
|
+
return null;
|
|
56
|
+
const configs = data.data?.packingConfigurations;
|
|
57
|
+
if (!Array.isArray(configs) || configs.length === 0)
|
|
58
|
+
return null;
|
|
59
|
+
return toFloridayPacking(configs.find((c) => c?.primary) ?? configs[0]) ?? null;
|
|
60
|
+
}
|
|
61
|
+
async function loadUserIdForMapping(supabase, connectionId, tradeItemId) {
|
|
62
|
+
const { data } = await supabase
|
|
63
|
+
.from("trade_item_stock")
|
|
64
|
+
.select("user_id")
|
|
65
|
+
.eq("connection_id", connectionId)
|
|
66
|
+
.eq("trade_item_key", tradeItemId)
|
|
67
|
+
.limit(1)
|
|
68
|
+
.maybeSingle();
|
|
69
|
+
return data?.user_id ?? null;
|
|
70
|
+
}
|
|
71
|
+
async function persistSupplyMapping(supabase, row) {
|
|
72
|
+
const { data: existing } = await supabase
|
|
73
|
+
.from("trade_item_supply_lines")
|
|
74
|
+
.select("id")
|
|
75
|
+
.eq("connection_id", row.connection_id)
|
|
76
|
+
.eq("trade_item_id", row.trade_item_id)
|
|
77
|
+
.eq("supply_type", row.supply_type)
|
|
78
|
+
.eq("endpoint_family", row.endpoint_family)
|
|
79
|
+
.eq("year", row.year)
|
|
80
|
+
.eq("week", row.week)
|
|
81
|
+
.limit(1)
|
|
82
|
+
.maybeSingle();
|
|
83
|
+
if (existing?.id) {
|
|
84
|
+
await supabase.from("trade_item_supply_lines").update(row).eq("id", existing.id);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (row.user_id)
|
|
88
|
+
await supabase.from("trade_item_supply_lines").insert(row);
|
|
89
|
+
}
|
|
90
|
+
async function logGatewayStep(supabase, payload) {
|
|
91
|
+
await supabase.from("floriday_write_log").insert({
|
|
92
|
+
connection_id: payload.connection_id ?? null,
|
|
93
|
+
module: "gateway",
|
|
94
|
+
action: String(payload.action ?? "supply-line-step"),
|
|
95
|
+
resource: "gateway",
|
|
96
|
+
floriday_id: String(payload.tradeItemId ?? payload.supplyLineId ?? "") || null,
|
|
97
|
+
request: payload,
|
|
98
|
+
response: null,
|
|
99
|
+
http_status: payload.status ?? 0,
|
|
100
|
+
ok: Boolean(payload.ok),
|
|
101
|
+
error: payload.error ? String(payload.error).slice(0, 500) : null,
|
|
102
|
+
idempotency_key: null,
|
|
103
|
+
caller: String(payload.caller ?? "self"),
|
|
104
|
+
}).then(() => undefined, () => undefined);
|
|
105
|
+
}
|
|
106
|
+
export async function runSupplyLine(supabase, input) {
|
|
107
|
+
const raw = input.raw;
|
|
108
|
+
const caller = input.caller;
|
|
109
|
+
const tradeItemId = pickString(raw.tradeItemId, raw.trade_item_id, raw.itemId);
|
|
110
|
+
const pricePerPiece = pickNumber(raw.pricePerPiece, raw.price, raw.unitPrice, raw?.priceInformation?.pricePerPiece);
|
|
111
|
+
const availableQuantity = pickNumber(raw.availableQuantity, raw.quantity, raw.stock, raw.available);
|
|
112
|
+
const supplyType = raw.supplyType === "BATCH_PRICE" ? "BATCH_PRICE" : "CATALOG_PRICE";
|
|
113
|
+
const currency = pickString(raw.currency, raw?.priceInformation?.currency) ?? "EUR";
|
|
114
|
+
const salesUnit = pickString(raw.salesUnit) ?? "PIECE";
|
|
115
|
+
const missing = [];
|
|
116
|
+
if (!tradeItemId)
|
|
117
|
+
missing.push("tradeItemId");
|
|
118
|
+
if (pricePerPiece === undefined)
|
|
119
|
+
missing.push("pricePerPiece (of `price`)");
|
|
120
|
+
if (availableQuantity === undefined)
|
|
121
|
+
missing.push("availableQuantity (of `quantity` / `stock`)");
|
|
122
|
+
if (missing.length) {
|
|
123
|
+
return { status: 400, payload: { ok: false, error: `Ontbrekende velden: ${missing.join(", ")}.`, missing } };
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const environment = await resolveGatewayEnvironment(supabase, input.environment ?? raw.environment);
|
|
127
|
+
const conn = await getActiveFlorydayCredentials(supabase, environment);
|
|
128
|
+
if (!conn) {
|
|
129
|
+
return { status: 409, payload: { ok: false, error: `Geen actieve Floriday-koppeling voor ${environment}` } };
|
|
130
|
+
}
|
|
131
|
+
const customerIds = Array.isArray(raw.customerOrganizationIds)
|
|
132
|
+
? raw.customerOrganizationIds.filter((v) => typeof v === "string" && v)
|
|
133
|
+
: [];
|
|
134
|
+
const userId = await loadUserIdForMapping(supabase, conn.id, tradeItemId);
|
|
135
|
+
// Structureel pad voor catalogusprijzen: geen supplyLineId, dus ook geen stale-id fallback meer.
|
|
136
|
+
if (supplyType === "CATALOG_PRICE") {
|
|
137
|
+
const explicitYear = pickNumber(raw.year, raw?.tradePeriod?.year);
|
|
138
|
+
const explicitWeek = pickNumber(raw.week, raw?.tradePeriod?.week);
|
|
139
|
+
const computed = weekOfYear(pickString(raw.periodStart, raw?.supplyPeriod?.periodStart) ? new Date(pickString(raw.periodStart, raw?.supplyPeriod?.periodStart)) : new Date());
|
|
140
|
+
const year = Math.trunc(explicitYear ?? computed.year);
|
|
141
|
+
const week = Math.trunc(explicitWeek ?? computed.week);
|
|
142
|
+
const baseSupplyBody = {
|
|
143
|
+
basePricePerPiece: { value: pricePerPiece, currency },
|
|
144
|
+
numberOfPieces: Math.max(0, Math.trunc(availableQuantity)),
|
|
145
|
+
};
|
|
146
|
+
const baseResult = await florydayWrite(supabase, environment, {
|
|
147
|
+
module: "catalog",
|
|
148
|
+
action: "upsert-weekly-base-supply",
|
|
149
|
+
method: "PUT",
|
|
150
|
+
path: `/trade-items/${encodeURIComponent(tradeItemId)}/base-supply/${year}/${week}`,
|
|
151
|
+
referenceId: tradeItemId,
|
|
152
|
+
body: baseSupplyBody,
|
|
153
|
+
caller,
|
|
154
|
+
idempotencyKey: `weekly-base-supply:${environment}:${tradeItemId}:${year}:${week}:${pricePerPiece}:${availableQuantity}`,
|
|
155
|
+
});
|
|
156
|
+
let availabilityResult = null;
|
|
157
|
+
if (raw.usesCatalogAvailability !== false) {
|
|
158
|
+
availabilityResult = await florydayWrite(supabase, environment, {
|
|
159
|
+
module: "catalog",
|
|
160
|
+
action: "set-trade-item-customer-offer-availability",
|
|
161
|
+
method: "PUT",
|
|
162
|
+
path: `/trade-items/${encodeURIComponent(tradeItemId)}/availability-for-customer-offers?isAvailableForCustomerOffers=true`,
|
|
163
|
+
referenceId: tradeItemId,
|
|
164
|
+
caller,
|
|
165
|
+
idempotencyKey: `trade-item-offer-availability:${environment}:${tradeItemId}:true`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
await persistSupplyMapping(supabase, {
|
|
169
|
+
connection_id: conn.id,
|
|
170
|
+
user_id: userId,
|
|
171
|
+
environment,
|
|
172
|
+
trade_item_id: tradeItemId,
|
|
173
|
+
supply_type: supplyType,
|
|
174
|
+
endpoint_family: "weekly-base-supply",
|
|
175
|
+
supply_line_id: null,
|
|
176
|
+
year,
|
|
177
|
+
week,
|
|
178
|
+
price_per_piece: pricePerPiece,
|
|
179
|
+
available_quantity: availableQuantity,
|
|
180
|
+
currency,
|
|
181
|
+
sales_unit: salesUnit,
|
|
182
|
+
last_status: baseResult.status,
|
|
183
|
+
last_error: baseResult.error ?? null,
|
|
184
|
+
updated_at: new Date().toISOString(),
|
|
185
|
+
});
|
|
186
|
+
await logGatewayStep(supabase, {
|
|
187
|
+
action: "supply-line-resolved",
|
|
188
|
+
ok: baseResult.ok,
|
|
189
|
+
status: baseResult.status,
|
|
190
|
+
caller,
|
|
191
|
+
connection_id: conn.id,
|
|
192
|
+
environment,
|
|
193
|
+
tradeItemId,
|
|
194
|
+
oldEndpoint: "/supply-lines/{id}",
|
|
195
|
+
endpoint: `/trade-items/${tradeItemId}/base-supply/${year}/${week}`,
|
|
196
|
+
oldSupplyLineId: pickString(raw.supplyLineId, raw.id) ?? null,
|
|
197
|
+
newSupplyLineId: null,
|
|
198
|
+
mapping: { endpoint_family: "weekly-base-supply", year, week },
|
|
199
|
+
payload: baseSupplyBody,
|
|
200
|
+
error: baseResult.error ?? null,
|
|
201
|
+
});
|
|
202
|
+
return {
|
|
203
|
+
status: baseResult.ok ? 200 : baseResult.status || 500,
|
|
204
|
+
payload: {
|
|
205
|
+
ok: baseResult.ok && (!availabilityResult || availabilityResult.ok),
|
|
206
|
+
status: baseResult.status,
|
|
207
|
+
environment,
|
|
208
|
+
endpointFamily: "weekly-base-supply",
|
|
209
|
+
tradeItemId,
|
|
210
|
+
supplyLineId: null,
|
|
211
|
+
year,
|
|
212
|
+
week,
|
|
213
|
+
attemptId: baseResult.attemptId,
|
|
214
|
+
availabilityAttemptId: availabilityResult?.attemptId ?? null,
|
|
215
|
+
error: baseResult.error ?? availabilityResult?.error,
|
|
216
|
+
data: { baseSupply: baseResult.data, customerOfferAvailability: availabilityResult?.data ?? null },
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
// Batch-prijs blijft volgens 2026v1 via POST /supply-lines lopen.
|
|
221
|
+
const period = defaultPeriod();
|
|
222
|
+
const packingConfiguration = raw.packingConfiguration && typeof raw.packingConfiguration === "object"
|
|
223
|
+
? toFloridayPacking(raw.packingConfiguration)
|
|
224
|
+
: await loadPrimaryPackingFromTradeItem(supabase, tradeItemId);
|
|
225
|
+
if (!packingConfiguration) {
|
|
226
|
+
return { status: 409, payload: { ok: false, error: "Kon geen fust-configuratie vinden voor dit product." } };
|
|
227
|
+
}
|
|
228
|
+
const supplyLineId = pickString(raw.supplyLineId, raw.id) ?? crypto.randomUUID();
|
|
229
|
+
const batchBody = {
|
|
230
|
+
supplyLineId,
|
|
231
|
+
batchId: pickString(raw.batchId) ?? supplyLineId,
|
|
232
|
+
tradeItemId,
|
|
233
|
+
pricePerPiece: { value: pricePerPiece, currency },
|
|
234
|
+
orderPeriod: raw.orderPeriod ?? period,
|
|
235
|
+
deliveryPeriod: raw.deliveryPeriod ?? period,
|
|
236
|
+
includedServices: Array.isArray(raw.includedServices) ? raw.includedServices : [],
|
|
237
|
+
packingConfigurations: [packingConfiguration],
|
|
238
|
+
allowedCustomerOrganizationIds: customerIds,
|
|
239
|
+
assignedNumberOfPieces: Math.max(0, Math.trunc(availableQuantity)),
|
|
240
|
+
onlyAsapDelivery: Boolean(raw.onlyAsapDelivery ?? false),
|
|
241
|
+
};
|
|
242
|
+
const result = await florydayWrite(supabase, environment, {
|
|
243
|
+
module: "catalog",
|
|
244
|
+
action: "create-batch-supply-line",
|
|
245
|
+
method: "POST",
|
|
246
|
+
path: "/supply-lines",
|
|
247
|
+
referenceId: supplyLineId,
|
|
248
|
+
body: batchBody,
|
|
249
|
+
caller,
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
status: result.ok ? 200 : result.status || 500,
|
|
253
|
+
payload: { ok: result.ok, status: result.status, environment, endpointFamily: "batch-supply-line", supplyLineId, attemptId: result.attemptId, error: result.error, data: result.data },
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
const msg = String(e?.message ?? e);
|
|
258
|
+
console.error("[gateway/supply-line] crashed:", msg);
|
|
259
|
+
return { status: 500, payload: { ok: false, error: msg } };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
export interface GatewayWriteBody {
|
|
3
|
+
environment: "staging" | "live";
|
|
4
|
+
module: string;
|
|
5
|
+
action: string;
|
|
6
|
+
method: "POST" | "PUT" | "PATCH" | "DELETE";
|
|
7
|
+
path: string;
|
|
8
|
+
body?: unknown;
|
|
9
|
+
referenceId?: string;
|
|
10
|
+
idempotencyKey?: string;
|
|
11
|
+
validateEnums?: Array<{
|
|
12
|
+
field: string;
|
|
13
|
+
listName: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export declare function isValidGatewayWriteBody(input: unknown): input is GatewayWriteBody;
|
|
17
|
+
export declare function runWrite(supabase: SupabaseClient, parsed: GatewayWriteBody, caller: string): Promise<import("../floriday.functions").FlorydayWriteResult>;
|
|
18
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/lib/gateway/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CASjF;AAED,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,gEAaf"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Gateway module: generieke schrijfactie naar Floriday.
|
|
2
|
+
// Spiegel van src/routes/api/public/gateway/write.ts (business-logica).
|
|
3
|
+
import { florydayWrite } from "../floriday.functions";
|
|
4
|
+
export function isValidGatewayWriteBody(input) {
|
|
5
|
+
if (!input || typeof input !== "object")
|
|
6
|
+
return false;
|
|
7
|
+
const o = input;
|
|
8
|
+
if (o.environment !== "staging" && o.environment !== "live")
|
|
9
|
+
return false;
|
|
10
|
+
if (typeof o.module !== "string" || !o.module)
|
|
11
|
+
return false;
|
|
12
|
+
if (typeof o.action !== "string" || !o.action)
|
|
13
|
+
return false;
|
|
14
|
+
if (typeof o.path !== "string" || !o.path)
|
|
15
|
+
return false;
|
|
16
|
+
if (!["POST", "PUT", "PATCH", "DELETE"].includes(o.method))
|
|
17
|
+
return false;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
export async function runWrite(supabase, parsed, caller) {
|
|
21
|
+
return florydayWrite(supabase, parsed.environment, {
|
|
22
|
+
module: parsed.module,
|
|
23
|
+
action: parsed.action,
|
|
24
|
+
method: parsed.method,
|
|
25
|
+
path: parsed.path,
|
|
26
|
+
body: parsed.body,
|
|
27
|
+
referenceId: parsed.referenceId,
|
|
28
|
+
idempotencyKey: parsed.idempotencyKey,
|
|
29
|
+
validateEnums: parsed.validateEnums,
|
|
30
|
+
caller,
|
|
31
|
+
});
|
|
32
|
+
}
|