@flowselections/google-maps-api-installatie-techniek 1.0.2
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/_core-safelist.d.ts +2 -0
- package/dist-lib/_core-safelist.d.ts.map +1 -0
- package/dist-lib/_core-safelist.js +15 -0
- package/dist-lib/components/MapsBeheerPage.d.ts +2 -0
- package/dist-lib/components/MapsBeheerPage.d.ts.map +1 -0
- package/dist-lib/components/MapsBeheerPage.js +68 -0
- package/dist-lib/components/MapsInstallatieLogo.d.ts +6 -0
- package/dist-lib/components/MapsInstallatieLogo.d.ts.map +1 -0
- package/dist-lib/components/MapsInstallatieLogo.js +4 -0
- package/dist-lib/components/maps/MapsDiagnosticsPanel.d.ts +2 -0
- package/dist-lib/components/maps/MapsDiagnosticsPanel.d.ts.map +1 -0
- package/dist-lib/components/maps/MapsDiagnosticsPanel.js +81 -0
- package/dist-lib/components/maps/MapsStatusPanel.d.ts +5 -0
- package/dist-lib/components/maps/MapsStatusPanel.d.ts.map +1 -0
- package/dist-lib/components/maps/MapsStatusPanel.js +74 -0
- package/dist-lib/components/settings/MapsSettingsCard.d.ts +2 -0
- package/dist-lib/components/settings/MapsSettingsCard.d.ts.map +1 -0
- package/dist-lib/components/settings/MapsSettingsCard.js +15 -0
- package/dist-lib/index.d.ts +7 -0
- package/dist-lib/index.d.ts.map +1 -0
- package/dist-lib/index.js +20 -0
- package/dist-lib/integrations/supabase/auth-attacher.d.ts +2 -0
- package/dist-lib/integrations/supabase/auth-attacher.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/auth-attacher.js +12 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +23365 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/auth-middleware.js +52 -0
- package/dist-lib/integrations/supabase/client.d.ts +23361 -0
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/client.js +29 -0
- package/dist-lib/integrations/supabase/client.server.d.ts +23361 -0
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/client.server.js +30 -0
- package/dist-lib/integrations/supabase/previewAuthStorage.d.ts +6 -0
- package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/previewAuthStorage.js +92 -0
- package/dist-lib/integrations/supabase/types.d.ts +23990 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/types.js +92 -0
- package/dist-lib/lib/central-auth.server.d.ts +60 -0
- package/dist-lib/lib/central-auth.server.d.ts.map +1 -0
- package/dist-lib/lib/central-auth.server.js +439 -0
- package/dist-lib/lib/google-maps.server.d.ts +22 -0
- package/dist-lib/lib/google-maps.server.d.ts.map +1 -0
- package/dist-lib/lib/google-maps.server.js +65 -0
- package/dist-lib/lib/maps-admin.server.d.ts +17 -0
- package/dist-lib/lib/maps-admin.server.d.ts.map +1 -0
- package/dist-lib/lib/maps-admin.server.js +121 -0
- package/dist-lib/lib/maps-diagnostics.server.d.ts +4 -0
- package/dist-lib/lib/maps-diagnostics.server.d.ts.map +1 -0
- package/dist-lib/lib/maps-diagnostics.server.js +137 -0
- package/dist-lib/lib/maps-processor.server.d.ts +16 -0
- package/dist-lib/lib/maps-processor.server.d.ts.map +1 -0
- package/dist-lib/lib/maps-processor.server.js +315 -0
- package/dist-lib/lib/maps.functions.d.ts +186950 -0
- package/dist-lib/lib/maps.functions.d.ts.map +1 -0
- package/dist-lib/lib/maps.functions.js +63 -0
- package/dist-lib/lib/utils.d.ts +3 -0
- package/dist-lib/lib/utils.d.ts.map +1 -0
- package/dist-lib/lib/utils.js +5 -0
- package/dist-lib/lib/validationSchemas.d.ts +15 -0
- package/dist-lib/lib/validationSchemas.d.ts.map +1 -0
- package/dist-lib/lib/validationSchemas.js +25 -0
- package/dist-lib/styles.css +1 -0
- package/package.json +87 -0
- package/public/logo.png +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Server-only Google-client. Alle Google-aanroepen van FlowSelections lopen
|
|
2
|
+
// via dit bestand. Authenticatie gebeurt met de Google Maps API-key die de
|
|
3
|
+
// centrale auth-module levert (provider google_maps).
|
|
4
|
+
import { getGoogleAccessToken } from "./central-auth.server";
|
|
5
|
+
const PLACES_SEARCH_URL = "https://places.googleapis.com/v1/places:searchText";
|
|
6
|
+
const ROUTE_MATRIX_URL = "https://routes.googleapis.com/distanceMatrix/v2:computeRouteMatrix";
|
|
7
|
+
async function googleFetch(url, body, fieldMask) {
|
|
8
|
+
const apiKey = await getGoogleAccessToken();
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: {
|
|
12
|
+
"X-Goog-Api-Key": apiKey,
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
"X-Goog-FieldMask": fieldMask,
|
|
15
|
+
},
|
|
16
|
+
body: JSON.stringify(body),
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
const detail = await response.text().catch(() => "");
|
|
20
|
+
throw new Error(`Google API-fout (status ${response.status}): ${detail.slice(0, 300)}`);
|
|
21
|
+
}
|
|
22
|
+
return response.json();
|
|
23
|
+
}
|
|
24
|
+
/** Zet één adres om naar coördinaten via Places Text Search. */
|
|
25
|
+
export async function geocodeAddress(rawAddress) {
|
|
26
|
+
const data = (await googleFetch(PLACES_SEARCH_URL, { textQuery: rawAddress, maxResultCount: 1, languageCode: "nl" }, "places.id,places.formattedAddress,places.location"));
|
|
27
|
+
const place = Array.isArray(data?.places) ? data.places[0] : undefined;
|
|
28
|
+
const lat = place?.location?.latitude;
|
|
29
|
+
const lng = place?.location?.longitude;
|
|
30
|
+
if (!place || typeof lat !== "number" || typeof lng !== "number")
|
|
31
|
+
return null;
|
|
32
|
+
return {
|
|
33
|
+
formattedAddress: place.formattedAddress ?? rawAddress,
|
|
34
|
+
lat,
|
|
35
|
+
lng,
|
|
36
|
+
placeId: place.id ?? "",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const TRAVEL_MODES = {
|
|
40
|
+
drive: "DRIVE",
|
|
41
|
+
bicycle: "BICYCLE",
|
|
42
|
+
walk: "WALK",
|
|
43
|
+
transit: "TRANSIT",
|
|
44
|
+
};
|
|
45
|
+
/** Reistijdmatrix (max 25x25 elementen per aanroep). */
|
|
46
|
+
export async function computeRouteMatrix(origins, destinations, mode = "drive") {
|
|
47
|
+
const waypoint = (point) => ({
|
|
48
|
+
waypoint: { location: { latLng: { latitude: point.lat, longitude: point.lng } } },
|
|
49
|
+
});
|
|
50
|
+
const data = (await googleFetch(ROUTE_MATRIX_URL, {
|
|
51
|
+
origins: origins.map(waypoint),
|
|
52
|
+
destinations: destinations.map(waypoint),
|
|
53
|
+
travelMode: TRAVEL_MODES[mode] ?? "DRIVE",
|
|
54
|
+
}, "originIndex,destinationIndex,duration,distanceMeters,condition"));
|
|
55
|
+
const rows = Array.isArray(data) ? data : [];
|
|
56
|
+
return rows.map((row) => ({
|
|
57
|
+
originIndex: row.originIndex ?? 0,
|
|
58
|
+
destinationIndex: row.destinationIndex ?? 0,
|
|
59
|
+
durationSec: typeof row.duration === "string"
|
|
60
|
+
? Number.parseInt(row.duration.replace("s", ""), 10)
|
|
61
|
+
: null,
|
|
62
|
+
distanceM: typeof row.distanceMeters === "number" ? row.distanceMeters : null,
|
|
63
|
+
status: row.condition === "ROUTE_EXISTS" ? "ok" : "unreachable",
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MapsOverview } from "./maps.functions";
|
|
2
|
+
export declare function getMapsOverviewData(): Promise<MapsOverview>;
|
|
3
|
+
export declare function saveMapsSettings(input: {
|
|
4
|
+
cacheTtlDays: number;
|
|
5
|
+
dailyCallLimit: number;
|
|
6
|
+
allowEstimateFallback: boolean;
|
|
7
|
+
provider: "free" | "google";
|
|
8
|
+
}): Promise<{
|
|
9
|
+
ok: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function clearCache(): Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function purgeExpired(): Promise<{
|
|
15
|
+
ok: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=maps-admin.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps-admin.server.d.ts","sourceRoot":"","sources":["../../src/lib/maps-admin.server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAiCrD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,YAAY,CAAC,CAuEjE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;;GAeA;AAED,wBAAsB,UAAU;;GAK/B;AAED,wBAAsB,YAAY;;GAQjC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Server-only beheerlogica voor de kaarten-module.
|
|
2
|
+
import { createClient } from "@supabase/supabase-js";
|
|
3
|
+
import { getGoogleConnectionStatus } from "./central-auth.server";
|
|
4
|
+
// Ruwe schatting: Routes/Places kosten ~ USD 5 per 1000 elementen.
|
|
5
|
+
// Alleen relevant zodra de betaalde Google-provider actief is.
|
|
6
|
+
const COST_PER_ELEMENT = 0.005;
|
|
7
|
+
function adminClient() {
|
|
8
|
+
const url = process.env["SUPABASE_URL"];
|
|
9
|
+
const key = process.env["SERVICE_ROLE_KEY"] ?? process.env["SUPABASE_SERVICE_ROLE_KEY"];
|
|
10
|
+
if (!url || !key)
|
|
11
|
+
throw new Error("Supabase serverconfiguratie ontbreekt.");
|
|
12
|
+
return createClient(url, key, {
|
|
13
|
+
auth: { persistSession: false, autoRefreshToken: false },
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function ensureSettings(db) {
|
|
17
|
+
const { data } = await db.from("maps_settings").select("*").limit(1).maybeSingle();
|
|
18
|
+
if (data)
|
|
19
|
+
return data;
|
|
20
|
+
const { data: created } = await db.from("maps_settings").insert({}).select("*").single();
|
|
21
|
+
return created;
|
|
22
|
+
}
|
|
23
|
+
async function count(db, table, apply) {
|
|
24
|
+
let query = db.from(table).select("id", { count: "exact", head: true });
|
|
25
|
+
if (apply)
|
|
26
|
+
query = apply(query);
|
|
27
|
+
const { count: total } = await query;
|
|
28
|
+
return total ?? 0;
|
|
29
|
+
}
|
|
30
|
+
export async function getMapsOverviewData() {
|
|
31
|
+
const db = adminClient();
|
|
32
|
+
const settings = await ensureSettings(db);
|
|
33
|
+
const status = await getGoogleConnectionStatus();
|
|
34
|
+
const now = new Date();
|
|
35
|
+
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
|
|
36
|
+
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1).toISOString();
|
|
37
|
+
const { data: monthRows } = await db
|
|
38
|
+
.from("maps_usage_log")
|
|
39
|
+
.select("elements, cache_hits, outcome, call_type, created_at")
|
|
40
|
+
.gte("created_at", startOfMonth);
|
|
41
|
+
const rows = Array.isArray(monthRows) ? monthRows : [];
|
|
42
|
+
// Alleen echte externe aanroepen tellen als "elementen".
|
|
43
|
+
const isRealCall = (row) => row.call_type === "geocode" || row.call_type === "matrix";
|
|
44
|
+
const billable = rows.filter((row) => isRealCall(row) && row.outcome === "ok");
|
|
45
|
+
const elementsMonth = billable.reduce((sum, row) => sum + (row.elements ?? 0), 0);
|
|
46
|
+
const elementsToday = billable
|
|
47
|
+
.filter((row) => row.created_at >= startOfDay)
|
|
48
|
+
.reduce((sum, row) => sum + (row.elements ?? 0), 0);
|
|
49
|
+
const cacheHitsMonth = rows.reduce((sum, row) => sum + (row.cache_hits ?? 0), 0);
|
|
50
|
+
const fallbacksMonth = rows.filter((row) => row.outcome === "fallback" || row.outcome === "skipped").length;
|
|
51
|
+
const errorsMonth = rows.filter((row) => isRealCall(row) && (row.outcome === "error" || row.outcome === "no_result")).length;
|
|
52
|
+
const [queuePending, queueFailed, addressCount, travelTimeCount, expiredCount] = await Promise.all([
|
|
53
|
+
count(db, "maps_request_queue", (q) => q.eq("status", "pending")),
|
|
54
|
+
count(db, "maps_request_queue", (q) => q.eq("status", "failed")),
|
|
55
|
+
count(db, "maps_addresses"),
|
|
56
|
+
count(db, "maps_travel_times"),
|
|
57
|
+
count(db, "maps_travel_times", (q) => q.lt("expires_at", now.toISOString())),
|
|
58
|
+
]);
|
|
59
|
+
return {
|
|
60
|
+
connected: status.connected,
|
|
61
|
+
connectionReason: status.reason,
|
|
62
|
+
settings: settings
|
|
63
|
+
? {
|
|
64
|
+
id: settings.id,
|
|
65
|
+
cacheTtlDays: settings.cache_ttl_days,
|
|
66
|
+
dailyCallLimit: settings.daily_call_limit,
|
|
67
|
+
allowEstimateFallback: settings.allow_estimate_fallback,
|
|
68
|
+
provider: settings.provider === "google" ? "google" : "free",
|
|
69
|
+
lastSuccessAt: settings.last_success_at,
|
|
70
|
+
lastErrorAt: settings.last_error_at,
|
|
71
|
+
lastError: settings.last_error,
|
|
72
|
+
}
|
|
73
|
+
: null,
|
|
74
|
+
queuePending,
|
|
75
|
+
queueFailed,
|
|
76
|
+
addressCount,
|
|
77
|
+
travelTimeCount,
|
|
78
|
+
expiredCount,
|
|
79
|
+
elementsToday,
|
|
80
|
+
elementsMonth,
|
|
81
|
+
cacheHitsMonth,
|
|
82
|
+
fallbacksMonth,
|
|
83
|
+
errorsMonth,
|
|
84
|
+
estimatedCostMonth: settings?.provider === "google"
|
|
85
|
+
? Number((elementsMonth * COST_PER_ELEMENT).toFixed(2))
|
|
86
|
+
: null,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export async function saveMapsSettings(input) {
|
|
90
|
+
const db = adminClient();
|
|
91
|
+
const settings = await ensureSettings(db);
|
|
92
|
+
const { error } = await db
|
|
93
|
+
.from("maps_settings")
|
|
94
|
+
.update({
|
|
95
|
+
cache_ttl_days: input.cacheTtlDays,
|
|
96
|
+
daily_call_limit: input.dailyCallLimit,
|
|
97
|
+
allow_estimate_fallback: input.allowEstimateFallback,
|
|
98
|
+
provider: input.provider,
|
|
99
|
+
updated_at: new Date().toISOString(),
|
|
100
|
+
})
|
|
101
|
+
.eq("id", settings.id);
|
|
102
|
+
if (error)
|
|
103
|
+
throw new Error(error.message);
|
|
104
|
+
return { ok: true };
|
|
105
|
+
}
|
|
106
|
+
export async function clearCache() {
|
|
107
|
+
const db = adminClient();
|
|
108
|
+
await db.from("maps_travel_times").delete().neq("id", "00000000-0000-0000-0000-000000000000");
|
|
109
|
+
await db.from("maps_addresses").delete().neq("id", "00000000-0000-0000-0000-000000000000");
|
|
110
|
+
return { ok: true };
|
|
111
|
+
}
|
|
112
|
+
export async function purgeExpired() {
|
|
113
|
+
const db = adminClient();
|
|
114
|
+
const { error } = await db
|
|
115
|
+
.from("maps_travel_times")
|
|
116
|
+
.delete()
|
|
117
|
+
.lt("expires_at", new Date().toISOString());
|
|
118
|
+
if (error)
|
|
119
|
+
throw new Error(error.message);
|
|
120
|
+
return { ok: true };
|
|
121
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps-diagnostics.server.d.ts","sourceRoot":"","sources":["../../src/lib/maps-diagnostics.server.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AAqI/B,oCAAoC;AACpC,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAEzE"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Server-only diagnose-logica voor de kaarten-module.
|
|
2
|
+
// Bouwt de diagnosestappen op met de Google-client en Supabase-toegang,
|
|
3
|
+
// via collectMapsDiagnostics uit central-auth.server.
|
|
4
|
+
import { createClient } from "@supabase/supabase-js";
|
|
5
|
+
import { collectMapsDiagnostics, } from "./central-auth.server";
|
|
6
|
+
import { geocodeAddress, computeRouteMatrix } from "./google-maps.server";
|
|
7
|
+
const TEST_ADDRESS = "Damrak 70, Amsterdam";
|
|
8
|
+
function errSummary(error) {
|
|
9
|
+
return error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200);
|
|
10
|
+
}
|
|
11
|
+
/** Probe-stap voor een Google-API-aanroep (Geocoding of Routes). */
|
|
12
|
+
async function probeGoogle(stepName, target) {
|
|
13
|
+
try {
|
|
14
|
+
if (stepName.includes("Geocoding")) {
|
|
15
|
+
const result = await geocodeAddress(TEST_ADDRESS);
|
|
16
|
+
if (!result) {
|
|
17
|
+
return {
|
|
18
|
+
name: stepName,
|
|
19
|
+
ok: false,
|
|
20
|
+
target,
|
|
21
|
+
httpStatus: null,
|
|
22
|
+
summary: "Google gaf geen adresresultaat terug.",
|
|
23
|
+
body: null,
|
|
24
|
+
code: "no_result",
|
|
25
|
+
hint: "Controleer of het testadres geldig is en of de Places-API is ingeschakeld voor het Google-project.",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
name: stepName,
|
|
30
|
+
ok: true,
|
|
31
|
+
target,
|
|
32
|
+
httpStatus: 200,
|
|
33
|
+
summary: `Geocoded naar "${result.formattedAddress}" (${result.lat}, ${result.lng}).`,
|
|
34
|
+
body: null,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Routes-test: 1×1 matrix tussen twee bekende punten.
|
|
38
|
+
const origin = { lat: 52.3731, lng: 4.8937 }; // Amsterdam Damrak
|
|
39
|
+
const destination = { lat: 52.3702, lng: 4.8952 }; // Amsterdam Centraal
|
|
40
|
+
const elements = await computeRouteMatrix([origin], [destination], "drive");
|
|
41
|
+
const el = Array.isArray(elements) ? elements[0] : null;
|
|
42
|
+
if (!el || el.status !== "ok") {
|
|
43
|
+
return {
|
|
44
|
+
name: stepName,
|
|
45
|
+
ok: false,
|
|
46
|
+
target,
|
|
47
|
+
httpStatus: null,
|
|
48
|
+
summary: "Google gaf geen route terug tussen de testpunten.",
|
|
49
|
+
body: null,
|
|
50
|
+
code: "no_route",
|
|
51
|
+
hint: "Controleer of de Routes-API is ingeschakeld voor het Google-project.",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
name: stepName,
|
|
56
|
+
ok: true,
|
|
57
|
+
target,
|
|
58
|
+
httpStatus: 200,
|
|
59
|
+
summary: `Route gevonden: ${el.durationSec ?? 0}s / ${el.distanceM ?? 0}m.`,
|
|
60
|
+
body: null,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return {
|
|
65
|
+
name: stepName,
|
|
66
|
+
ok: false,
|
|
67
|
+
target,
|
|
68
|
+
httpStatus: null,
|
|
69
|
+
summary: errSummary(error),
|
|
70
|
+
body: null,
|
|
71
|
+
code: "google_error",
|
|
72
|
+
hint: "Controleer de Google-API-status en of billing is ingeschakeld voor de Routes/Places-API.",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Probe-stap voor Supabase-toegang tot de maps_*-tabellen. */
|
|
77
|
+
async function probeSupabase() {
|
|
78
|
+
const target = "SELECT count(*) FROM maps_settings";
|
|
79
|
+
try {
|
|
80
|
+
const url = process.env["SUPABASE_URL"];
|
|
81
|
+
const key = process.env["SERVICE_ROLE_KEY"] ?? process.env["SUPABASE_SERVICE_ROLE_KEY"];
|
|
82
|
+
if (!url || !key) {
|
|
83
|
+
return {
|
|
84
|
+
name: "Supabase-toegang",
|
|
85
|
+
ok: false,
|
|
86
|
+
target,
|
|
87
|
+
httpStatus: null,
|
|
88
|
+
summary: "SUPABASE_URL of SERVICE_ROLE_KEY ontbreekt.",
|
|
89
|
+
body: null,
|
|
90
|
+
code: "supabase_config",
|
|
91
|
+
hint: "Voeg SUPABASE_URL en SERVICE_ROLE_KEY toe aan de server-omgeving.",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const db = createClient(url, key, {
|
|
95
|
+
auth: { persistSession: false, autoRefreshToken: false },
|
|
96
|
+
});
|
|
97
|
+
const { count, error } = await db
|
|
98
|
+
.from("maps_settings")
|
|
99
|
+
.select("id", { count: "exact", head: true });
|
|
100
|
+
if (error) {
|
|
101
|
+
return {
|
|
102
|
+
name: "Supabase-toegang",
|
|
103
|
+
ok: false,
|
|
104
|
+
target,
|
|
105
|
+
httpStatus: null,
|
|
106
|
+
summary: `Supabase-fout: ${error.message.slice(0, 200)}`,
|
|
107
|
+
body: null,
|
|
108
|
+
code: "supabase_error",
|
|
109
|
+
hint: "Controleer of de maps_*-tabellen bestaan en of de service-role sleutel toegang heeft.",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
name: "Supabase-toegang",
|
|
114
|
+
ok: true,
|
|
115
|
+
target,
|
|
116
|
+
httpStatus: null,
|
|
117
|
+
summary: `maps_settings bereikbaar (${count ?? 0} rijen).`,
|
|
118
|
+
body: null,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return {
|
|
123
|
+
name: "Supabase-toegang",
|
|
124
|
+
ok: false,
|
|
125
|
+
target,
|
|
126
|
+
httpStatus: null,
|
|
127
|
+
summary: errSummary(error),
|
|
128
|
+
body: null,
|
|
129
|
+
code: "supabase_error",
|
|
130
|
+
hint: "Controleer de Supabase-configuratie van de server.",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Volledige diagnose uitvoeren. */
|
|
135
|
+
export async function runMapsDiagnostics() {
|
|
136
|
+
return collectMapsDiagnostics(probeGoogle, probeSupabase);
|
|
137
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ProcessResult {
|
|
2
|
+
processed: number;
|
|
3
|
+
geocoded: number;
|
|
4
|
+
travelTimes: number;
|
|
5
|
+
failed: number;
|
|
6
|
+
skipped: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** SHA-256 hash via Web Crypto (browser, Node 15+ en Deno). */
|
|
9
|
+
export declare function addressHash(raw: string): Promise<string>;
|
|
10
|
+
/** Claimt de verwerkingslease. Geeft false als er al een run bezig is. */
|
|
11
|
+
export declare function claimQueueLease(): Promise<boolean>;
|
|
12
|
+
/** Geeft de verwerkingslease weer vrij. */
|
|
13
|
+
export declare function releaseQueueLease(): Promise<void>;
|
|
14
|
+
/** Verwerkt een batch uit de wachtrij. Veilig om vaker aan te roepen. */
|
|
15
|
+
export declare function processMapsQueueBatch(): Promise<ProcessResult>;
|
|
16
|
+
//# sourceMappingURL=maps-processor.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps-processor.server.d.ts","sourceRoot":"","sources":["../../src/lib/maps-processor.server.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,+DAA+D;AAC/D,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9D;AAcD,0EAA0E;AAC1E,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAUxD;AAED,2CAA2C;AAC3C,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMvD;AAgHD,yEAAyE;AACzE,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAmMpE"}
|