# AGENTS.md

## Scope
- Applies to the whole backend repo (`cbm-portal-backend`).
- Existing agent-instruction files discovered via glob: `deployment/README.md` only.

## System shape (read this first)
- Stack: Spring Boot 3.4, Java 17, JPA + Flyway, JWT resource server, PostgreSQL/H2 (`pom.xml`).
- Main layers are `controllers -> services -> repositories -> domains` under `src/main/java/com/cbmportal/portal`.
- Form submissions are split by business area controllers (for example `FinanceSubmissionController`) and mapped from DTOs via `FormDtoMapper` before service processing.
- Admin form aggregation/pagination is centralized in `FormAdminController` + `services/admin/FormAdminService`; form-name normalization is handled by `services/util/FormTypeResolver`.
- Auth/session model is access JWT + persisted refresh tokens (`RefreshToken` entity, `TokenServiceImpl`, `SessionManagementServiceImpl`).

## Security and auth conventions
- Public routes are limited to `/api/v1/auth/**` and `/api/v1/health/**`; admin routes require authorities (`SecurityConfiguration`).
- JWT authorities come from claim `userRole` with no `ROLE_` prefix; use `@PreAuthorize("hasAnyAuthority('Admin','Office','DM')")` style checks.
- `AuthController` expects login payload in `LoginRequestVO`; device/IP are taken from request headers/remote address.
- Username handling is normalized to lowercase in auth service (`AuthenticationServiceImpl`); preserve this in new auth code.
- RSA JWT keys are loaded/generated from filesystem `keys/` (`utility/RSAKeyProperties`), not ephemeral-only memory.

## Error/logging patterns
- Use global error contract (`domains/VO/ErrorResponse`) via `GlobalExceptionHandler`.
- Correlation IDs are required: `RequestCorrelationFilter` accepts/sets `X-Correlation-Id`, stores in MDC, and responses echo it.
- Logging pattern includes correlation ID (`application.yml` / profile yml): `%5p [cid:%X{correlationId}]`.

## Data and migration rules
- Add schema changes only via Flyway migrations in `src/main/resources/db/migration` (sequential `V__` files).
- Runtime profile behavior: `dev` uses PostgreSQL + Flyway; `test` uses H2 with Flyway disabled (`application-test.yml`).
- Prefer repository style already present: mixed `CrudRepository` and `JpaRepository` depending on entity usage (do not mass-refactor).

## External integrations
- Email delivery uses Microsoft Graph (`MicrosoftGraphEmailService`); in `test` profile the actual send is skipped.
- Planned storage confidentiality for emailed/downloaded form files uses Azure Key Vault-backed KEK management; see `deployment/KEY_VAULT_SETUP.md` and `deployment/KEY_VAULT_RUNBOOK.md`.
- Stage deployment expects environment-provided secrets (`application-stage.yml`) and systemd unit (`deployment/cbm-portal.service`).
- Health endpoints used by ops scripts are `/api/v1/health` and `/api/v1/health/detailed`.

## Dev workflows that match this repo
- Local build/test baseline (from Maven wrapper): run `./mvnw clean test`.
- Focused auth/session suite exists as Maven profile `auth-tests` in `pom.xml`.
- Web-layer tests use `@WebMvcTest` + mocked startup runner bean `@MockBean(name = "run")` (see `AuthControllerTest`).
- Controller security tests use `@WithMockUser` authorities matching JWT claim values (see `FormAdminControllerTest`).
- Deployment script (`deployment/deploy.sh`) builds with `-DskipTests`, deploys jar, then validates health and auto-rolls back on failure.

## Change hygiene for agents
- Keep endpoint naming/versioning style (`/api/v1/...`) and existing response VO patterns.
- When adding a new form type, update all three: `FormTypeResolver`, `FormAdminController` switch paths, and related VO page field mapping.
- Do not commit secrets or environment-specific credentials; prefer stage/env substitution model used in `application-stage.yml` and `deployment/environment.conf.example`.

