# View Models

## Definition

A **View Model** represents a **fully prepared UI state**.

It answers the question:

> “What does the UI need in order to render this screen without thinking?”

View Models are **UI-owned** classes.
They do not represent business truth and do not enforce domain rules.

**Uncle Bob says**: "Objects expose behavior, not data." ViewModels encapsulate the behavior of the UI.

---

## Responsibilities

A View Model MAY:

- accept an API DTO as input
- derive UI-specific fields
- combine or reshape data for rendering
- perform formatting (dates, numbers, labels), especially for **client-only context** (e.g., local timezone, relative "time ago")
- handle localization and presentation logic
- use **Display Objects** for reusable UI concerns and rich APIs

### Formatting Responsibility

While `ViewData Builders` handle formatting for SEO and initial render using **Formatters**, `View Models` are responsible for:
- **Client-specific formatting:** Data that depends on the browser's locale, timezone, or precise location.
- **Interactive formatting:** Updating display values in response to user input or state changes.
- **Rich APIs:** Providing **Display Objects** to the UI for multi-variant formatting (e.g., `date.short`, `date.relative`).

In the website SSR/RSC architecture, View Models MAY compute view-only derived values, but MUST NOT be the type passed into Templates.

A View Model MUST:

- be fully usable by the UI without further computation
- expose only data and UI-oriented helpers
- be created in a consistent, explicit way

---

## Restrictions

A View Model MUST NOT:

- contain business logic
- validate domain rules
- enforce permissions or authorization
- contain domain entities or value objects
- perform side effects
- be sent back to the server

If a View Model decides whether something is *allowed* or *correct*,
that logic belongs in the Core, not here.

---

## Ownership & Placement

- View Models belong to the **frontend**
- They live close to the UI, not in shared or core layers
- They are not shared with the backend

---

## Creation Rules

This repository distinguishes **Page DTO**, **ViewModel**, and **ViewData**:

- Page DTO: server-to-client payload (JSON-serializable)
- ViewModel: client-only class (never serialized)
- ViewData: template input (JSON-serializable)

Rules (website):

1) View Models are created in client code only.
2) View Models are created from **ViewData** (not from DTOs).
3) Templates MUST NOT accept View Models; Templates accept ViewData only.
4) View Models MUST compose Display Objects and produce rich UI APIs.

Authoritative reference: [plans/nextjs-rsc-viewmodels-concept.md](plans/nextjs-rsc-viewmodels-concept.md:1).

---

## Testing

View Models SHOULD be tested when they contain:

- formatting logic
- localization behavior
- non-trivial derived fields

View Models do NOT need tests if they only expose data without logic.

---

## Summary

- View Models describe **UI state**
- They are **presentation-focused**, not business-focused
- They reduce complexity in components
- They form a stable contract for the UI
