Frontend & Backend Output Shapes – Clean Architecture (Strict, Final) This document defines the exact responsibilities, naming, and placement of all data shapes involved in delivering data from Core → API → Frontend UI. It resolves all ambiguity around Presenters, View Models, DTOs, and Output Ports. There is no overlap of terminology across layers. ⸻ 1. Core Layer (Application / Use Cases) Core Output Ports (formerly “Presenters”) In the Core, a Presenter is not a UI concept. It is an Output Port that defines how a Use Case emits its result. Rules • Core Output Ports: • define what data is emitted • do not store state • do not expose getters • do not reference DTOs or View Models • Core never pulls data back from an output port • Core calls present() and stops Naming • *OutputPort • *Result (pure application result) Example export interface CompleteDriverOnboardingResult { readonly success: boolean; readonly driverId?: string; readonly error?: string; } export interface CompleteDriverOnboardingOutputPort { present(result: CompleteDriverOnboardingResult): void; } The Core does not know or care what happens after present() is called. ⸻ 2. API Layer (Delivery / Adapter) API Presenters (Response Mappers) API Presenters are Adapters. They: • implement Core Output Ports • translate Core Results into API Response DTOs • store response state temporarily for the controller They are not View Models. Rules • API Presenters: • implement a Core Output Port • map Core Results → API Responses • may store state internally • API Presenters must not: • contain business logic • reference frontend View Models Naming • *Presenter or *ResponseMapper • Output types end with Response or ApiResponse ⸻ 3. Frontend Layer (apps/website) View Models (UI-Owned, Final Form) A View Model represents fully prepared UI state. Only the frontend has Views — therefore only the frontend has View Models. Rules • View Models: • live only in apps/website • accept API Response DTOs as input • expose UI-ready data and helpers • View Models must not: • contain domain logic • validate business rules • perform side effects • be sent back to the server Naming • *ViewModel ⸻ 4. Website Presenters (DTO → ViewModel) Website Presenters are pure mappers. They: • convert API Response DTOs into View Models • perform formatting and reshaping • are deterministic and side-effect free They are not Core Presenters. Rules • Input: API DTOs • Output: View Models • Must not: • call APIs • read storage • perform decisions ⸻ 5. API Client (Frontend) The API Client is a thin HTTP layer. Rules • Sends HTTP requests • Returns API DTOs only • Must not: • return View Models • contain business logic • format data for UI ⸻ 6. Website Services (Orchestration) Website Services orchestrate: • API Client calls • Website Presenter mappings They are the only layer allowed to touch both. Rules • Services: • call API Client • call Website Presenters • return View Models only • Components never touch API Client or DTOs ⸻ 7. Final Data Flow (Unambiguous) Core Use Case → OutputPort.present(Result) API Presenter (Adapter) → maps Result → ApiResponse API Controller → returns ApiResponse (JSON) Frontend API Client → returns ApiResponse DTO Website Presenter → maps DTO → ViewModel UI Component → consumes ViewModel ⸻ 8. Terminology Rules (Strict) Term Layer Meaning OutputPort Core Use case output contract Result Core Pure application result Presenter (API) apps/api Maps Result → API Response Response / ApiResponse apps/api HTTP transport shape Presenter (Website) apps/website Maps DTO → ViewModel ViewModel apps/website UI-ready state No term is reused with a different meaning. ⸻ 9. Non-Negotiable Rules • Core has no DTOs • Core has no View Models • API has no View Models • Frontend has no Core Results • View Models exist only in the frontend • Presenters mean different things per layer, but: • Core = Output Port • API = Adapter • Website = Mapper ⸻ 10. Final Merksatz The Core emits results. The API transports them. The Frontend interprets them. If a type tries to do more than one of these — it is incorrectly placed.