# Units — Implementation Tasks

> Produced by the Reversa **Writer** (phase: generation) · doc_level: `complete`
> Generated on 2026-09-21

**Confidence scale:** 🟢 CONFIRMED · 🟡 INFERRED · 🔴 GAP

## Prerequisites

- [ ] `Encore\Admin` installed with the `ModelForm` trait, grid/form/widgets/layout components. 🟢 (`UnitController.php:6-18`)
- [ ] `Unit` model (bare Eloquent, no relations/casts/fillable). 🟢 (`Unit.php`)
- [ ] `units` table (`id`, `name`, `description`, nullable `category_id`, timestamps) present. 🟢 (`create_units_table` migration)
- [ ] A seeded default unit at id 1. 🟢 (`UnitController.php:67`)
- [ ] Admin route group `['web','admin']` + `settings` prefix. 🟢 (`routes/web.php:86-89`)

## Tasks

> Each task references the legacy file the behaviour was extracted from.

- [ ] T-01, Register `resource settings/units` → `UnitController` inside the `settings` prefix group.
  - Legacy origin: `routes/web.php:89`
  - Done when: the seven resource routes resolve for an authenticated admin; anonymous → `302` to `auth/login`.
  - Confidence: 🟢

- [ ] T-02, Implement `index()`: two-column `Admin::content` (header `Đơn vị`) — left `grid()->render()`, right an inline `Widgets\Form` (action `settings/units`) with `name`(required)/`description` in a green `Box`.
  - Legacy origin: `UnitController.php:20-41`
  - Done when: the page shows the grid and the inline create form.
  - Confidence: 🟢

- [ ] T-03, Implement `grid()`: columns id(sortable)/name/description; disable create button, export, row selector, filter, pagination.
  - Legacy origin: `UnitController.php:54-64`
  - Done when: the grid shows the three columns with none of the disabled controls.
  - Confidence: 🟢

- [ ] T-04, Implement the row-action lock: `disableDelete()` on every row; `disableEdit()` when the row key is `1`.
  - Legacy origin: `UnitController.php:66-71`
  - Done when: no row offers delete; the id-1 row offers no edit.
  - Confidence: 🟢

- [ ] T-05, Implement `edit($id)` (`form()->edit($id)`) and `form()` (`name` required / `description`) so `ModelForm` store/update/edit work.
  - Legacy origin: `UnitController.php:43-49,76-82`
  - Done when: creating and editing units persists `name`/`description`, with `name` required.
  - Confidence: 🟢

- [ ] T-06, (Cleanup, not in legacy) Decide the fate of the dead `units.category_id` column — drop it or wire it to a real feature.
  - Legacy origin: `create_units_table` migration:20; `units` flowchart:39
  - Done when: the column is either removed by migration or documented as actively used.
  - Confidence: 🟡

- [ ] T-07, (Improvement, not in legacy) Reconcile base-unit-by-name (`products.unit`) with conversion-by-id (`product_units.unit_id`) so renaming a unit stays consistent.
  - Legacy origin: `units` flowchart:28-32
  - Done when: a unit rename propagates (or the base unit is stored by id).
  - Confidence: 🟡

- [ ] T-08, (Improvement, not in legacy) Make the default-unit lock resilient — key the edit lock off a seeded flag/slug rather than the literal id `1`.
  - Legacy origin: `UnitController.php:67`
  - Done when: the default unit stays protected regardless of its id.
  - Confidence: 🟡

- [ ] T-09, (Improvement, not in legacy) Add observability on unit create/update.
  - Legacy origin: `UnitController.php` (absence)
  - Done when: unit mutations emit a structured log or metric.
  - Confidence: 🔴

## Test Tasks

- [ ] TT-01, List: `GET settings/units` returns the grid + inline create form (see `requirements.md`, Acceptance Criteria).
- [ ] TT-02, Create happy path: posting `name`+`description` persists a unit.
- [ ] TT-03, Create validation: posting without `name` fails and creates nothing.
- [ ] TT-04, Edit: updating a non-locked unit's `name`/`description` persists.
- [ ] TT-05, Locks: the id-1 row offers no edit; no row offers delete.
- [ ] TT-06, Auth: anonymous request → `302` to `auth/login`.

## Data Migration Tasks (if applicable)

- [ ] TM-01, Ensure the `units` table and its seeded default (id 1) exist before products/`product_units` reference units.
  - Legacy origin: `create_units_table` migration; `UnitController.php:67`

## Suggested Order

1. T-01 → T-02 (route + index screen).
2. T-03 → T-05 (grid, locks, form/edit).
3. T-06 → T-09 (cleanup and improvements).

## Pending Gaps (🔴)

- **No observability (T-09):** unit mutations emit no signal.
- **Dead `category_id` column (T-06):** confirm removal or intended use.
