fbd7d44e88
- Document module loader registry, category pages, and expanded module views - Record threat mitigations T-03-09, T-03-10, T-03-11 - Self-check passed: all files and commits verified
5.6 KiB
5.6 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, key_decisions, patterns_established, requirements_completed, duration, completed
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | key_decisions | patterns_established | requirements_completed | duration | completed | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-module-system-domaincheck | 03 | module-ui-loader |
|
|
|
|
|
|
|
6min | 2026-06-19 |
Phase 03 Plan 03: Module UI Lazy Loading + Category Pages Summary
Lazy-loaded module UI rendering via next/dynamic with slug-whitelist registry, category grid pages, and expanded module views
Performance
- Duration: 6 min
- Started: 2026-06-19T11:32:50Z
- Completed: 2026-06-19T11:38:50Z
- Tasks: 2/2
- Files created: 5
- Files modified: 2
Accomplishments
- MODULE_REGISTRY in module-loader.ts maps module slugs to dynamically imported components via next/dynamic with ssr:false, ensuring inactive modules are never bundled (MOD-04)
- Category page at /modules/[category] fetches active modules from API, filters by category, and renders a responsive card grid (D-04)
- ModuleCard component displays icon, name, localized description, and link to expanded view with hover effects (D-05a)
- Expanded module view at /modules/[category]/[moduleSlug] loads the module component on demand via whitelist lookup (D-05b)
- API client utilities (getActiveModules, getModuleBySlug) provide typed fetch wrappers for module endpoints
- i18n keys added for "modules" namespace in both German and English
Task Commits
Each task was committed atomically:
- Task 1: Module Loader Utility + Category Page with Lazy Cards -
a191628(feat) - Task 2: Expanded Module View with Dynamic Routing -
de63b10(feat)
Files Created/Modified
apps/web/src/lib/module-loader.ts- MODULE_REGISTRY with loadModuleComponent and loadModuleCard exportsapps/web/src/lib/api.ts- getActiveModules and getModuleBySlug API client functionsapps/web/src/app/(portal)/modules/[category]/page.tsx- Category page with module grid and empty stateapps/web/src/app/(portal)/modules/[category]/components/ModuleCard.tsx- Module card with icon, description, and linkapps/web/src/app/(portal)/modules/[category]/[moduleSlug]/page.tsx- Expanded module view with lazy loading and not-found stateapps/web/src/messages/de.json- Added modules namespace (categoryTitle, openModule, noModules, notFound, etc.)apps/web/src/messages/en.json- Added modules namespace (categoryTitle, openModule, noModules, notFound, etc.)
Decisions Made
- Slug whitelist pattern: MODULE_REGISTRY acts as an allowlist — only explicitly registered slugs can trigger dynamic imports. Arbitrary URL slugs get a not-found state, never an import attempt (T-03-09).
- Client components throughout: All three pages use 'use client' to support next/dynamic with ssr:false and client-side fetch with credentials:include for auth cookie forwarding.
- Inline SVG icons: ModuleCard uses inline SVGs rather than an icon library to avoid adding a dependency for a small number of icons. Icons are mapped by the module's icon property (e.g., 'Globe' for domaincheck).
- Category filtering: The category page fetches all active modules and filters client-side by category. This keeps the API simple (single /modules/active endpoint) while supporting category-based views.
Threat Mitigations Applied
| Threat ID | Mitigation | Implementation |
|---|---|---|
| T-03-09 | Slug whitelist via MODULE_REGISTRY | module-loader.ts: only registered slugs resolve to components; [moduleSlug]/page.tsx checks slug in MODULE_REGISTRY before loading |
| T-03-10 | API filters by tenant active modules | [category]/page.tsx: fetches from /modules/active which is tenant-scoped server-side |
| T-03-11 | Accepted | Module names/descriptions are non-sensitive catalog data |
Deviations from Plan
None - plan executed exactly as written.
Verification Results
pnpm --filter web build: PASS- Route
/modules/[category]generated: confirmed in build output (2.01 kB) - Route
/modules/[category]/[moduleSlug]generated: confirmed in build output (1.95 kB) - Domaincheck module code at
/modules/domaincheck(1.47 kB) is separate from category page, confirming code-splitting works - No stubs or placeholders found in created files
Self-Check: PASSED
All 5 created files verified on disk. Both task commits (a191628, de63b10) verified in git log.