Story AUDIT-000: Dev environment + test infrastructure for the AUDIT module¶
Module: audit-log Slice: AUDIT-S0 (Architecture §11, Tier 0) — file renamed AUDIT-000 for zero-padded sequencing; other modules reference this slice as "AUDIT-S0" Side: [BACKEND] Version target: V0.0.0 Priority: 1 (blocks every other AUDIT story) Depends on: TENANT-S0 (platform DB exists) Can develop concurrently with: None (foundation) Merge order: Before any AUDIT-001x Estimated complexity: M PRD User Stories: N/A — Technical Story (V0 envelope enablement) Wireframe: N/A — backend only
Objective¶
Wire the new audit-log backend module into the existing local + CI development environment so that later AUDIT stories have a place to build. This story introduces the new external dependencies AUDIT needs — the audit-exports MinIO bucket and the new PostgreSQL roles — and the Testcontainers fixtures every AUDIT integration test will extend. No business logic and no database schema land in this story; the next story (AUDIT-001a) creates the schema.
Backend Scope¶
Entities¶
None. This story creates no tables. (The audit_log, audit_tenant_salt and audit_export tables are introduced by AUDIT-001a.)
Migrations¶
None in this slice. The Flyway migration folder backend/src/main/resources/db/migration/platform/ is created but empty. The first migrations (V001..V005) land in AUDIT-001a.
Service Layer¶
backend/build.gradle.kts— add AUDIT'saws-sdk-s3dependency (MinIO-compatible client);spring-modulith-events-jdbcandspring-jdbcare already on the singlebackendmodule. AUDIT is a Spring Modulith package within the onebackendSpring Boot application, NOT a separate Gradle module (java-spring-guidelines.md§6). No application beans yet.- Module wiring so the modulith recognises
audit-logas a control-plane module (package rootcom.altarys.papillon.pcs.controlplane.audit).
API Endpoints¶
None.
Validation Rules¶
None (no runtime surface yet).
Multi-Tenant Considerations¶
AUDIT data lives on the platform DB for every tenant regardless of db_profile (AUDIT-ADR-01). This story only confirms the platform DB and MinIO are reachable from the new module; tenant scoping is exercised by later stories. Both V1 DB profiles (SHARED, BYO) route their audit rows to the platform DB — AUDIT never installs schema on a tenant's own DB.
Audit & Logging¶
None emitted in this story. The AUDIT_SCHEMA_MIGRATED event arrives with the first migration in AUDIT-001a.
Infrastructure / Dev-env tasks (the real work of this story)¶
docker-compose.yml— ensure the MinIO service auto-creates theaudit-exportsbucket on boot (init container or boot script). Bucket lifecycle and object-lock are configured later; for now the bucket must simply exist.- New PostgreSQL roles are declared here as part of the dev-env bootstrap so later stories can grant against them. The actual
GRANTstatements that lock downaudit_logship with AUDIT-001a'sV004__audit_roles.sql. backend/src/test/resources/application-test.yml— Testcontainers config (Postgres + MinIO endpoints, testAUDIT_KEK); AUDIT adds its keys to the shared test config, it does not own the file.backend/src/test/java/com/altarys/papillon/pcs/controlplane/audit/AuditTestContainersBase.java— shared PostgreSQL (postgres:16-alpine) + MinIO container fixture (see Architecture §13.1). All AUDIT integration tests extend this base.backend/src/test/java/com/altarys/papillon/pcs/controlplane/audit/AuditModuleBoundariesTest.java— a Spring ModulithApplicationModules.verify()test that fails if any module reaches into AUDIT internals.
Environment variables (declared here, consumed by later stories)¶
| Var | Default | Notes |
|---|---|---|
AUDIT_KEK |
required | 64-char hex (32 bytes), openssl rand -hex 32. Never committed. |
AUDIT_MINIO_BUCKET |
audit-exports |
bucket auto-created at boot if missing |
AUDIT_EXPORT_PRESIGN_TTL_SECONDS |
900 | 15-min presigned URL (used in AUDIT-003) |
AUDIT_OUTBOX_POLL_INTERVAL_MS |
30000 | spring-modulith republisher interval (used in AUDIT-001b) |
AUDIT_DEGRADED_THRESHOLD |
100 | incomplete-count threshold for FR-10 (used in AUDIT-003) |
AUDIT_SALT_CACHE_TTL_SECONDS |
300 | 5-min in-memory salt cache (used in AUDIT-001c) |
Frontend Scope¶
N/A — AUDIT has no UI in V0 or V1 (PRD §C.5). No pages, components, or UI states.
Acceptance Criteria¶
These are technical-enablement criteria (no PRD user-story ACs apply to dev-env setup).
AC-000.1: Module builds and checks pass
Given the audit-log Spring Modulith package in the single backend application
When a developer runs ./gradlew :backend:check
Then the build is green and ApplicationModules.verify() passes
AC-000.2: MinIO bucket exists on boot
Given a fresh docker compose up
When the stack finishes starting
Then a MinIO instance is running with the audit-exports bucket pre-created
AC-000.3: No schema yet
Given the dev environment from this story only
When a developer inspects the platform DB
Then the audit_log table does NOT yet exist (it is introduced by AUDIT-001a)
Compliance Rules¶
None directly. This story only prepares infrastructure. The compliance obligations (CIMA Reg. 01-24 §16.5 proof base, CI fiscal 10-year retention, law n°2013-450 minimisation) are honoured by the stories that add schema, hashing and retention behaviour.
Standards & Conventions¶
docs/standards/tech-stack.md— locked stack (Spring Boot, PostgreSQL, MinIO, spring-modulith).docs/standards/multi-datasource-patterns.md— platform DB vs tenant DB; AUDIT contributes toplatform/only.docs/standards/java-spring-guidelines.md— module + package conventions, Spring Modulith boundaries.docs/standards/database-guidelines.md— Flyway folder layout.docs/standards/git-workflow.md— branch + commit conventions.
Testing Requirements¶
Unit Tests¶
None meaningful (no logic). A trivial context-loads test is acceptable.
Integration Tests¶
AuditModuleBoundariesTest—ApplicationModules.verify()green.- A smoke test confirming the MinIO container starts and the
audit-exportsbucket is reachable from the test fixture.
What QA Will Validate¶
./gradlew :backend:checkis green.docker compose upyields a running MinIO with theaudit-exportsbucket.- The platform DB has no
audit_logtable yet.
Out of Scope¶
- Any database schema (AUDIT-001a).
- Any outbox listener, PiiHasher, or producer stubs (AUDIT-001b / 001c).
- Any export endpoint or metrics (AUDIT-003).
- Object-lock / WORM on the MinIO bucket (V2).
Definition of Done¶
- [ ] the backend application builds and
./gradlew :backend:checkis green (AUDIT is a package, not a separate Gradle module) - [ ]
ApplicationModules.verify()passes - [ ]
docker compose upauto-creates theaudit-exportsMinIO bucket - [ ]
AuditTestContainersBase(Postgres + MinIO) usable by later AUDIT tests - [ ] All declared
AUDIT_*env vars documented (Architecture §14.2 env table + §14.3 smoke command) - [ ] No
audit_logtable created in this story - [ ] Tenant isolation N/A in this story (no data path yet) — noted for AUDIT-001x
- [ ] No silent failures: missing
AUDIT_KEKor unreachable MinIO fails fast at boot