## 2026-04-24 Device API IDOR Closure For `/devices/:id*`
### Latest Verification Snapshot
| Command | Result | Note |
|------|------|------|
| `go test ./internal/api/handler -run 'TestDeviceHandler_(GetDevice|UpdateDevice|DeleteDevice|TrustDevice|UntrustDevice|UpdateDeviceStatus)_IDOR_Forbidden' -count=1` | `PASS` | targeted handler regression set is green after owner/admin checks were wired into all device-by-id routes |
| `go test ./internal/service -run 'TestDeviceService_DeviceOwnershipAuthorization' -count=1` | `PASS` | targeted service regression set is green after adding actor-aware authorization helpers |
| `go test ./internal/api/handler -run 'TestDeviceHandler_' -count=1` | `PASS` | broader device handler regression set stays green after the authorization change |
| `go test ./internal/service -run 'Test(DeviceService_|BusinessLogic_DEV_)' -count=1` | `PASS` | broader device service and business-logic regression set stays green after the authorization change |
| `go test ./... -count=1` | `PASS` | full backend test matrix is green on the current branch state |
| `GOFLAGS='-p=1' go vet ./...` | `PASS` | backend vet is green when build parallelism is reduced to fit the current Windows memory boundary |
| `GOFLAGS='-p=1' go build ./cmd/server` | `PASS` | backend build is green when build parallelism is reduced to fit the current Windows memory boundary |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `PASS` | supported browser-level gate re-ran green with `21` isolated scenario runs, including `device-management` after the device-authorization fix |
### Current Honest Status
- The device-interface IDOR gap is closed on the current branch state for the supported device-by-id routes:
-`GET /api/v1/devices/:id`
-`PUT /api/v1/devices/:id`
-`DELETE /api/v1/devices/:id`
-`PUT /api/v1/devices/:id/status`
-`POST /api/v1/devices/:id/trust`
-`DELETE /api/v1/devices/:id/trust`
- The concrete defect fixed in this round was that those handlers trusted the path `id` directly and forwarded it into service methods that had no actor-aware ownership check, so any authenticated user who knew another device ID could read or mutate that device.
- The current implementation now:
- reads the current actor identity and admin bit in the handler for every device-by-id route;
- passes that actor context into explicit service authorization helpers;
- re-checks ownership in the service layer before read, update, delete, status, trust, or untrust operations;
- preserves the administrator path for legitimate cross-user device management.
- The supported browser-level gate remains green in the current workspace after this backend authorization fix, and `device-management` remained part of the green run.
### Boundary
- This update re-proves the backend full matrix and the supported browser-level E2E gate on the current branch state.
- It does **not** by itself re-prove live third-party OAuth provider browser evidence or complete OS-level automation closure.
## 2026-04-24 Password Authorization Closure For `/users/:id/password`
### Latest Verification Snapshot
| Command | Result | Note |
|------|------|------|
| `go test ./internal/service -run 'TestUserService_(ChangePassword|AdminResetPassword)' -count=1` | `PASS` | targeted service regression set is green after adding explicit admin reset semantics |
| `go test ./internal/api/handler -run 'TestUserHandler_UpdatePassword_(NonAdminCannotUpdateAnotherUser|AdminCanResetAnotherUser)' -count=1` | `PASS` | targeted handler regression set is green after enforcing `self-or-admin` authorization |
| `go test ./... -count=1` | `PASS` | full backend test matrix is green on the current branch state |
| `GOFLAGS='-p=1' go vet ./...` | `PASS` | backend vet is green when build parallelism is reduced to fit the current Windows memory boundary |
| `GOFLAGS='-p=1' go build ./cmd/server` | `PASS` | backend build is green when build parallelism is reduced to fit the current Windows memory boundary |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `PASS` | supported browser-level gate re-ran green with `21` isolated scenario runs, including `profile-and-security` after the password-authorization fix |
### Current Honest Status
- The authorization gap on `PUT /api/v1/users/:id/password` is closed on the current branch state.
- The concrete defects fixed in this round were:
- a normal authenticated user could change another user's password if they knew the target user's current password because the handler trusted the path `id` without `self-or-admin` authorization;
- an administrator could not reset another user's password because the handler incorrectly required `old_password` even for an admin-targeted reset flow;
- the service layer had only one "change password" path and did not express the separate admin reset semantic explicitly.
- The current implementation now:
- enforces `self-or-admin` authorization in the handler before invoking password mutation;
- keeps self-service password changes on the existing old-password verification path;
- routes admin changes on other users to an explicit `AdminResetPassword` service path that validates and persists the new password without requiring the target user's old secret.
- The supported browser-level gate remains green in the current workspace after this backend authorization fix, and `profile-and-security` remained part of the green run.
### Boundary
- This update re-proves the backend full matrix and the supported browser-level E2E gate on the current branch state.
- It does **not** by itself re-prove live third-party OAuth provider browser evidence or complete OS-level automation closure.
| `cd frontend/admin && npm.cmd run test:run -- src/lib/playwright-e2e-scenarios.test.ts` | `PASS` | scenario-selection regression tests are green after moving scenario planning into a shared helper |
| `cd frontend/admin && npm.cmd run test:run` | `PASS` | full frontend unit and component suite is green on the current workspace state (`83` files / `525` tests) |
| `cd frontend/admin && node --check ./scripts/run-playwright-cdp-e2e.mjs` | `PASS` | Playwright CDP runner script is syntactically valid after adding list mode and shared scenario selection |
| `cd frontend/admin && npm.cmd run lint` | `PASS` | frontend lint is green after the browser-wrapper orchestration change |
| `cd frontend/admin && npm.cmd run build` | `PASS` | frontend production build is green after the browser-wrapper orchestration change |
| `cd frontend/admin && $env:E2E_SCENARIOS='email-activation'; npm.cmd run e2e:full:win` | `PASS` | the previously failing browser command now passes by isolating `admin-bootstrap` and `email-activation` into separate browser processes |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `PASS` | the supported browser-level gate is green again with `21` isolated scenario runs in the current workspace (`admin-bootstrap` plus the `20` steady-state scenarios) |
### Current Honest Status
- The supported browser-level real E2E command `cd frontend/admin && npm.cmd run e2e:full:win` is green again in the current workspace.
- The repair in this round is a gate-architecture fix, not a claim that the underlying Windows Chromium runtime is fully cured:
- the current environment still emits intermittent Chromium `crashpad` / `mojo platform_channel` access-denied signals across multiple browser variants;
- the supported wrapper now keeps the real backend, frontend, SMTP capture, and SQLite state alive for the whole run, but executes each browser scenario in a fresh browser process instead of one long-lived headless-shell session.
- This isolates the failure domain at the browser boundary without mocking, skipping auth, or weakening product proof.
- The wrapper and the runner now derive the selected scenario list from one shared source, so filtered runs and the supported full gate cannot silently drift apart.
### Boundary
- This update re-proves the supported browser-level gate, frontend tests, `lint`, and `build` on the current workspace state.
- It does **not** by itself re-prove the backend full matrix (`go test ./... -count=1`, `go vet ./...`, `go build ./cmd/server`) in this latest batch, and it does **not** prove that the underlying Chromium `0x5` runtime issue has disappeared from the host environment.
## 2026-04-24 Profile Management Contract Recovery And Main-Gate Reality Check
### Latest Verification Snapshot
| Command | Result | Note |
|------|------|------|
| `go test ./internal/api/handler -run 'TestUserHandler_UpdateUser_(Success|AdminCanUpdateAnotherUser|ProfileFieldsPersisted)' -count=1` | `PASS` | targeted handler regression set is green after expanding the real update/detail contract |
| `cd frontend/admin && $env:E2E_SCENARIOS='profile-management'; npm.cmd run e2e:full:win` | `PASS` | the supported official browser entrypoint is green for `admin-bootstrap` plus `profile-management` |
| `go test ./... -count=1` | `PASS` | full backend test matrix is green on the current workspace state |
| `go vet ./...` | `PASS` | backend vet is green on the current workspace state |
| `go build ./cmd/server` | `PASS` | backend build is green on the current workspace state |
| `cd frontend/admin && npm.cmd run lint` | `PASS` | frontend lint is green after the browser-wrapper and profile-contract changes |
| `cd frontend/admin && npm.cmd run build` | `PASS` | frontend production build is green after the browser-wrapper and profile-contract changes |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `FAIL` | the unfiltered supported browser gate is still intermittently blocked by the pre-existing `admin-bootstrap` headless-shell disconnect on this workspace state |
### Current Honest Status
- The `/profile` browser closure is now real on the current branch state:
- the backend `PUT /api/v1/users/:id` handler now accepts the profile fields the page actually submits (`gender`, `birthday`, `region`, `bio`, along with the existing fields);
- the backend `GET /api/v1/users/:id` response now returns the profile fields the page actually hydrates and re-reads after save;
- the supported official browser sub-gate `cd frontend/admin && $env:E2E_SCENARIOS='profile-management'; npm.cmd run e2e:full:win` passed with `admin-bootstrap` on the same workspace state.
- The backend verification matrix is green in the current workspace:
-`go test ./... -count=1`
-`go vet ./...`
-`go build ./cmd/server`
- The frontend static verification matrix is green in the current workspace:
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
- The full unfiltered supported browser command is **not** green in the current workspace as of 2026-04-24:
-`cd frontend/admin && npm.cmd run e2e:full:win` still redlines at the already-known `admin-bootstrap` browser lifecycle flake before the rest of the suite can complete.
- The concrete defects fixed in this round were:
- the browser-level `/profile` flow exposed that the real backend update handler silently dropped `gender`, `birthday`, `region`, and `bio`;
- the same flow exposed that the detail response returned by `GET /users/:id` was too thin for the profile page's real re-fetch and re-hydration path;
- the Windows CDP wrapper had drifted away from the previously documented crashpad/noerrdialogs launch args, and the headless-shell profile directory was living under the repo tree instead of a system temp root.
### Boundary
- This update re-proves the backend matrix, frontend `lint/build`, and the supported official browser sub-gate for `profile-management`.
- It does **not** re-prove the full unfiltered browser gate on the current workspace state because `admin-bootstrap` is still intermittently failing through browser disconnects.
- The supported browser-level real E2E command `cd frontend/admin && npm.cmd run e2e:full:win` is green in the current workspace after re-verifying the full `20`-scenario suite.
- The directly affected frontend verification set is green in the current workspace:
- targeted profile page and service tests
-`npm.cmd run lint`
-`npm.cmd run build`
- The concrete defects fixed in this round were:
- frontend profile password writes were still sending the UI form shape (`current_password`, `confirm_password`) to `/users/:id/password`, while the real backend handler binds `old_password` and `new_password`, which produced a real browser-visible `400`;
- the Playwright `profile-and-security` scenario could leave background fetch waiters running after a later locator failure, which then collapsed into misleading `Target page, context or browser has been closed` noise instead of exposing the true failing step.
- This round did **not** re-run the full backend matrix (`go test ./... -count=1`, `go vet ./...`, `go build ./cmd/server`); the latest backend-wide green evidence remains the 2026-04-23 snapshot below.
### Boundary
- This update re-proves the directly affected frontend regression set and the supported browser-level E2E gate in the current workspace.
- It does **not** by itself re-prove the full backend matrix, live third-party OAuth verification, or OS-level automation closure.
## 2026-04-23 Permissions CRUD And Full Matrix Closure
### Latest Verification Snapshot
| Command | Result | Note |
|------|------|------|
| `go test ./... -count=1` | `PASS` | full backend test matrix re-ran green on the current branch state |
| `go vet ./...` | `PASS` | backend vet is green on the current branch state |
| `go build ./cmd/server` | `PASS` | backend build is green on the current branch state |
| `cd frontend/admin && npm.cmd run test:run` | `PASS` | frontend unit/integration suite passed `82` files / `522` tests |
| `cd frontend/admin && npm.cmd run lint` | `PASS` | frontend lint is green after the permissions/browser harness updates |
| `cd frontend/admin && npm.cmd run build` | `PASS` | frontend production build is green after the explicit Vite root fix |
| `cd frontend/admin && node --check ./scripts/run-playwright-cdp-e2e.mjs` | `PASS` | Playwright CDP runner script is syntactically valid after the permissions CRUD and CDP stability changes |
| `cd frontend/admin && $env:E2E_SCENARIOS='permissions-management-crud'; npm.cmd run e2e:full:win` | `PASS` | targeted browser-level proof is green for `admin-bootstrap` plus `permissions-management-crud` |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `PASS` | supported browser-level Playwright CDP E2E path re-ran green with `20` scenarios in the current workspace |
### Current Honest Status
- The full backend matrix (`go test ./... -count=1`, `go vet ./...`, `go build ./cmd/server`) is green in the current workspace.
- The full frontend matrix (`npm.cmd run test:run`, `npm.cmd run lint`, `npm.cmd run build`) is green in the current workspace.
- The supported browser-level real E2E command `cd frontend/admin && npm.cmd run e2e:full:win` is green in the current workspace.
- The re-verified browser scenarios now include `20` flows:
-`admin-bootstrap`
-`public-registration`
-`email-activation`
-`password-reset`
-`login-surface`
-`auth-workflow`
-`responsive-login`
-`desktop-mobile-navigation`
-`user-management-crud`
-`user-management-batch`
-`role-management-crud`
-`permissions-management-crud`
-`device-management`
-`login-logs`
-`operation-logs`
-`webhook-management`
-`import-export`
-`profile-and-security`
-`settings`
-`dashboard-stats`
- The concrete defects fixed in this round were:
- the permissions service adapter moved to the real numeric backend `type` contract, and older aggregate service tests were updated to match the new raw payload shape instead of asserting stale string payloads;
- backend permission creation/status handling now accepts real browser payloads such as menu `type=0` and numeric `status` updates without falsely rejecting valid requests;
- the permissions browser CRUD scenario was red because CDP `page.waitForRequest/Response` could miss successful proxied `/api/v1/permissions` calls even while the browser `fetch` had already returned `201`; the runner now proves those steps through in-page fetch completion plus UI refresh instead of misclassifying them as product failures;
- Ant modal close assertions in the permissions flow were tightened to accept real leave-state transitions instead of requiring a brittle `hidden` state that could lag under headless-shell animation timing;
- frontend aggregate tests now reflect the real permissions adapter contract, avoiding false red tests after a valid service-layer schema change;
- frontend production build on Windows with `vite --configLoader native` was failing because Vite 8 resolved `index.html` as an absolute emitted asset name; setting explicit `root` in `frontend/admin/vite.config.js` restored a green build;
- the browser harness is more tolerant of transient Windows CDP startup/runtime instability after raising the suite retry default to `3` and aligning the CDP attach timeout with the startup timeout window.
### Boundary
- This update re-proves the supported browser-level E2E path and the full local backend/frontend verification matrices in the current workspace.
- It does **not** by itself re-prove real third-party OAuth live verification or complete OS-level automation closure.
## 2026-04-23 Password Reset And E2E Stability Update
### Latest Verification Snapshot
| Command | Result | Note |
|------|------|------|
| `go test ./... -count=1` | `PASS` | full backend test matrix re-ran green on the current branch state |
| `go vet ./...` | `PASS` | backend vet is green after the auth capability fix |
| `go build ./cmd/server` | `PASS` | backend build is green after the auth capability fix |
| `cd frontend/admin && npm.cmd run test:run` | `PASS` | frontend unit/integration suite passed `82` files / `521` tests |
| `cd frontend/admin && npm.cmd run lint` | `PASS` | frontend lint is green after the password-reset and CDP recovery changes |
| `cd frontend/admin && npm.cmd run build` | `PASS` | frontend production build is green after the password-reset and CDP recovery changes |
| `cd frontend/admin && npm.cmd run e2e:full:win` | `PASS` | supported browser-level Playwright CDP E2E path re-ran green with `19` scenarios in the current workspace |
### Current Honest Status
- The full backend matrix (`go test ./... -count=1`, `go vet ./...`, `go build ./cmd/server`) is green again in the current workspace.
- The full frontend matrix (`npm.cmd run test:run`, `npm.cmd run lint`, `npm.cmd run build`) is green again in the current workspace.
- settings frontend service was double-unwrapping `/admin/settings` even though the shared HTTP client had already returned `result.data`.
- backend `/api/v1/auth/capabilities` omitted `password_reset`, so the real login surface never exposed the password-reset entry even though the route was mounted.
- the outer browser-suite retry path was carrying a stale `admin-bootstrap` expectation across attempts even after the first attempt had already changed backend bootstrap state.
- the Playwright CDP runner did not reconnect the browser connection when a late-stage page/context disappeared, so a single headless-shell target closure could falsely redline the rest of the suite.
- added a strict live-delivery drill entrypoint in [`scripts/ops/drill-alertmanager-live-delivery.ps1`](/D:/project/scripts/ops/drill-alertmanager-live-delivery.ps1)
- the new drill refuses unresolved placeholders, `example.*` addresses/hosts, and placeholder secrets instead of producing fake success
- the drill writes only redacted config output and masked recipient evidence, so real contacts and secrets are not leaked into the repo evidence tree
- [`scripts/ops/validate-alerting-package.ps1`](/D:/project/scripts/ops/validate-alerting-package.ps1) now falls back to the latest available baseline report across prior evidence dates, removing a date-rollover false blocker
- structural alerting package validation still passes
- render drill still passes
- the new live-delivery drill fails closed against `alertmanager.env.example`, which is the correct behavior and proves the path does not fake production closure
- Real remaining blocker:
-`Q-006` now narrows to one external proof item: a real non-placeholder env/secret source plus a successful live SMTP acceptance run for the configured on-call receivers
- The `frontend/admin``Q-004` closure track can now be honestly declared closed.
- Real closure evidence:
- the latest full frontend `test:coverage` run no longer emits the previously recurring post-summary jsdom `AggregateError` network-noise lines
-`frontend/admin/src/app/router.tsx` remained at `100 / 100 / 100 / 100` in that same full-suite run, so the earlier transient regression is not part of the current real state
- Validation passed:
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `93.98%`
- branches `82.29%`
- functions `91.37%`
- lines `94.15%`
- Latest full test result:
-`54` passing test files
-`248` passing tests
- Real hygiene note:
- the previous jsdom `AggregateError` noise is absent in the latest successful run
- the remaining command-line warning is the external npm user-config warning `Unknown user config "//git@github.com/"`, not a project-generated frontend validation failure
-`Q-004` remediation progressed again, but still cannot be honestly declared closed.
- Frontend theme-provider closure:
-`frontend/admin/src/app/providers/ThemeProvider.tsx` is now covered at `100 / 100 / 100 / 100`.
-`frontend/admin/src/app/providers/ThemeProvider.test.tsx` now covers locale propagation, theme-token propagation, component-level override propagation, and child rendering through `ConfigProvider`.
- Validation passed:
-`cd frontend/admin && npm.cmd run test:run -- src/app/providers/ThemeProvider.test.tsx`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `93.93%`
- branches `82.29%`
- functions `91.37%`
- lines `94.10%`
- Real remaining `Q-004` frontend gap after this closure:
- the post-summary jsdom `AggregateError` network-noise hygiene issue
- Real hygiene note:
- all previously identified frontend code hotspots in this closure track are now covered and re-verified
- the successful frontend coverage run still prints post-summary jsdom `AggregateError` network-noise lines, so the run is green but not yet fully clean
-`Q-004` remediation progressed again, but still cannot be honestly declared closed.
- Frontend breadcrumb-hook closure:
-`frontend/admin/src/lib/hooks/useBreadcrumbs.ts` is now covered at `100 / 100 / 100 / 100`.
- the hook was simplified to remove redundant parent-injection logic that was dead under the current route model.
-`frontend/admin/src/lib/hooks/useBreadcrumbs.test.tsx` now covers root, single-segment, nested, and unknown-segment breadcrumb behavior.
- Validation passed:
-`cd frontend/admin && npm.cmd run test:run -- src/lib/hooks/useBreadcrumbs.test.tsx`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `93.84%`
- branches `82.29%`
- functions `91.21%`
- lines `94.01%`
- Real remaining `Q-004` frontend gaps after this closure:
-`src/app/providers/ThemeProvider.tsx`
- the post-summary jsdom `AggregateError` network-noise hygiene issue
- Real hygiene note:
- the successful frontend coverage run still prints post-summary jsdom `AggregateError` network-noise lines, so the run is green but not yet fully clean
-`Q-004` remediation progressed again, but still cannot be honestly declared closed.
- Frontend 404-page closure:
-`frontend/admin/src/pages/NotFoundPage/NotFoundPage.tsx` is now covered at `100 / 100 / 100 / 100`.
-`frontend/admin/src/pages/NotFoundPage/NotFoundPage.test.tsx` now covers 404 rendering, missing-page messaging, and navigation back to `/dashboard`.
- Validation passed:
-`cd frontend/admin && npm.cmd run test:run -- src/pages/NotFoundPage/NotFoundPage.test.tsx`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `93.69%`
- branches `81.95%`
- functions `91.24%`
- lines `93.85%`
- Real remaining `Q-004` frontend gaps after this closure:
-`src/lib/hooks/useBreadcrumbs.ts`
-`src/app/providers/ThemeProvider.tsx`
- the post-summary jsdom `AggregateError` network-noise hygiene issue
- Real hygiene note:
- the successful frontend coverage run still prints post-summary jsdom `AggregateError` network-noise lines, so the run is green but not yet fully clean
-`Q-004` remediation progressed again, but still cannot be honestly declared closed.
- Frontend import/export closure:
-`frontend/admin/src/pages/admin/ImportExportPage/ImportExportPage.tsx` is now covered at `100 / 100 / 100 / 100`.
-`frontend/admin/src/pages/admin/ImportExportPage/ImportExportPage.test.tsx` now covers template format switching, validation guards, import success and warning flows, reset behavior, export field updates, and export failure handling.
- Validation passed:
-`cd frontend/admin && npm.cmd run test:run -- src/pages/admin/ImportExportPage/ImportExportPage.test.tsx`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `93.56%`
- branches `81.95%`
- functions `90.93%`
- lines `93.71%`
- Real remaining `Q-004` frontend gaps after this closure:
-`src/pages/NotFoundPage/NotFoundPage.tsx`
-`src/lib/hooks/useBreadcrumbs.ts`
-`src/app/providers/ThemeProvider.tsx`
- the post-summary jsdom `AggregateError` network-noise hygiene issue
- Real hygiene note:
- the page-local `window.getComputedStyle(..., pseudoElt)` noise introduced during the first draft of this pass has been removed
- the successful frontend coverage run still prints post-summary jsdom `AggregateError` network-noise lines, so the run is green but not yet fully clean
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass
## 2026-03-28 Coverage Remediation Update XIV
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade auth recovery page coverage for `ForgotPasswordPage` and `ResetPasswordPage`
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass
## 2026-03-28 Coverage Remediation Update XIII
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade page coverage for `src/pages/admin/ProfileSecurityPage/ProfileSecurityPage.tsx`
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass
## 2026-03-28 Coverage Remediation Update XII
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade module coverage for `src/lib/http/client.ts`
- a production hygiene fix for shared refresh-promise rejection handling
-`src/lib/http/client.ts` is no longer a remaining `Q-004` gap
-`Q-004` still cannot be truthfully closed
- the remaining highest-value frontend gap is now more concentrated in:
- deeper remaining `ProfileSecurityPage` branches
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass
## 2026-03-28 Coverage Remediation Update XI
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade module coverage for `src/lib/http/csrf.ts`
-`src/lib/http/csrf.ts` is no longer a remaining `Q-004` gap
-`Q-004` still cannot be truthfully closed
- the remaining highest-value frontend gaps are now more concentrated in:
-`src/lib/http/client.ts`
- deeper remaining `ProfileSecurityPage` branches
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass
## 2026-03-28 Coverage Remediation Update X
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade behavior coverage for `src/pages/auth/RegisterPage/RegisterPage.tsx`
-`RegisterPage` is no longer a remaining `Q-004` gap
-`Q-004` still cannot be truthfully closed
- the remaining highest-value frontend gaps are now more concentrated in:
- deeper remaining `ProfileSecurityPage` branches
-`lib/http`
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- the required sequential `lint` -> `build` -> `test:coverage` path passed in this pass without a new build-path regression observation
## 2026-03-28 Coverage Remediation Update IX
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade behavior coverage for `src/pages/auth/LoginPage/LoginPage.tsx`
- the remaining highest-value frontend gaps are now more concentrated in:
-`RegisterPage`
- deeper remaining `ProfileSecurityPage` branches
-`lib/http`
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
- one concurrent `lint` + `build` attempt produced a transient Windows/Vite `index.html` emit-path failure; the required standalone `build` rerun passed immediately afterward
- this is real observation, but not yet proven to be a deterministic repo defect
## 2026-03-28 Coverage Remediation Update VIII
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- closure-grade provider behavior coverage for `src/app/providers/AuthProvider.tsx`
-`AuthProvider` is no longer a remaining `Q-004` gap
-`Q-004` still cannot be truthfully closed
- the remaining highest-value frontend gaps are now more concentrated in:
-`LoginPage`
-`RegisterPage`
- deeper remaining `ProfileSecurityPage` branches
-`lib/http`
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
## 2026-03-28 Coverage Remediation Update VII
-`Q-004` improved materially again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- full modal/drawer coverage for the remaining `UsersPage` component cluster
- full modal/drawer coverage for the remaining `WebhooksPage` component cluster
- deeper repository coverage across role/permission/relation repositories
- A real backend defect pair was discovered and fixed during this pass:
-`internal/repository/role.go`
- explicit role create requests with `status=0` were being persisted as enabled because the DB default swallowed the zero value
-`internal/repository/permission.go`
- explicit permission create requests with `status=0` were being persisted as enabled for the same reason
-`UsersPage` is no longer a dominant uncovered admin cluster
-`WebhooksPage` is no longer a dominant uncovered admin cluster
-`internal/repository` has improved materially, but `Q-004` still cannot be truthfully closed
- the remaining highest-value gaps are now more concentrated in:
- deeper remaining `ProfileSecurityPage` branches
-`LoginPage` / `RegisterPage`
-`app/providers/AuthProvider`
-`lib/http`
- remaining repository depth outside the newly covered role/permission/relation paths
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
## 2026-03-28 Coverage Remediation Update VI
-`Q-004` improved materially again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- deep transport-based coverage across `internal/auth/providers`
-`internal/auth/providers` is no longer one of the dominant `Q-004` blockers
-`RolesPage`, `PermissionsPage`, and `ProfilePage` are no longer dominant uncovered admin page clusters
-`Q-004` still cannot be truthfully closed because the remaining high-value gaps have narrowed to:
-`internal/repository` depth (`37.1%`)
-`UsersPage` drawers/modals
-`WebhooksPage` modal/drawer components
- deeper remaining `ProfileSecurityPage` branches
- the frontend coverage run still emits one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
## 2026-03-27 Coverage Remediation Update V
-`Q-004` improved again after another strict remediation pass, but it still remains open.
- This pass added and verified:
- frontend regression coverage for `LoginLogsPage`
- frontend regression coverage for `OperationLogsPage`
- deeper non-network parsing/error coverage for `internal/auth/providers`
- frontend service adapters are no longer a primary `Q-004` gap
-`LoginLogsPage` and `OperationLogsPage` are no longer primary page-level hotspots
-`internal/auth/providers` improved materially but is still too shallow to declare `Q-004` closed
- the highest-value next work remains deeper provider paths plus still-uncovered admin pages/components such as `PermissionsPage`, `RolesPage`, `ProfilePage`, and multiple drawers/modals
- the latest successful frontend coverage run still emitted one post-summary jsdom `AggregateError` noise line, so the validation path is green but not yet perfectly clean
## 2026-03-27 Coverage Remediation Update IV
-`Q-004` has continued to improve and was re-verified again, but it still remains open.
- This pass mainly closed much of the frontend service-adapter gap:
-`users.ts`
-`roles.ts`
-`devices.ts`
-`profile.ts`
-`login-logs.ts`
-`operation-logs.ts`
-`permissions.ts`
-`stats.ts`
-`import-export.ts`
- This pass also increased non-network provider coverage through:
- Alipay private-key parsing/signing tests
- Twitter PKCE auth URL tests
- OAuth helper error-body boundary tests
- Strict verification caught one more real engineering issue during this pass:
- the first version of the new permission-service tests passed under Vitest but failed under `tsc -b` because the fixture payloads did not match the real request types
- The earlier high-priority quality-audit items around browser-side token persistence, OAuth `return_to` trust boundary, and fail-open security randomness are now closed at implementation level and re-verified.
- Backend/session closure:
- refresh continuity is now based on the backend-managed `HttpOnly` refresh cookie.
- the backend now emits a non-sensitive session-presence cookie (`ums_session_present`) so the frontend can distinguish "restore is possible" from "no server session exists".
- OAuth `return_to` no longer trusts request-derived forwarded origin inference; it is restricted to absolute paths or explicit allowlisted origins.
- security-sensitive random generation no longer silently degrades on `crypto/rand` failure.
- Frontend/session closure:
- access token, current user, and current roles are memory-only and no longer persist into `localStorage` / `sessionStorage`.
-`AuthProvider` now avoids blind `/auth/refresh` probing when no session-presence cookie exists.
- protected-route restore failure no longer loses the original route intent; redirect ownership is back on `RequireAuth`.
- post-login route races are hardened by exporting effective auth state from the in-memory session store.
- Real-browser closure:
- the supported CDP E2E path was rerun after the session model change and now passes again without the earlier `400 Bad Request` console-noise regression.
- Latest verified commands for this closure:
-`go test ./... -count=1`
-`go vet ./...`
-`go build ./cmd/server`
-`cd D:\project\frontend\admin && npm.cmd run test:run`
-`cd D:\project\frontend\admin && npm.cmd run lint`
-`cd D:\project\frontend\admin && npm.cmd run build`
- this closes the earlier session-model / OAuth return-path / random-fail-open implementation gaps.
- it does not close the separate remaining boundaries around coverage depth, dev-toolchain SCA cleanup, or external production alert delivery evidence.
## 2026-03-27 First Admin Bootstrap Closure Update
- The previously real usability gap around “no default account, no first-admin product path” is now closed at product implementation level.
- Backend closure:
- added public `POST /api/v1/auth/bootstrap-admin`.
- bootstrap is guarded by `GET /api/v1/auth/capabilities -> admin_bootstrap_required`, so it is only available while the system still has no active admin.
- successful bootstrap creates the first active admin, binds the `admin` role, returns a real session, and closes the bootstrap window afterward.
- Frontend closure:
- added public `/bootstrap-admin` page.
-`/login` and `/register` now expose a real first-run admin initialization entry instead of only showing a passive warning.
- successful bootstrap now logs the operator into `/dashboard` directly.
- Supported-browser validation closure:
-`frontend/admin/scripts/run-playwright-auth-e2e.ps1` no longer depends on startup-injected admin credentials.
- the real browser E2E suite now begins with `admin-bootstrap`, proving `无默认账号 -> 初始化首个管理员 -> 进入后台 -> 登出`.
- Latest verified commands for this closure:
-`go test ./... -count=1`
-`go build ./cmd/server`
-`cd D:\project\frontend\admin && npm.cmd run lint`
-`cd D:\project\frontend\admin && npm.cmd run test:run`
-`cd D:\project\frontend\admin && npm.cmd run build`
- PRD `1.1 多种注册方式` is now closed at product implementation level for the self-service frontend loop.
- Backend closure:
- the existing `POST /api/v1/auth/register` product API is now matched by a real public frontend path.
-`POST /api/v1/auth/send-code` now accepts both `purpose` and legacy `scene` payloads, preventing older clients from silently breaking while the frontend uses the normalized `purpose` contract.
- Frontend closure:
-`/register` is now a real public route linked from `/login`.
- users can complete username/password self-registration, optionally provide nickname/email, and use capability-gated phone registration when SMS is enabled.
-`/dashboard` is now admin-guarded, so newly registered non-admin users no longer land on an admin-only stats error path after first login; they settle on `/profile`.
-`/register` is treated as a public auth path during session-restore cleanup.
- Latest verified commands for this closure:
-`go test ./... -count=1`
-`go build ./cmd/server`
-`cd D:\project\frontend\admin && npm.cmd run lint`
-`cd D:\project\frontend\admin && npm.cmd run test:run`
-`cd D:\project\frontend\admin && npm.cmd run build`
当前可以诚实表述为:项目已完成当前受限 Windows 环境下的浏览器级真实 E2E 收口,并具备本地可审计的一轮治理证据闭环;尚未完成的是完整 OS 级自动化、真实第三方 OAuth live 验证,以及部分生产外部交付层证据,不应夸大为“全部企业级上线材料均已闭环”。
## 2026-03-26 Social Account Binding Closure Update
- PRD social account management (`1.5`, `2.2`, `2.3`) is now closed at implementation level.
- Backend closure:
-`POST /api/v1/users/me/bind-social` now starts an authenticated OAuth binding flow instead of relying on raw `open_id` input from the product UI path.
-`GET /api/v1/auth/oauth/:provider/callback` now supports both login callback and bind callback through persisted OAuth state purpose.
-`GET /api/v1/users/me/social-accounts` now returns sanitized bound-account info.
-`DELETE /api/v1/users/me/bind-social/:provider` now enforces password/TOTP verification when available and blocks unbinding if no login method would remain.
- Frontend closure:
-`/profile/security` now exposes a real social-account management section with bind entry, bound account table, callback-result handling, and guarded unbind modal.
- Validation passed:
-`go test ./... -count=1`
-`go build ./cmd/server`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run test:run -- src/services/auth.test.ts src/services/social-accounts.test.ts src/pages/admin/ProfileSecurityPage/ProfileSecurityPage.social.test.tsx`
-`Q-004` remediation progressed again, but still cannot be honestly declared closed.
- Admin shell closure:
-`frontend/admin/src/layouts/AdminLayout/AdminLayout.tsx` is now covered at `100 / 100 / 100 / 100`.
-`frontend/admin/src/layouts/AdminLayout/AdminLayout.test.tsx` now covers loading, desktop and mobile navigation, dropdown actions, collapse state, avatar and username fallback logic, and explicit child rendering.
- Validation passed:
-`cd frontend/admin && npm.cmd run test:run -- src/layouts/AdminLayout/AdminLayout.test.tsx`
-`cd frontend/admin && npm.cmd run lint`
-`cd frontend/admin && npm.cmd run build`
-`cd frontend/admin && npm.cmd run test:coverage`
- Frontend current full coverage:
- statements `92.06%`
- branches `79.29%`
- functions `89.09%`
- lines `92.22%`
- Real remaining `Q-004` frontend gaps after this closure: