Files
tessera-ctl/apps/web/src/lib/module-loader.ts
T
schalli 01ff137f43
Tessera CI/CD / Lint & Type Check (push) Waiting to run
Tessera CI/CD / Tests (push) Blocked by required conditions
Tessera CI/CD / Build & Deploy (push) Blocked by required conditions
fix(07): UAT fixes — SMTP test email, DKV routing, Exchange domain field
- SMTP: add test-to field, send real email via sendMail() instead of verify()
- SMTP: fix no_auth warning shown as error for open-relay servers
- DKV: register dkv-fleet in MODULE_REGISTRY (fixes "Modul nicht gefunden")
- DKV: add dynamic [category]/[moduleSlug]/settings + vehicles sub-routes
- DKV: settings/vehicles links use useParams for consistent URLs
- DKV: add gear icon settings link to module main page
- DKV: rename module to "DKV-Rechnung" in seed + translations
- DKV: add optional domain field for Exchange (WebCredentials 3rd arg)
- DKV: hide IMAP-only fields (Port/Verschlüsselung/Ordner) when Exchange selected
- DKV: hide Exchange-only field (Domain) when IMAP selected
- Prisma: add domain column to DkvModuleConfig

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 21:58:26 +02:00

73 lines
2.0 KiB
TypeScript

/**
* Module Loader — Lazy-loading registry for Tessera modules.
*
* Maps module slugs to dynamically imported components.
* Only modules listed in MODULE_REGISTRY will have their code loaded;
* inactive/unregistered modules never trigger an import (MOD-04).
*
* Security: Only whitelisted slugs are resolved — arbitrary slugs
* from URL params return null (T-03-09).
*/
import dynamic from 'next/dynamic';
import type { ComponentType } from 'react';
/**
* Registry entry for a module's lazy-loaded components.
*/
interface ModuleRegistryEntry {
/** Main module page component (loaded on demand) */
component: ComponentType;
/** Optional card component for category grid view */
cardComponent?: ComponentType;
}
/**
* Module registry mapping slugs to lazy-loaded components.
*
* To register a new module, add its slug and dynamic imports here.
* Components are only fetched when React renders them (code-splitting).
*/
export const MODULE_REGISTRY: Record<string, ModuleRegistryEntry> = {
domaincheck: {
component: dynamic(
() => import('@/app/(portal)/modules/domaincheck/page'),
{ ssr: false },
),
},
'dkv-fleet': {
component: dynamic(
() => import('@/app/(portal)/modules/dkv-fleet/page'),
{ ssr: false },
),
},
};
/**
* Load the main component for a module by slug.
*
* @param slug - Module slug (e.g., 'domaincheck')
* @returns The dynamic component, or null if the slug is not registered
*/
export function loadModuleComponent(
slug: string,
): ComponentType | null {
const entry = MODULE_REGISTRY[slug];
return entry?.component ?? null;
}
/**
* Load the card component for a module by slug.
*
* Falls back to null if no card component is registered.
*
* @param slug - Module slug (e.g., 'domaincheck')
* @returns The card component, or null if not available
*/
export function loadModuleCard(
slug: string,
): ComponentType | null {
const entry = MODULE_REGISTRY[slug];
return entry?.cardComponent ?? null;
}