feat(F-065): completed feature

This commit is contained in:
chattie
2026-08-19 17:12:25 +02:00
parent a6d65310df
commit e60e22ca30
14 changed files with 169 additions and 12 deletions

View File

@@ -0,0 +1,64 @@
# F-065 — Implementer evidence
## Scope delivered
`<input type="search">` controls across the storefront frontend and the
admin backoffice were missing the `id` and `name` attributes, which
fails the a11y lint rule `form-field-element-required` (and similar
browser autofill heuristics). Every affected search input now carries
both attributes.
## Changes
| File | Input | Added |
| ---- | ----- | ----- |
| `project/frontend/src/components/layout/Header.tsx` | header live search | `id="site-search" name="q"` |
| `project/frontend/src/app/search/page.tsx` | full search form | `id="search-page-q"` |
| `project/apps/admin/src/app/(dashboard)/products/page.tsx` | products list search | `id="admin-products-search" name="q"` |
| `project/apps/admin/src/app/(dashboard)/customers/page.tsx` | customers search | `id="admin-customers-search" name="q"` |
| `project/apps/admin/src/app/(dashboard)/inventory/page.tsx` | inventory search | `id="admin-inventory-search" name="q"` |
| `project/apps/admin/src/app/(dashboard)/orders/page.tsx` | orders search | `id="admin-orders-search" name="q"` |
`name="q"` is meaningful for the forms that submit via GET (header live
search and the storefront `/search` page use it as the query parameter),
and for the admin filters it provides a stable identifier that browser
autofill can latch onto.
## Acceptance traceability
| Acceptance criterion | How it is met |
| -------------------- | ------------- |
| Every search input has an `id` attribute and a meaningful `name` attribute | All six inputs updated. |
| a11y lint rule `form-field-element-required` (and equivalents) are happy | The original report referenced `A form field element should have an id or name attribute`; both are now present. |
| `verify.sh` is green | Exit 0. |
## Manual verification
```
$ curl -s http://192.168.18.93:3003/ | python3 -c "import re,sys; html=sys.stdin.read(); print('\n'.join(re.findall(r'<input[^>]*type=\"search\"[^>]*>', html)[:1]))"
<input type="search" id="site-search" placeholder="…" class="…" name="q" value=""/>
$ curl -s http://192.168.18.93:3003/search | python3 -c "import re,sys; html=sys.stdin.read(); print('\n'.join(re.findall(r'<input[^>]*type=\"search\"[^>]*>', html)))"
<input type="search" id="site-search" placeholder="…" class="…" name="q" value=""/>
<input id="search-page-q" type="search" placeholder="…" name="q" value=""/>
```
The admin inputs are client-rendered; the source was updated and the
typecheck/build passes.
## Build verification
- `npx tsc --noEmit` (frontend / admin) — exit 0
- `./scripts/verify.sh` — exit 0
- Admin and frontend services restarted via `monolith.sh prod restart`
## Files touched
```
project/frontend/src/components/layout/Header.tsx (id + name)
project/frontend/src/app/search/page.tsx (id)
project/apps/admin/src/app/(dashboard)/products/page.tsx (id + name)
project/apps/admin/src/app/(dashboard)/customers/page.tsx (id + name)
project/apps/admin/src/app/(dashboard)/inventory/page.tsx (id + name)
project/apps/admin/src/app/(dashboard)/orders/page.tsx (id + name)
```

View File

@@ -0,0 +1,13 @@
{
"feature_id": "F-065",
"agent": "leader",
"verdict": "APPROVED",
"summary": "All gates approved. Closing F-065.",
"evidence": [
"work/artifacts/F-065/reviewer.json verdict=APPROVED",
"work/artifacts/F-065/security.json verdict=APPROVED",
"work/artifacts/F-065/qa.json verdict=APPROVED",
"./scripts/verify.sh exit 0"
],
"timestamp": "2026-08-19T15:30:00Z"
}

View File

@@ -0,0 +1,13 @@
{
"feature_id": "F-065",
"agent": "qa",
"verdict": "APPROVED",
"summary": "End-to-end trace. Rendered HTML on the storefront frontend shows the header and search-page inputs both have id and name. Admin pages were also updated at the source level; typecheck and verify.sh pass.",
"evidence": [
"AC1 'Every search input has an id attribute and a meaningful name attribute' — confirmed in source and in rendered HTML on / and /search",
"AC2 'a11y lint rule no-autofocus and form-field-label are happy' — the original report's 'A form field element should have an id or name attribute' is satisfied; no autofocus regression on the search-page input (still intentional)",
"AC3 'verify.sh is green' — exit 0",
"Regression: typecheck green for frontend and admin; admin and frontend services restarted and responding 200"
],
"timestamp": "2026-08-19T15:30:00Z"
}

View File

@@ -0,0 +1,14 @@
{
"feature_id": "F-065",
"agent": "reviewer",
"verdict": "APPROVED",
"summary": "Six search inputs (header + search page + four admin filters) now carry both id and name. Names use the meaningful 'q' convention. The rendered HTML on the storefront matches: id=site-search, name=q.",
"evidence": [
"git diff — six files, each adding id (and name where the field is a search form) to the input",
"curl / on port 3003 → <input type=\"search\" id=\"site-search\" ... name=\"q\" value=\"\"/>",
"curl /search on port 3003 → header + page inputs both have id+name",
"npx tsc --noEmit (frontend / admin) — exit 0",
"./scripts/verify.sh — exit 0"
],
"timestamp": "2026-08-19T15:30:00Z"
}

View File

@@ -0,0 +1,13 @@
{
"feature_id": "F-065",
"agent": "security",
"verdict": "APPROVED",
"summary": "Attribute-only change. No new endpoints, no new input handling, no new dependencies. The id values are stable strings used purely for label association; the name attribute was already used by the GET forms to read the query parameter, so no information disclosure or injection vector changed.",
"evidence": [
"Only HTML attributes added; no event handlers changed",
"Stable id strings (site-search, admin-products-search, …) do not leak information",
"name='q' is already the public query parameter on /search; no new naming",
"No new env vars, no new dependencies"
],
"timestamp": "2026-08-19T15:30:00Z"
}