- 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: