Aller au contenu

Story CP-004: Lazy-load payment/receipt bundle + CI bundle-budget gate

Module: customer-portal Slice: CP-004 (architecture §11) Side: [CUSTOMER] + [BACKEND] Version target: [V0.0.3] Priority: 6 Depends on: CP-003 merged Can develop concurrently with: CP-005 Merge order: After CP-003 Estimated complexity: S PRD User Stories: N/A - Technical Story (serves CP-NFR-01) Design reference: N/A — no new screen (bundle/route-split optimisation). Budget basis: docs/design/customer-portal-design.md §7 (connectivity / payload budget) Wireframe: N/A — bundle/route-split optimisation (no new screen)

[LEGAL-REVIEW] — Inherits the module-wide magic-link INCERTAIN gate. No new legal surface in this slice.


Objective

Tighten route-split so the landing critical path stays small and the payment/receipt code loads only when needed, and add a CI bundle-budget gate that fails the build above 180 KB gzipped on the landing path. This is the v0.0.3 optimisation slice — no new business behavior.


Backend Scope

Entities

None.

Migrations

None.

Service Layer

None (frontend + CI optimisation). Cache headers per arch §3.4 already in place: static bundle public, max-age=31536000, immutable (hashed filenames).

API Endpoints

None.

Validation Rules

None.

Multi-Tenant Considerations

None (no data path change).

Audit & Logging

None.


Frontend Scope

Pages & Routes

  • No new route. Confirm route-split chunks: landing (WelcomePage + ContractList), Summary+Consent, Payment status (CP-08/09), Receipt (CP-07/13) are each lazy and load only on their trigger.

Components

  • No new components; convert/verify lazy imports (React.lazy + Suspense) for the payment + receipt chunks so they load only after the redirect-return.

UI States (ALL REQUIRED)

State Behavior French Copy
Loading Suspense fallback skeleton while a lazy chunk loads
Empty N/A
Error Chunk-load failure → retry/reload affordance « Le chargement a échoué. Réessayer. »
Offline / low network Existing offline banner applies « Connexion instable. Vos choix sont enregistrés. »
Success Chunk loads on demand; landing path stays light

Responsive Behavior

Unchanged from CP-001/002/003 (mobile-first 360 px). No layout change.

Connectivity Behavior (CUSTOMER stories only)

  • Landing critical path ≤ 200 KB gzipped, with the CI gate enforcing ≤ 180 KB on the landing path specifically.
  • Receipt + payment chunks only fetched after the redirect-return — not on the landing path.
  • Slow-3G TTI budget on landing ≤ 6 s, FCP ≤ 3 s (arch §8.4) preserved.

Interactions

  • No new interactions; lazy-chunk loading is transparent with a Suspense skeleton.

Acceptance Criteria

AC-004.1: Landing path under the budget
Given a production build
When the CI bundle-budget script measures the landing critical path
Then it is ≤ 180 KB gzipped and the build fails if it exceeds that threshold (CP_BUNDLE_BUDGET_BYTES_GZIPPED)
AC-004.2: Payment/receipt code loads only after redirect-return
Given the customer lands on the contract list
When the landing path loads
Then the payment status and receipt chunks are NOT in the landing bundle; they are fetched only after the PSP redirect-return (or on "Payer" intent for the summary chunk)

Compliance Rules

  • Inherits module-wide magic-link INCERTAIN ([LEGAL-REVIEW]). No new compliance surface.

Standards & Conventions

  • docs/standards/connectivity-low-bandwidth.md — payload budget, route-split, Slow-3G.
  • docs/standards/react-typescript-guidelines.md — React.lazy + Suspense, code-splitting.
  • docs/standards/tech-stack.md — Vite, vite-bundle-visualizer.
  • docs/standards/git-workflow.md — CI gate wiring.
  • docs/design/customer-portal-design.md — §7 connectivity behaviour (Slow-3G budgets the gate enforces).

Testing Requirements

Unit Tests

  • N/A (build-time gate); a Suspense-fallback render test for the lazy boundaries.

Integration Tests

  • CI build asserts landing path ≤ 180 KB gzipped (size-budget script).
  • E2E: payment/receipt chunk network request only fires after redirect-return.

What QA Will Validate

  • Slow-3G smoke: landing TTI ≤ 6 s; lazy chunks load on demand without breaking the flow; chunk-load error shows a retry.

Out of Scope

  • Any new screen or endpoint.
  • Link TTL / attempt counter / rate limiting (CP-005).
  • SSR/streaming changes beyond existing setup.

Definition of Done

  • [ ] Route-split verified: landing, summary+consent, payment status, receipt are separate lazy chunks
  • [ ] CI bundle-budget gate fails the build above 180 KB gzipped on the landing path
  • [ ] Payment/receipt chunks load only after redirect-return (verified in E2E)
  • [ ] Suspense fallback + chunk-load error handled (no silent failure)
  • [ ] AC-004.1, AC-004.2 pass
  • [ ] Slow-3G smoke: landing TTI ≤ 6 s
  • [ ] French micro-copy for chunk-load error matches spec