website refactor

This commit is contained in:
2026-01-12 19:24:59 +01:00
parent 1f0c4f7fa6
commit 5ea95eaf51
54 changed files with 2894 additions and 2342 deletions

View File

@@ -42,18 +42,52 @@ Authoritative contract: [`WEBSITE_CONTRACT.md`](docs/architecture/website/WEBSIT
- JSON-serializable only.
- Contains only values ready to render (mostly strings/numbers).
- Built from Page DTO (initial render) and from ViewModel (post-hydration).
- Built from API DTO directly in RSC.
The mapping between Page DTO, ViewModel, and ViewData is performed by Presenters.
See [`PRESENTERS.md`](docs/architecture/website/PRESENTERS.md:1).
The mapping between API DTO and ViewData is performed by ViewData Builders.
See [`BUILDERS.md`](docs/architecture/website/BUILDERS.md:1).
## 3) Required per-route structure
Every route MUST follow:
### Server Components (RSC)
Every RSC route MUST follow:
1) `page.tsx` (server): calls a PageQuery and passes Page DTO
2) `*PageClient.tsx` (client): builds ViewData and renders Template
3) `*Template.tsx` (pure UI): renders ViewData only
1) `page.tsx`: calls a PageQuery
2) `page.tsx`: builds ViewData using ViewDataBuilder
3) `page.tsx`: renders Template with ViewData
Example:
```typescript
export default async function AdminDashboardPage() {
const apiDto = await AdminDashboardPageQuery.execute();
const viewData = AdminDashboardViewDataBuilder.build(apiDto);
return <AdminDashboardTemplate viewData={viewData} />;
}
```
### Client Components
Client components that need API data MUST follow:
1) `*Client.tsx`: fetches API DTO
2) `*Client.tsx`: builds ViewModel using ViewModelBuilder
3) `*Client.tsx`: renders Template with ViewModel
Example:
```typescript
'use client';
export function AdminDashboardClient() {
const [viewModel, setViewModel] = useState<AdminDashboardViewModel | null>(null);
useEffect(() => {
const apiDto = await adminApiClient.getDashboard();
const vm = AdminDashboardViewModelBuilder.build(apiDto);
setViewModel(vm);
}, []);
return viewModel ? <AdminDashboardTemplate viewModel={viewModel} /> : null;
}
```
All writes enter through Server Actions.
See [`FORM_SUBMISSION.md`](docs/architecture/website/FORM_SUBMISSION.md:1).