/** * 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 = { 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; }