From c30e2b1348975f342958a6f6793d4b22b0341f88 Mon Sep 17 00:00:00 2001 From: shunli Date: Thu, 28 May 2026 16:23:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20OALAUNCH1=20=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E4=B8=8E=E4=B8=9A=E5=8A=A1=E6=B5=81=E5=9B=9E=E5=BD=92?= =?UTF-8?q?=EF=BC=8805-28-oalaunch1-parallel-closeout=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spec/hyb-oa/frontend-react-vite-design.md | 69 +++++++++++++++++++ client/src/pages/ForgotPasswordPage.tsx | 2 +- client/src/pages/LoginPage.tsx | 2 +- client/src/pages/PaymentBatchesPage.tsx | 13 +++- .../e2e/mobile-approvals-offline.spec.ts | 68 ++++++++++++++---- .../e2e/permission-direct-access.spec.ts | 18 +---- .../e2e/r102-reimbursement-main-flow.spec.ts | 2 +- .../e2e/r89-mobile-login-navigation.spec.ts | 9 +++ .../reimbursement-payment-batch-flow.spec.ts | 32 ++++----- 9 files changed, 162 insertions(+), 53 deletions(-) diff --git a/.trellis/spec/hyb-oa/frontend-react-vite-design.md b/.trellis/spec/hyb-oa/frontend-react-vite-design.md index b865395d..9c5baa82 100644 --- a/.trellis/spec/hyb-oa/frontend-react-vite-design.md +++ b/.trellis/spec/hyb-oa/frontend-react-vite-design.md @@ -32,6 +32,75 @@ or hidden according to the active Issue; do not silently re-enable them. - Trial-facing PC lists must hide obvious TEST/SMOKE records by default when a page-level toggle exists; the toggle may reveal them for troubleshooting. +## Scenario: Business Flow Tests And Frozen Modules + +### 1. Scope / Trigger + +- Trigger: Playwright or QA shell tests need to create workflow data while some + product modules are frozen for launch. +- Applies to `client/tests/e2e/**`, `scripts/qa/run-business-flow-gates.sh`, + and frontend route/permission assertions. + +### 2. Signatures + +- QA command: `BUSINESS_FLOW_GROUPS= bash scripts/qa/run-business-flow-gates.sh local`. +- Frozen-module API expectation: non-admin launch roles may receive `403` for + frozen module list/create/submit endpoints. +- Enabled workflow test data sources should use active entities such as leave, + reimbursement or procurement unless the task explicitly reopens the frozen + module. + +### 3. Contracts + +- Do not use a frozen module as fixture setup for an unrelated enabled feature. + Example: mobile approval offline sync should not create a travel request when + travel permissions are intentionally frozen. +- Permission direct-access tests must assert the frozen contract directly, such + as employee `GET /api/travel-requests?...` returning `403`. +- UI route smoke may still verify that a frozen page displays a boundary state + without entering a management or write-capable mode. +- Do not loosen roles or seed permissions merely to make old E2E data setup + pass. + +### 4. Validation & Error Matrix + +- Frozen role calls frozen module create/submit/list endpoint -> `403` or the + documented feature-gate status. +- Enabled workflow feature needs pending task data -> create data through an + enabled workflow entity. +- E2E fails with `PERM_001` while setting up unrelated feature data -> update + the test data source before changing app permissions. + +### 5. Good/Base/Bad Cases + +- Good: mobile approval offline test creates a submitted leave request, then + verifies pending-task deep link, offline queue, sync success and conflict. +- Base: travel-specific tests are skipped or admin-scoped while travel remains + frozen. +- Bad: grant employee `travel.create` only so a mobile approval test can build + a fixture. + +### 6. Tests Required + +- Focused E2E group that previously failed. +- Full affected business-flow group after the focused fix. +- `cd client && npm run typecheck && npm run build` when TypeScript test code + changes. + +### 7. Wrong vs Correct + +#### Wrong + +```ts +await createSubmittedTravelRequestViaApi({ user: EMPLOYEE }); +``` + +#### Correct + +```ts +await createSubmittedLeaveViaApi({ user: EMPLOYEE }); +``` + ## Convention: PC Operation List Density **What**: PC list/workflow pages that combine status metrics, tabs/filters, diff --git a/client/src/pages/ForgotPasswordPage.tsx b/client/src/pages/ForgotPasswordPage.tsx index 674800f8..cb25f6c0 100644 --- a/client/src/pages/ForgotPasswordPage.tsx +++ b/client/src/pages/ForgotPasswordPage.tsx @@ -33,7 +33,7 @@ export function ForgotPasswordPage() { queryFn: () => fetchAuthCapabilities(), staleTime: 60_000, }); - const emailDeliveryReady = authCapabilitiesQuery.data?.emailDelivery.ready === true; + const emailDeliveryReady = authCapabilitiesQuery.data?.emailDelivery?.ready === true; const emailDeliveryChecking = authCapabilitiesQuery.isLoading; const emailDeliveryUnavailable = authCapabilitiesQuery.isSuccess && !emailDeliveryReady; const emailDeliveryUnknown = authCapabilitiesQuery.isError; diff --git a/client/src/pages/LoginPage.tsx b/client/src/pages/LoginPage.tsx index 9d6ae392..3aabee5e 100644 --- a/client/src/pages/LoginPage.tsx +++ b/client/src/pages/LoginPage.tsx @@ -76,7 +76,7 @@ export function LoginPage() { queryFn: () => fetchAuthCapabilities(), staleTime: 60_000, }); - const emailDeliveryReady = authCapabilitiesQuery.data?.emailDelivery.ready === true; + const emailDeliveryReady = authCapabilitiesQuery.data?.emailDelivery?.ready === true; const emailDeliveryChecking = authCapabilitiesQuery.isLoading; const emailDeliveryUnavailable = authCapabilitiesQuery.isSuccess && !emailDeliveryReady; const emailDeliveryUnknown = authCapabilitiesQuery.isError; diff --git a/client/src/pages/PaymentBatchesPage.tsx b/client/src/pages/PaymentBatchesPage.tsx index bfca9408..939ac51a 100644 --- a/client/src/pages/PaymentBatchesPage.tsx +++ b/client/src/pages/PaymentBatchesPage.tsx @@ -368,7 +368,7 @@ export function PaymentBatchesPage() {
-
+

新建批次

{!canManageBatch ? (
@@ -379,6 +379,7 @@ export function PaymentBatchesPage() { setName(event.target.value)} @@ -400,6 +402,7 @@ export function PaymentBatchesPage() {