// R-P5 (P5) §P3 — pure route-path builders for Apps-Engine URLs. Loaders build // these and pass them into the VMs so the VMs stay routing-agnostic. // // NOTE: DataConnection is tenant-scoped (tenant connector + integrations.* tenant // permission), so its management screens live in the tenant settings workspace. // OAuth callbacks remain outside the settings workspace under /integrations/:provider. // Tenant connector module key. It lives in this client-safe module (not in // integrationsAccess.server) so a route `handle` export can reference it without // dragging the server-only access guard into the client bundle (RR code-splitting // only strips loader/action/middleware/headers, not `handle`). export const INTEGRATIONS_MODULE_KEY = "integrations"; export const KWP_SETUP_PATH = "/integrations/kwp/setup"; export const KWP_OAUTH_CALLBACK_PATH = "/integrations/kwp/oauth/callback"; export function integrationsCatalogPath(tenantSlug: string): string { return `/${tenantSlug}/settings/integrations`; } export function integrationsAppPath(tenantSlug: string, appKey: string): string { return `/${tenantSlug}/settings/integrations/${appKey}`; } export function kwpProjectImportPath(tenantSlug: string): string { return `/${tenantSlug}/settings/integrations/kwp/import`; } export function kwpSetupPath(tenantSlug?: string): string { const normalizedTenantSlug = tenantSlug?.trim(); return normalizedTenantSlug ? `${KWP_SETUP_PATH}?tenant=${encodeURIComponent(normalizedTenantSlug)}` : KWP_SETUP_PATH; } export function kwpMandantSelectionPath(tenantSlug: string, connectionId: string): string { const query = new URLSearchParams({ tenant: tenantSlug.trim(), connection: connectionId.trim() }); return `${KWP_SETUP_PATH}?${query.toString()}`; } export function integrationsSyncsPath(tenantSlug: string, appKey: string, connectionId: string): string { return `/${tenantSlug}/settings/integrations/${appKey}/${connectionId}/syncs`; } export function integrationsSyncRunPath(tenantSlug: string, appKey: string, connectionId: string, runId: string): string { return `/${tenantSlug}/settings/integrations/${appKey}/${connectionId}/syncs/${runId}`; } export function legacyIntegrationsRedirectPath(requestUrl: string, tenantSlug: string): string | null { const url = new URL(requestUrl); const legacyPrefix = `/${tenantSlug}/integrations`; if (url.pathname !== legacyPrefix && !url.pathname.startsWith(`${legacyPrefix}/`)) { return null; } const settingsSuffix = url.pathname.slice(legacyPrefix.length); return `/${tenantSlug}/settings/integrations${settingsSuffix}${url.search}${url.hash}`; }