# Proforma List Contract ## UI model - frontend keeps `archiveView=active|archived|all` as semantic UI state - frontend keeps `status=all|draft|sent|approved|rejected|issued` - `archiveView` is not a backend query param ## Backend contract `GET /proformas` stays based on `Criteria`: - `q` - `pageNumber` - `pageSize` - `orderBy` - `order` - `filters[]` ## Allowed filters - `archived_at IS_NULL` - `archived_at IS_NOT_NULL` - `status EQUALS draft|sent|approved|rejected|issued` ## Scope rules - active view -> `archived_at IS_NULL` - archived view -> `archived_at IS_NOT_NULL` - all view -> no `archived_at` filter - status `all` -> no `status` filter - any concrete status -> `status EQUALS ` - `q` applies after the scope is defined by `filters[]` ## Resource visibility - `GET /proformas` defaults to active scope - `GET /proformas/:id` returns archived proformas too - soft-deleted proformas never appear in list results - soft-deleted proformas are treated as non-existent by `GET /proformas/:id` ## Frontend persistence - URL stores `archiveView` - URL stores `status` - URL stores `q` - `localStorage["proformas:list:grid"]` keeps only table preferences