Files
gridpilot.gg/docs/architecture/website/FORM_SUBMISSION.md
2026-01-11 14:04:48 +01:00

3.1 KiB

Form Submission Flow (UI → System)

This document defines the only valid data flow when a user submits a form. It applies to all write operations (create, update, delete).

There are no exceptions.

Authoritative contract: WEBSITE_CONTRACT.md.

Core Principle

Read and Write paths are different.

What is displayed is never sent back.

Non-negotiable write boundary

All writes MUST enter the system through Next.js Server Actions.

Forbidden:

  • client components performing write HTTP requests
  • client components calling API clients for mutations

Allowed:

  • client submits intent (FormData, button action)
  • server action performs UX validation
  • server action calls the API

High-Level Flow

UI → Command DTO → API → Core Use Case → Persistence

•	View Models are read-only
•	Display Objects are read-only
•	Commands are write-only

  1. UI (Component)

Responsibility • Collect user input • Manage UX state (loading, disabled, local errors)

Rules • Only primitives are handled (string, number, boolean) • No DTO reuse • No ViewModel reuse • No domain objects

The UI does not decide whether an action is allowed.

  1. Form Model (Optional)

Responsibility • Local form state • Client-side validation (required, min/max length) • Field-level errors

Rules • UX-only validation • No business rules • Never shared with API or Core

  1. Command DTO (Frontend)

Responsibility • Express intent • Represent a write operation

Rules • Created fresh on submit • Never derived from a ViewModel • Never reused from read DTOs • Write-only

  1. Frontend Service

Responsibility • Orchestrate the write action • Call the API Client • Propagate success or failure

Rules • No business logic • No validation • No UI decisions • No ViewModel creation for writes (except explicit success summaries)

  1. API Client (Frontend)

Responsibility • Perform HTTP request • Handle transport-level failures

Rules • Stateless • No retries unless explicitly designed • Throws technical errors only

  1. API Layer (Backend)

Responsibility • HTTP boundary • Transport validation (schema / class-validator) • Map API DTO → Core Command

Rules • No business logic • No persistence • No UI concerns

  1. Core Use Case

Responsibility • Enforce business rules • Validate domain invariants • Change system state

Rules • Single source of truth • No UI logic • No HTTP knowledge

Response Handling

Success • API returns a Result DTO (IDs, status) • Frontend reacts by: • navigation • reload via GET • toast / confirmation

Failure • Business errors → user-visible message • Technical errors → error boundary / monitoring

Forbidden Patterns • ViewModel → Command • DisplayObject → API • DTO roundtrip • Domain Object in UI • Reusing read models for writes

Summary • Read Flow: DTO → ViewModel → UI • Write Flow: UI → Command DTO → Core

What is shown is never sent back.