Story CP-S0: Dev environment + test infra for customer-portal¶
Module: customer-portal Slice: CP-S0 (architecture §11 Vertical Slice Decomposition) Side: [BACKEND] Version target: [V0.0.0] Priority: 0 Depends on: TENANT-S0 merged (Postgres + Keycloak + MinIO + Redis docker-compose) Can develop concurrently with: None (Tier 0 — must merge first) Merge order: Before CP-001 Estimated complexity: S PRD User Stories: N/A - Technical Story Wireframe: N/A — backend only
Objective¶
Stand up the build + test scaffolding for the customer-portal Spring Modulith module and the frontend-customer React app so every later CP story has green CI to build on. No business behavior. Reuses TENANT-S0's docker-compose.yml (Postgres, Keycloak, MinIO, Redis) — no new container. Adds WireMock (test-only) to stub the PAY sandbox, and TestContainers wiring for CP integration tests against a tenant DB.
Backend Scope¶
Entities¶
None.
Migrations¶
None. (The CP baseline migration V0_0_0_001__cp_baseline.sql is introduced by CP-001.)
Service Layer¶
None. This story only wires build + test infrastructure:
- Create the empty Spring Modulith module customer-portal (package root com.altarys.papillon.pcs.customer) with a module descriptor and a placeholder CustomerPortalConfiguration.
- Add a @SpringBootTest smoke test that boots the empty module context.
- Add WireMock as a test dependency and a test profile that points PAY_CLIENT_BASE_URL at the WireMock server.
- Add TestContainers (PostgreSQL 16) wiring shared with the tenant-DB datasource switch (reuse TENANT's test harness).
API Endpoints¶
None.
Validation Rules¶
None.
Multi-Tenant Considerations¶
Test harness must exercise the tenantDataSource routing so later CP integration tests can run asTenant("A") / asTenant("B") (see arch §13.2). No tenant business logic in this story.
Audit & Logging¶
None.
Frontend Scope¶
Pages & Routes¶
None (no UI behavior). Only frontend-customer/vitest.config.ts + a trivial passing test to make pnpm test green.
Components¶
None.
UI States (ALL REQUIRED)¶
N/A — backend/infra only.
Responsive Behavior¶
N/A.
Connectivity Behavior (CUSTOMER stories only)¶
N/A.
Interactions¶
N/A.
Acceptance Criteria¶
AC-S0.1: Backend module builds and boots
Given the empty customer-portal module
When I run ./gradlew :customer-portal:test
Then the build is green and the Spring context boots with no business beans
AC-S0.2: PAY sandbox is stubbable in tests
Given the test profile
When an integration test starts
Then a WireMock server is available and PAY_CLIENT_BASE_URL resolves to it
AC-S0.3: Frontend test runner is green
Given frontend-customer
When I run pnpm test
Then Vitest runs and the placeholder test passes
Compliance Rules¶
None directly. (All later CP stories carry the module-wide [LEGAL-REVIEW] — see index "Bloquant".)
Standards & Conventions¶
docs/standards/java-spring-guidelines.md— module layout, package…pcs.customer, Spring Data JDBC (not JPA).docs/standards/tech-stack.md— versions (React 19.2, Spring Boot 4, PostgreSQL 16).docs/standards/git-workflow.md— branch + worktree conventions.
Testing Requirements¶
Unit Tests¶
- Context-loads smoke test (backend) + placeholder Vitest test (frontend).
Integration Tests¶
- TestContainers PostgreSQL boots and the tenant-DB switch resolves in a test (smoke only).
- WireMock server starts under the test profile.
What QA Will Validate¶
./gradlew :customer-portal:testandcd frontend-customer && pnpm testboth green on a module with no business logic.
Out of Scope¶
- Any CP endpoint, table, or screen (CP-001+).
- New docker containers (reuse TENANT-S0 stack).
- Keycloak realm config (AUTH owns; CP customer side is cookie-based, not Keycloak).
Definition of Done¶
- [ ]
customer-portalmodule created (packagecom.altarys.papillon.pcs.customer) - [ ]
./gradlew :customer-portal:testgreen - [ ] WireMock wired under the test profile;
PAY_CLIENT_BASE_URLresolves to it - [ ] TestContainers PostgreSQL + tenant-DB switch smoke test green
- [ ]
frontend-customerVitest runner green - [ ] CI green on the empty CP module