a3aff9fa49
- add `src/core/modules/` with registry, discovery (server), and public index - add `src/core/public-pages/` with registry, server component, and public index - add `src/core/users/permissions-registry.js` for runtime permission registration - expose `./modules`, `./public-pages`, and `./public-pages/server` package exports - rename `registerFeatureRoutes` to `registerApiRoutes` with backward-compatible alias - extend `seedDefaultRolesAndPermissions` to include module-registered permissions - update `initializeZen` and shared init to wire module discovery and registration - add `docs/MODULES.md` documenting the `@zen/module-*` authoring contract - update `docs/DEV.md` with references to module system docs
29 lines
1011 B
JavaScript
29 lines
1011 B
JavaScript
import { notFound } from 'next/navigation';
|
|
import { getPublicModulePage } from './registry.js';
|
|
|
|
/**
|
|
* Composant serveur RSC catch-all pour `/zen/<module>/<...>`.
|
|
*
|
|
* Next.js route ce composant via un segment `[...path]`. Le premier segment
|
|
* identifie le module ; le reste est passé au composant enregistré qui fait
|
|
* son propre routage interne.
|
|
*
|
|
* `/zen/api/...` est intercepté en amont par la route API (`route.js`) qui
|
|
* est plus spécifique pour Next.js — ce composant ne le verra jamais en
|
|
* pratique, mais on garde le filtre par sûreté.
|
|
*/
|
|
export default async function PublicModulePage({ params }) {
|
|
const resolved = await params;
|
|
const path = Array.isArray(resolved?.path) ? resolved.path : [];
|
|
|
|
if (path.length === 0) notFound();
|
|
const [moduleName, ...rest] = path;
|
|
if (moduleName === 'api') notFound();
|
|
|
|
const entry = getPublicModulePage(moduleName);
|
|
if (!entry) notFound();
|
|
|
|
const { Component } = entry;
|
|
return <Component params={resolved} segments={rest} />;
|
|
}
|