# Units Specification

## Purpose

The Units capability provides a back-office management screen for measurement-unit reference data, allowing administrators to create and edit units used across product definitions, order lines, and receipts. It is a thin admin CRUD restricted to authenticated administrators and exposed at the `settings/units` resource route. (Implemented in `app/Http/Controllers/UnitController.php`, `routes/web.php:86-89`)

## Requirements

### Requirement: List Units Screen

The system SHALL render `GET settings/units` as a two-column HTML page: the left column contains a sortable grid of all existing units, and the right column contains an inline create form. The grid SHALL display columns `id`, `name`, and `description` with no create button, export control, row selector, filter, or pagination. (Implemented in `app/Http/Controllers/UnitController.php:20-41,54-64`)

#### Scenario: Authenticated administrator loads the list

- **GIVEN** a request is made by an authenticated administrator
- **WHEN** `GET settings/units` is received
- **THEN** the system responds with HTTP 200 and an HTML page containing the units grid and the inline "new unit" form side by side

#### Scenario: Grid presents only id, name, and description

- **GIVEN** units exist in the system
- **WHEN** the list page is rendered
- **THEN** the grid shows exactly the `id` (sortable), `name`, and `description` columns with no export button, row checkbox, search filter, or page controls

### Requirement: Create Unit Via Inline Form

The system SHALL accept `POST settings/units` with fields `name` (required) and `description` (optional), persist a new unit, and redirect back to the list. Submitting without `name` SHALL return a validation error and persist nothing. (Implemented in `app/Http/Controllers/UnitController.php:76-82`)

#### Scenario: Valid create submission

- **GIVEN** an authenticated administrator on the list page
- **WHEN** the inline form is submitted with a non-empty `name` and an optional `description`
- **THEN** a new unit row is persisted and the response is a `302` redirect back to the list

#### Scenario: Missing name on create

- **GIVEN** an authenticated administrator on the list page
- **WHEN** the inline form is submitted with `name` absent or empty
- **THEN** validation fails, no unit is created, and the user is redirected back with an error

### Requirement: Edit Unit

The system SHALL render `GET settings/units/{id}/edit` as an HTML edit form with `name` (required) and `description` fields for any unit that is not the default unit (id 1). `PUT settings/units/{id}` SHALL update the unit and redirect back to the list. Requesting an unknown `id` SHALL return HTTP 404. (Implemented in `app/Http/Controllers/UnitController.php:43-49,76-82`)

#### Scenario: Valid edit submission

- **GIVEN** an authenticated administrator and a unit whose id is not 1
- **WHEN** the edit form is submitted with a non-empty `name`
- **THEN** the unit's `name` and `description` are updated and the response is a `302` redirect to the list

#### Scenario: Missing name on edit

- **GIVEN** an authenticated administrator editing a non-locked unit
- **WHEN** the form is submitted with `name` absent or empty
- **THEN** validation fails, the unit is not updated, and the user is redirected back with an error

#### Scenario: Unknown id on edit

- **GIVEN** an authenticated administrator
- **WHEN** `GET settings/units/{id}/edit` or `PUT settings/units/{id}` is requested with an id that does not exist
- **THEN** the system responds with HTTP 404

### Requirement: Default Unit Edit Lock

The system SHALL suppress the edit row-action for the unit with id `1` in the grid, making that unit immutable through the UI. (Implemented in `app/Http/Controllers/UnitController.php:67-69`)

#### Scenario: Default unit row has no edit action

- **GIVEN** the units grid is rendered
- **WHEN** the row for the unit with id `1` is displayed
- **THEN** no edit action link or button is present for that row

#### Scenario: Non-default unit row has an edit action

- **GIVEN** the units grid is rendered and a unit with id other than `1` exists
- **WHEN** that row is displayed
- **THEN** an edit action link or button is present for that row

### Requirement: Deletion Disabled for All Units

The system SHALL suppress the delete row-action for every unit in the grid. No unit SHALL be deletable through the UI. (Implemented in `app/Http/Controllers/UnitController.php:70`)

#### Scenario: No row offers a delete action

- **GIVEN** the units grid is rendered with one or more units
- **WHEN** any row is displayed
- **THEN** no delete action link or button is present on any row

### Requirement: Admin Authentication Required

The system SHALL require an authenticated administrator session for all `settings/units` routes. Unauthenticated requests SHALL receive a `302` redirect to `auth/login`. (Implemented in `routes/web.php:24-28,86-89`)

#### Scenario: Unauthenticated request is redirected

- **GIVEN** no authenticated admin session exists
- **WHEN** any request is made to a `settings/units` route
- **THEN** the system responds with HTTP 302 redirecting to `auth/login`

#### Scenario: Authenticated request proceeds

- **GIVEN** a valid authenticated administrator session exists
- **WHEN** a request is made to `GET settings/units`
- **THEN** the system responds with HTTP 200 and the list page
