@flowselections/floriday-verkoop-module 1.0.7 → 1.0.9

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 (67) hide show
  1. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.d.ts +9 -0
  2. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.d.ts.map +1 -0
  3. package/dist-lib/components/floriday/FlorydaySyncHealthBanner.js +26 -0
  4. package/dist-lib/components/verkoop/AnalyticsCards.js +2 -2
  5. package/dist-lib/components/verkoop/CreateOrderPage.d.ts +2 -0
  6. package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -0
  7. package/dist-lib/components/verkoop/CreateOrderPage.js +218 -0
  8. package/dist-lib/components/verkoop/DiagnoseConnectionDialog.d.ts +5 -0
  9. package/dist-lib/components/verkoop/DiagnoseConnectionDialog.d.ts.map +1 -0
  10. package/dist-lib/components/verkoop/DiagnoseConnectionDialog.js +40 -0
  11. package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts +2 -0
  12. package/dist-lib/components/verkoop/SalesOrderDetailPage.d.ts.map +1 -0
  13. package/dist-lib/components/verkoop/SalesOrderDetailPage.js +14 -0
  14. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts +6 -0
  15. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -0
  16. package/dist-lib/components/verkoop/SalesOrderDetailView.js +213 -0
  17. package/dist-lib/components/verkoop/SalesOrdersFilterPanel.d.ts +9 -0
  18. package/dist-lib/components/verkoop/SalesOrdersFilterPanel.d.ts.map +1 -0
  19. package/dist-lib/components/verkoop/SalesOrdersFilterPanel.js +62 -0
  20. package/dist-lib/components/verkoop/SalesOrdersFilters.d.ts +13 -0
  21. package/dist-lib/components/verkoop/SalesOrdersFilters.d.ts.map +1 -1
  22. package/dist-lib/components/verkoop/SalesOrdersFilters.js +123 -23
  23. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts +3 -2
  24. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  25. package/dist-lib/components/verkoop/SalesOrdersTable.js +3 -3
  26. package/dist-lib/components/verkoop/VerkoopOrdersPage.d.ts.map +1 -1
  27. package/dist-lib/components/verkoop/VerkoopOrdersPage.js +125 -33
  28. package/dist-lib/components/verkoop/WeekCalendar.d.ts +6 -0
  29. package/dist-lib/components/verkoop/WeekCalendar.d.ts.map +1 -0
  30. package/dist-lib/components/verkoop/WeekCalendar.js +101 -0
  31. package/dist-lib/index.d.ts +2 -0
  32. package/dist-lib/index.d.ts.map +1 -1
  33. package/dist-lib/index.js +2 -0
  34. package/dist-lib/integrations/supabase/auth-middleware.d.ts +8509 -937
  35. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  36. package/dist-lib/integrations/supabase/client.d.ts +8509 -937
  37. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  38. package/dist-lib/integrations/supabase/client.server.d.ts +8509 -937
  39. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  40. package/dist-lib/integrations/supabase/types.d.ts +8753 -954
  41. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  42. package/dist-lib/integrations/supabase/types.js +20 -1
  43. package/dist-lib/lib/floriday-gateway.server.d.ts +42 -0
  44. package/dist-lib/lib/floriday-gateway.server.d.ts.map +1 -0
  45. package/dist-lib/lib/floriday-gateway.server.js +222 -0
  46. package/dist-lib/lib/floriday-public.functions.d.ts +63971 -0
  47. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -0
  48. package/dist-lib/lib/floriday-public.functions.js +210 -0
  49. package/dist-lib/lib/floriday-sync.d.ts +32 -0
  50. package/dist-lib/lib/floriday-sync.d.ts.map +1 -0
  51. package/dist-lib/lib/floriday-sync.js +116 -0
  52. package/dist-lib/lib/floriday-writes.functions.d.ts +45678 -0
  53. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -0
  54. package/dist-lib/lib/floriday-writes.functions.js +110 -0
  55. package/dist-lib/lib/salesorders-mapping.d.ts +85 -0
  56. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -0
  57. package/dist-lib/lib/salesorders-mapping.js +198 -0
  58. package/dist-lib/lib/salesorders.functions.d.ts +27436 -0
  59. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -0
  60. package/dist-lib/lib/salesorders.functions.js +174 -0
  61. package/dist-lib/lib/tradeitems.functions.d.ts +9139 -0
  62. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -0
  63. package/dist-lib/lib/tradeitems.functions.js +60 -0
  64. package/dist-lib/lib/useSalesOrdersQuery.d.ts +6 -0
  65. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -0
  66. package/dist-lib/lib/useSalesOrdersQuery.js +129 -0
  67. package/package.json +16 -3
@@ -0,0 +1,210 @@
1
+ // Public-read helpers (server functions) — used by all other modules.
2
+ // Reads gaan via de lokale Supabase-cache; geen directe Floriday API-calls.
3
+ import { createServerFn } from "@tanstack/react-start";
4
+ import { z } from "zod";
5
+ import { requireSupabaseAuth } from "../integrations/supabase/auth-middleware";
6
+ const EnvSchema = z.enum(["staging", "live"]);
7
+ // Toegestane cache-entities en hun tabel-mapping.
8
+ const ENTITY_TABLE = {
9
+ "sales-orders": "floriday_salesorders_cache",
10
+ "trade-items": "floriday_trade_items_cache",
11
+ "customer-organizations": "floriday_customers_cache",
12
+ carriers: "floriday_carriers_cache",
13
+ "fulfillment-orders": "floriday_fulfillment_orders_cache",
14
+ "delivery-orders": "floriday_delivery_orders_cache",
15
+ "clock-supplies": "floriday_clock_supplies_cache",
16
+ "clock-presales": "floriday_clock_presales_cache",
17
+ contracts: "floriday_contracts_cache",
18
+ "blanket-orders": "floriday_blanket_orders_cache",
19
+ warehouses: "floriday_warehouses_cache",
20
+ "delivery-locations": "floriday_delivery_locations_cache",
21
+ packings: "floriday_packings_cache",
22
+ connections: "floriday_connections_cache",
23
+ "customer-stickers": "floriday_customer_stickers_cache",
24
+ "additional-services": "floriday_additional_services_cache",
25
+ "commercial-service-types": "floriday_commercial_service_types_cache",
26
+ collections: "floriday_collections_cache",
27
+ "price-groups": "floriday_price_groups_cache",
28
+ "delivery-condition-sets": "floriday_delivery_condition_sets_cache",
29
+ "sales-strategies": "floriday_sales_strategies_cache",
30
+ "base-items": "floriday_base_items_cache",
31
+ "contract-trade-item-groups": "floriday_contract_trade_item_groups_cache",
32
+ };
33
+ const CachedListSchema = z.object({
34
+ environment: EnvSchema,
35
+ entity: z.string().min(1),
36
+ limit: z.number().int().positive().max(5000).optional(),
37
+ });
38
+ export const getFlorydayCachedList = createServerFn({ method: "POST" })
39
+ .middleware([requireSupabaseAuth])
40
+ .inputValidator((d) => CachedListSchema.parse(d))
41
+ .handler(async ({ data, context }) => {
42
+ const table = ENTITY_TABLE[data.entity];
43
+ if (!table) {
44
+ throw new Error(`Onbekende entity "${data.entity}" — toegestane waarden: ${Object.keys(ENTITY_TABLE).join(", ")}`);
45
+ }
46
+ const limit = data.limit ?? 1000;
47
+ let q = context.supabase.from(table).select("*").limit(limit);
48
+ // Most cache-tables have an is_deleted column; filter when present.
49
+ const hasIsDeleted = [
50
+ "floriday_salesorders_cache",
51
+ "floriday_trade_items_cache",
52
+ ].includes(table);
53
+ if (hasIsDeleted)
54
+ q = q.eq("is_deleted", false);
55
+ const { data: rows, error } = await q;
56
+ if (error)
57
+ throw new Error(`${table} lezen faalde: ${error.message}`);
58
+ return { entity: data.entity, rows: rows ?? [] };
59
+ });
60
+ const CodeListSchema = z.object({
61
+ environment: EnvSchema,
62
+ listName: z.string().min(1),
63
+ });
64
+ export const getFlorydayCodeList = createServerFn({ method: "POST" })
65
+ .middleware([requireSupabaseAuth])
66
+ .inputValidator((d) => CodeListSchema.parse(d))
67
+ .handler(async ({ data, context }) => {
68
+ const { data: rows, error } = await context.supabase
69
+ .from("floriday_code_lists_cache")
70
+ .select("code, label, payload")
71
+ .eq("environment", data.environment)
72
+ .eq("list_name", data.listName);
73
+ if (error)
74
+ throw new Error(`code-list lezen faalde: ${error.message}`);
75
+ return { listName: data.listName, items: rows ?? [] };
76
+ });
77
+ export const getFlorydayAllowedValues = createServerFn({ method: "POST" })
78
+ .middleware([requireSupabaseAuth])
79
+ .inputValidator((d) => CodeListSchema.parse(d))
80
+ .handler(async ({ data, context }) => {
81
+ const { data: rows, error } = await context.supabase
82
+ .from("floriday_code_lists_cache")
83
+ .select("code")
84
+ .eq("environment", data.environment)
85
+ .eq("list_name", data.listName);
86
+ if (error)
87
+ throw new Error(`allowed-values lezen faalde: ${error.message}`);
88
+ return { listName: data.listName, values: (rows ?? []).map((r) => String(r.code)) };
89
+ });
90
+ const AssertSchema = z.object({
91
+ environment: EnvSchema,
92
+ listName: z.string().min(1),
93
+ value: z.string(),
94
+ });
95
+ export const assertFlorydayValue = createServerFn({ method: "POST" })
96
+ .middleware([requireSupabaseAuth])
97
+ .inputValidator((d) => AssertSchema.parse(d))
98
+ .handler(async ({ data, context }) => {
99
+ const { data: rows, error } = await context.supabase
100
+ .from("floriday_code_lists_cache")
101
+ .select("code")
102
+ .eq("environment", data.environment)
103
+ .eq("list_name", data.listName);
104
+ if (error)
105
+ throw new Error(`assert lezen faalde: ${error.message}`);
106
+ const allowed = (rows ?? []).map((r) => String(r.code));
107
+ if (allowed.length === 0) {
108
+ return { ok: false, error: `Lijst "${data.listName}" leeg of niet gecached`, allowed };
109
+ }
110
+ if (allowed.includes(data.value))
111
+ return { ok: true, allowed };
112
+ return {
113
+ ok: false,
114
+ error: `Waarde "${data.value}" niet toegestaan in "${data.listName}"`,
115
+ allowed,
116
+ };
117
+ });
118
+ const VbnSchema = z.object({
119
+ environment: EnvSchema,
120
+ code: z.string().optional(),
121
+ search: z.string().optional(),
122
+ });
123
+ export const getFlorydayVbnProduct = createServerFn({ method: "POST" })
124
+ .middleware([requireSupabaseAuth])
125
+ .inputValidator((d) => VbnSchema.parse(d))
126
+ .handler(async ({ data, context }) => {
127
+ let q = context.supabase
128
+ .from("floriday_code_lists_cache")
129
+ .select("code, label, payload")
130
+ .eq("environment", data.environment)
131
+ .eq("list_name", "vbn-products");
132
+ if (data.code)
133
+ q = q.eq("code", data.code);
134
+ else if (data.search)
135
+ q = q.ilike("label", `%${data.search}%`).limit(50);
136
+ else
137
+ q = q.limit(50);
138
+ const { data: rows, error } = await q;
139
+ if (error)
140
+ throw new Error(`vbn-products lezen faalde: ${error.message}`);
141
+ return { items: rows ?? [] };
142
+ });
143
+ const SchemaArgs = z.object({
144
+ resource: z.string().min(1),
145
+ version: z.string().optional(),
146
+ });
147
+ export const getFlorydayResourceSchema = createServerFn({ method: "POST" })
148
+ .middleware([requireSupabaseAuth])
149
+ .inputValidator((d) => SchemaArgs.parse(d))
150
+ .handler(async ({ data, context }) => {
151
+ let q = context.supabase
152
+ .from("floriday_resource_schemas")
153
+ .select("resource, version, schema, enums, fetched_at")
154
+ .eq("resource", data.resource);
155
+ if (data.version)
156
+ q = q.eq("version", data.version);
157
+ const { data: rows, error } = await q.order("fetched_at", { ascending: false }).limit(1);
158
+ if (error)
159
+ throw new Error(`resource-schema lezen faalde: ${error.message}`);
160
+ return rows?.[0] ?? null;
161
+ });
162
+ const SyncHealthSchema = z.object({
163
+ environment: EnvSchema,
164
+ resources: z.array(z.string()).min(1),
165
+ });
166
+ // Voor de FlorydaySyncHealthBanner — leest sync-state voor de actieve connectie
167
+ // van de gevraagde environment en geeft per resource laatste sync-info terug.
168
+ export const getFlorydaySyncHealth = createServerFn({ method: "POST" })
169
+ .middleware([requireSupabaseAuth])
170
+ .inputValidator((d) => SyncHealthSchema.parse(d))
171
+ .handler(async ({ data, context }) => {
172
+ const dbEnv = data.environment === "live" ? "production" : "staging";
173
+ const { data: conns } = await context.supabase
174
+ .from("floriday_connections")
175
+ .select("id")
176
+ .eq("environment", dbEnv)
177
+ .eq("is_active", true)
178
+ .limit(1);
179
+ const connectionId = (conns ?? [])[0]?.id ?? null;
180
+ if (!connectionId) {
181
+ return { connectionId: null, resources: [] };
182
+ }
183
+ // Map resource → entity_type used in floriday_sync_state.
184
+ const RES_TO_ENTITY = {
185
+ "sales-orders": "salesorders",
186
+ "trade-items": "tradeitems",
187
+ "customer-organizations": "customers",
188
+ "fulfillment-orders": "fulfillment-orders",
189
+ };
190
+ const { data: rows } = await context.supabase
191
+ .from("floriday_sync_state")
192
+ .select("entity_type, last_sequence_number, last_synced_at, last_success_at, last_error")
193
+ .eq("connection_id", connectionId);
194
+ const stateByEntity = new Map((rows ?? []).map((r) => [String(r.entity_type), r]));
195
+ return {
196
+ connectionId,
197
+ resources: data.resources.map((res) => {
198
+ const entity = RES_TO_ENTITY[res] ?? res;
199
+ const s = stateByEntity.get(entity) ?? null;
200
+ return {
201
+ resource: res,
202
+ entityType: entity,
203
+ lastSyncedAt: s?.last_synced_at ?? null,
204
+ lastSuccessAt: s?.last_success_at ?? null,
205
+ lastSequenceNumber: s?.last_sequence_number ?? null,
206
+ lastError: s?.last_error ?? null,
207
+ };
208
+ }),
209
+ };
210
+ });
@@ -0,0 +1,32 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ export declare const FLORIDAY_API_BASES: {
3
+ readonly staging: "https://api.staging.floriday.io/suppliers-api-2026v1";
4
+ readonly production: "https://api.floriday.io/suppliers-api-2026v1";
5
+ };
6
+ export interface FloridayConnectionRow {
7
+ id: string;
8
+ environment: string | null;
9
+ access_token: string | null;
10
+ api_key: string | null;
11
+ is_active: boolean | null;
12
+ }
13
+ export interface SyncOptions<TRow> {
14
+ connection: FloridayConnectionRow;
15
+ entityType: string;
16
+ maxEndpoint: string;
17
+ syncEndpointBase: string;
18
+ cacheTable: string;
19
+ conflictTarget: string;
20
+ mapRow: (record: any, connectionId: string) => TRow;
21
+ }
22
+ export interface SyncResult {
23
+ ok: boolean;
24
+ entityType: string;
25
+ connectionId: string;
26
+ synced: number;
27
+ fromSequence: number;
28
+ toSequence: number;
29
+ }
30
+ export declare function syncBySequence<TRow extends Record<string, any>>(supabase: SupabaseClient, opts: SyncOptions<TRow>): Promise<SyncResult>;
31
+ export declare function loadActiveConnections(supabase: SupabaseClient): Promise<FloridayConnectionRow[]>;
32
+ //# sourceMappingURL=floriday-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floriday-sync.d.ts","sourceRoot":"","sources":["../../src/lib/floriday-sync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW,CAAC,IAAI;IAC/B,UAAU,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAkCD,wBAAsB,cAAc,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACnE,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,CA+FrB;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAOlC"}
@@ -0,0 +1,116 @@
1
+ export const FLORIDAY_API_BASES = {
2
+ staging: "https://api.staging.floriday.io/suppliers-api-2026v1",
3
+ production: "https://api.floriday.io/suppliers-api-2026v1",
4
+ };
5
+ async function readLastSequence(supabase, connectionId, entityType) {
6
+ const { data } = await supabase
7
+ .from("floriday_sync_state")
8
+ .select("last_sequence_number")
9
+ .eq("connection_id", connectionId)
10
+ .eq("entity_type", entityType)
11
+ .maybeSingle();
12
+ const v = data?.last_sequence_number;
13
+ return typeof v === "number" ? v : Number(v ?? 0) || 0;
14
+ }
15
+ async function writeLastSequence(supabase, connectionId, entityType, lastSequenceNumber) {
16
+ await supabase.from("floriday_sync_state").upsert({
17
+ connection_id: connectionId,
18
+ entity_type: entityType,
19
+ last_sequence_number: lastSequenceNumber,
20
+ last_synced_at: new Date().toISOString(),
21
+ }, { onConflict: "connection_id,entity_type" });
22
+ }
23
+ export async function syncBySequence(supabase, opts) {
24
+ // Lazy import vermijdt circular dependency tussen sync en gateway.
25
+ const { florydayFetch } = await import("./floriday-gateway.server");
26
+ const { connection, entityType, maxEndpoint, syncEndpointBase, cacheTable, conflictTarget, mapRow } = opts;
27
+ let active = connection;
28
+ const maxCall = await florydayFetch(supabase, active, {
29
+ method: "GET",
30
+ path: maxEndpoint,
31
+ });
32
+ if (!maxCall.ok) {
33
+ throw new Error(`Floriday GET ${maxEndpoint} faalde [${maxCall.status}]: ${maxCall.rawText.slice(0, 400)}`);
34
+ }
35
+ active = maxCall.connection;
36
+ const maxRes = maxCall.data;
37
+ const maxSequence = Number((typeof maxRes === "number" ? maxRes : maxRes?.maxSequenceNumber ?? maxRes?.sequenceNumber ?? 0) ?? 0);
38
+ const fromSequence = await readLastSequence(supabase, active.id, entityType);
39
+ let cursor = fromSequence;
40
+ let synced = 0;
41
+ let safetyHops = 0;
42
+ const MAX_HOPS = 1000;
43
+ let effectiveMax = maxSequence;
44
+ while (cursor < effectiveMax && safetyHops < MAX_HOPS) {
45
+ safetyHops += 1;
46
+ const batchCall = await florydayFetch(supabase, active, {
47
+ method: "GET",
48
+ path: `${syncEndpointBase}/${cursor}`,
49
+ });
50
+ if (!batchCall.ok) {
51
+ throw new Error(`Floriday GET ${syncEndpointBase}/${cursor} faalde [${batchCall.status}]: ${batchCall.rawText.slice(0, 400)}`);
52
+ }
53
+ active = batchCall.connection;
54
+ const batch = batchCall.data;
55
+ let list = [];
56
+ let respSeq = null;
57
+ let respMaxSeq = null;
58
+ if (Array.isArray(batch)) {
59
+ list = batch;
60
+ }
61
+ else if (batch && typeof batch === "object") {
62
+ list = (batch.results ?? batch.items ?? batch.salesOrders ?? batch.data ?? []);
63
+ const s = Number(batch.sequenceNumber);
64
+ const m = Number(batch.maximumSequenceNumber);
65
+ if (Number.isFinite(s))
66
+ respSeq = s;
67
+ if (Number.isFinite(m))
68
+ respMaxSeq = m;
69
+ }
70
+ if (list.length > 0) {
71
+ const rows = list.map((r) => mapRow(r, active.id));
72
+ const { error: upErr } = await supabase.from(cacheTable).upsert(rows, { onConflict: conflictTarget });
73
+ if (upErr)
74
+ throw new Error(`Upsert ${cacheTable} faalde: ${upErr.message}`);
75
+ synced += list.length;
76
+ }
77
+ const seqs = list
78
+ .map((r) => Number(r?.sequenceNumber ?? 0))
79
+ .filter((n) => Number.isFinite(n));
80
+ const highestInList = seqs.length ? Math.max(...seqs) : -Infinity;
81
+ let nextCursor = cursor;
82
+ if (highestInList > cursor)
83
+ nextCursor = highestInList;
84
+ else if (respSeq !== null && respSeq > cursor)
85
+ nextCursor = respSeq;
86
+ else if (list.length === 0 && respMaxSeq !== null && respMaxSeq > cursor) {
87
+ nextCursor = respMaxSeq;
88
+ }
89
+ else if (list.length === 0) {
90
+ break;
91
+ }
92
+ if (nextCursor <= cursor)
93
+ break;
94
+ cursor = nextCursor;
95
+ await writeLastSequence(supabase, active.id, entityType, cursor);
96
+ if (respMaxSeq !== null && respMaxSeq > effectiveMax)
97
+ effectiveMax = respMaxSeq;
98
+ }
99
+ return {
100
+ ok: true,
101
+ entityType,
102
+ connectionId: active.id,
103
+ synced,
104
+ fromSequence,
105
+ toSequence: cursor,
106
+ };
107
+ }
108
+ export async function loadActiveConnections(supabase) {
109
+ const { data, error } = await supabase
110
+ .from("floriday_connections")
111
+ .select("id, environment, access_token, api_key, is_active")
112
+ .eq("is_active", true);
113
+ if (error)
114
+ throw new Error(`floriday_connections lezen faalde: ${error.message}`);
115
+ return (data ?? []);
116
+ }