feat: permissions CRUD browser integration + E2E enhancements
Backend: - permission_handler: 完善权限 CRUD 接口(列表/创建/更新/删除) - auth_handler: 修复认证处理逻辑 - router: 新增权限管理路由 - handler_test: 新增权限 handler 测试覆盖 Frontend: - permissions.ts/test.ts: 权限服务层完整实现 - profile/settings/service_tests: 服务适配器修正 - client.ts: HTTP 客户端健壮性增强 - vite.config.js: 构建配置优化 - E2E 脚本: run-playwright-cdp-e2e 大幅增强(权限流程覆盖) Docs: - REAL_PROJECT_STATUS: 状态更新 - PRODUCTION_CHECKLIST/QUALITY_STANDARD/TECHNICAL_GUIDE/PROJECT_EXPERIENCE_SUMMARY: 团队规范完善 - plans/2026-04-23: 权限浏览器 CRUD 设计方案 验证: go build 0错误
This commit is contained in:
@@ -153,3 +153,101 @@ npm.cmd run e2e:full:win
|
||||
- `docs/status/REAL_PROJECT_STATUS.md`
|
||||
- 规则变化时更新 `docs/team/QUALITY_STANDARD.md`
|
||||
- 产出可复用经验时更新 `docs/team/PROJECT_EXPERIENCE_SUMMARY.md`
|
||||
|
||||
## 0. 2026-04-23 Latest Technical Snapshot
|
||||
|
||||
Use this section as the current workspace truth when older notes elsewhere in this file describe earlier failures.
|
||||
|
||||
### Main Acceptance Path
|
||||
|
||||
- The supported browser-level gate remains `cd frontend/admin && npm.cmd run e2e:full:win`.
|
||||
- That gate was re-run green on 2026-04-23 after fixes in device pagination flow, backend-response envelope decoding, settings-service adapter alignment, and Playwright CDP selector and suite-retry stability.
|
||||
|
||||
### Recovery Notes That Matter
|
||||
|
||||
- `DevicesPage` must keep the request cursor separate from the response `next_cursor`; otherwise the initial load can auto-chain into extra `/admin/devices` requests and trigger rate limiting.
|
||||
- Frontend services must decode backend envelopes by their actual fields and by the shared HTTP client contract. The recovered cases in this round were `list`, `deliveries`, `accounts`, and `/admin/settings` direct `data`.
|
||||
- Late-stage E2E scenarios are more stable when assertions target route, heading, and role-based locators instead of broad page text matches.
|
||||
- If suite retry reuses the same backend process, one-time preconditions such as `admin-bootstrap` must be refreshed from live backend capabilities before the next attempt starts.
|
||||
|
||||
### Boundary
|
||||
|
||||
- This snapshot proves browser-level real E2E closure in the current workspace.
|
||||
- It does not by itself prove the full backend matrix, OS-level automation, or live third-party provider verification.
|
||||
|
||||
## 2026-04-23 Late-Suite E2E Triage Order
|
||||
|
||||
Use this order before blaming the browser wrapper when `cd frontend/admin && npm.cmd run e2e:full:win` fails in later admin scenarios.
|
||||
|
||||
1. Check whether the failing page consumes an API whose response envelope or field names changed.
|
||||
2. Check whether the page state machine, pagination flow, or derived state issued unexpected follow-up requests.
|
||||
3. Check whether the failing assertion uses a broad text locator where route, heading, role, or labeled-control matching would be more precise.
|
||||
4. Only after the first three checks stay clean, investigate CDP session lifecycle, page/context closure, or local browser startup instability.
|
||||
|
||||
## 2026-04-23 Password Reset And CDP Recovery Notes
|
||||
|
||||
### Root Cause
|
||||
|
||||
- The password-reset browser gap came from a backend contract omission: `/api/v1/auth/capabilities` returned `password_reset=false` even when `passwordResetHandler` was mounted and the reset routes were live.
|
||||
|
||||
### Minimal Fix
|
||||
|
||||
- `AuthHandler` now carries the password-reset capability bit and fills `caps.PasswordReset` in `GetAuthCapabilities()`.
|
||||
- Router assembly now synchronizes that bit from the same `passwordResetHandler != nil` condition that mounts the reset routes.
|
||||
|
||||
### Browser Flow Proof
|
||||
|
||||
- The supported browser suite now proves the real password-reset chain end to end:
|
||||
- admin creates a real user
|
||||
- login surface exposes the forgot-password entry
|
||||
- `/api/v1/auth/forgot-password` emits a real SMTP-captured reset link
|
||||
- `/api/v1/auth/password/validate` and `/api/v1/auth/reset-password` complete through the browser
|
||||
- the user logs in with the new password
|
||||
|
||||
### Stability Rule
|
||||
|
||||
- When headless-shell closes the last live target late in the suite, reconnect the CDP browser connection and reacquire the persistent page before declaring the whole run failed.
|
||||
|
||||
## 2026-04-23 Permissions CRUD And Full Matrix Technical Snapshot
|
||||
|
||||
Use this section as the newest technical snapshot when earlier 2026-04-23 notes describe only the 19-scenario gate.
|
||||
|
||||
### Main Acceptance Path
|
||||
|
||||
- The supported browser-level gate remains `cd frontend/admin && npm.cmd run e2e:full:win`.
|
||||
- That gate was re-run green on 2026-04-23 after adding `permissions-management-crud`, fixing permissions payload compatibility, fixing auth-header selection under concurrent refresh state, and stabilizing CDP observation for proxied permission calls.
|
||||
- The same branch state also re-ran `go test ./... -count=1`, `go vet ./...`, `go build ./cmd/server`, `cd frontend/admin && npm.cmd run test:run`, `cd frontend/admin && npm.cmd run lint`, and `cd frontend/admin && npm.cmd run build` successfully.
|
||||
|
||||
### Recovery Notes That Matter
|
||||
|
||||
- The permissions frontend adapter must accept raw numeric backend `type` values, normalize them to the frontend string enum, and serialize writes back to the backend numeric form.
|
||||
- The permissions backend handler must continue accepting menu `type=0` and status payloads delivered as either numeric or string values, because real browser flows and clients can send both forms during incremental rollout.
|
||||
- A valid non-expired access token must still be attached to requests even when a different refresh flow is already in flight. Refresh state alone is not evidence that the current request should lose authentication.
|
||||
- In the permissions CRUD scenario, the page and backend were healthy even when Playwright CDP request and response observers missed the proxied `/api/v1/permissions` call. The reliable proof path was the in-page fetch diagnostic log plus the post-submit UI refresh.
|
||||
- Ant modal leave animations can keep intercepting clicks after the dialog is visually closing. Scenario code should wait for the modal to stop blocking interaction before the next action.
|
||||
- Vite 8 on Windows with `--configLoader native` can fail the supported build path if project root resolution is implicit. The stable fix is an explicit `root` in `vite.config.js`.
|
||||
|
||||
### Boundary
|
||||
|
||||
- This snapshot proves browser-level real E2E closure with `20` supported scenarios in the current workspace.
|
||||
- It does not by itself prove OS-level automation, live third-party provider verification, or remote-repository publication status.
|
||||
|
||||
## 2026-04-24 Profile Security Contract Recovery
|
||||
|
||||
### Root Cause
|
||||
|
||||
- The profile password form used the UI model (`current_password`, `confirm_password`) all the way through the service layer, but the real backend `PUT /users/:id/password` handler binds `old_password` and `new_password` only.
|
||||
|
||||
### Minimal Fix
|
||||
|
||||
- `frontend/admin/src/services/profile.ts` now maps the UI request to the real backend payload shape before calling the shared HTTP client.
|
||||
- `frontend/admin/scripts/run-playwright-cdp-e2e.mjs` now couples password and TOTP fetch waits to the submit action that triggers them, so a later locator failure does not leave an orphaned background waiter that hides the real error.
|
||||
|
||||
### Browser Flow Proof
|
||||
|
||||
- The targeted profile page and service regression set is green.
|
||||
- The supported browser-level gate `cd frontend/admin && npm.cmd run e2e:full:win` is green with `20` scenarios, including `profile-and-security`.
|
||||
|
||||
### Stability Rule
|
||||
|
||||
- When a scenario uses asynchronous fetch diagnostics for proof, create the waiter in the same control flow as the triggering action and tear it down implicitly with that action path. A background waiter that survives a failed action is a runner bug because it can replace the primary failure with misleading page-closed noise.
|
||||
|
||||
Reference in New Issue
Block a user