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

@@ -1,56 +1,40 @@
# Presenters (Strict)
# Builders (Deprecated)
This document defines the **Presenter** boundary for `apps/website`.
**This document is deprecated.** See [`BUILDERS.md`](docs/architecture/website/BUILDERS.md) for the current pattern.
Presenters exist to prevent responsibility drift into:
## Summary of changes
- server routes
- Page Queries
- Templates
The architecture has been updated to use **Builders** instead of **Presenters**:
## 1) Definition
### Old pattern (deprecated)
- `lib/presenters/` - All transformations
- `lib/view-models/` - ViewModels + some presenters
A **Presenter** is a deterministic, side-effect free transformation between website presentation models.
### New pattern (current)
- `lib/builders/view-models/` - DTO → ViewModel
- `lib/builders/view-data/` - ViewModel → ViewData
- `lib/view-models/` - ViewModels only
Allowed transformations:
### Why the change?
- Page DTO → ViewData
- Page DTO → ViewModel
- ViewModel → ViewData
The old pattern had **three anti-patterns**:
## 2) Non-negotiable rules
1. **Inconsistent naming** - Same concept had 3 names (Presenter, Transformer, ViewModelPresenter)
2. **Inconsistent location** - Presenters lived in both `lib/presenters/` and `lib/view-models/`
3. **Confusing semantics** - "Presenter" implies presenting to client, but some presenters prepared data for server templates
1. Presenters MUST be deterministic.
2. Presenters MUST be side-effect free.
3. Presenters MUST NOT perform HTTP.
4. Presenters MUST NOT call API clients.
5. Presenters MUST NOT access cookies/headers.
6. Presenters MAY use Display Objects.
7. Presenters MUST NOT import Templates.
### What changed?
## 3) Where Presenters run
**ViewModel Builders** (DTO → ViewModel):
- Location: `lib/builders/view-models/`
- Naming: `*ViewModelBuilder`
- Example: `AdminViewModelBuilder.build(dto)`
Presenters run in **client code only**.
**ViewData Builders** (ViewModel → ViewData):
- Location: `lib/builders/view-data/`
- Naming: `*ViewDataBuilder`
- Example: `LeagueViewDataBuilder.build(viewModel, id)`
Presenters MUST be defined in `'use client'` modules.
This makes the architecture **self-documenting** and **clean**.
If a computation affects routing decisions (redirect, notFound), it belongs in a Page Query or server route composition, not in a Presenter.
## 4) Relationship to Display Objects
Display Objects implement reusable formatting/mapping.
Rules:
- Presenters may orchestrate Display Objects.
- Display Object instances MUST NOT appear in ViewData.
See [`DISPLAY_OBJECTS.md`](docs/architecture/website/DISPLAY_OBJECTS.md:1) and [`VIEW_DATA.md`](docs/architecture/website/VIEW_DATA.md:1).
## 5) Canonical placement in this repo (strict)
Presenters MUST live colocated with ViewModels under:
- `apps/website/lib/view-models/**`
Reason: this repo already treats `apps/website/lib/view-models/**` as the client-only presentation module boundary.
See [`BUILDERS.md`](docs/architecture/website/BUILDERS.md) for full details.