Scenario: Spring Boot Enterprise with AEEF Standards
This walkthrough shows how to apply AEEF production standards together on a Spring Boot enterprise application. It follows an entire feature from prompt to production, demonstrating how the standards create a governed delivery pipeline — with specific attention to layered architecture, Spring Security, and the testing pyramid with Testcontainers.
Time required: 60-90 minutes (reading + doing) Prerequisites: Familiarity with Java 21+, Spring Boot 3, and basic AEEF concepts from the Startup Quick-Start.
This is a realistic composite scenario showing how standards apply together. Adapt the specifics to your stack — the governance workflow is universal.
The Project
An enterprise multi-tenant document management system built with:
- Framework: Spring Boot 3.3 with Java 21
- Database: PostgreSQL via Spring Data JPA (Hibernate 6)
- Security: Spring Security 6 with JWT + role-based access
- Search: Elasticsearch for full-text document search
- Storage: S3-compatible object storage for files
- Testing: JUnit 5 + Mockito + Testcontainers + MockMvc
- CI: GitHub Actions with SpotBugs + OWASP Dependency-Check
- Build: Gradle with Spring Boot plugin
The team has 20 engineers across 4 squads and has completed the CI/CD Pipeline Starter and Policy Templates.
The Feature
User story: As an organization admin, I can define document retention policies so that documents are automatically archived or deleted after the retention period expires.
This feature touches:
- Database schema (retention policy entity, document metadata update)
- REST API (CRUD for retention policies)
- Scheduled job (nightly scan for expired documents)
- Audit trail (log all retention actions for compliance)
- Authorization (only org admins can define policies; deletion must be approved by two admins)
- Event-driven: publish events when documents are archived/deleted
Phase 1: Prompt Engineering (PRD-STD-001)
Step 1.1: Structured Prompt for REST Endpoint
Using the Java Secure REST Endpoint template (prompt-library/by-language/java/secure-endpoint.md) combined with the Spring Boot Endpoint Implementation template (prompt-library/by-framework/spring-boot/endpoint-implementation.md):
You are a senior Spring Boot engineer building production-grade REST endpoints.
**Context:**
- Spring Boot 3.3 with Java 21 (records, sealed interfaces, pattern matching)
- Database: Spring Data JPA with Hibernate 6, PostgreSQL
- Security: Spring Security 6 with JWT, role hierarchy (VIEWER < EDITOR < ADMIN < ORG_ADMIN)
- Validation: Jakarta Bean Validation
- API docs: springdoc-openapi (OpenAPI 3.1)
- Build: Gradle
**Task:** Create CRUD endpoints for document retention policies.
**Requirements:**
1. RetentionPolicy entity: org_id, name, document_category, retention_days,
action (ARCHIVE/DELETE), requires_approval (boolean), created_by, active
2. Only ORG_ADMIN role can create, update, or delete policies
3. Any authenticated user can list policies for their org
4. Policies with requires_approval=true need a second ORG_ADMIN to approve deletion actions
5. Unique constraint on (org_id, document_category) — one policy per category per org
6. Soft-delete with deactivation timestamp (never hard-delete policies for audit trail)
**Constraints:**
- DTOs as Java records — never expose JPA entities
- @Valid on ALL @RequestBody parameters
- Constructor injection — no field injection
- @Transactional(readOnly = true) on read operations
- @PreAuthorize("hasRole('ORG_ADMIN')") on mutation endpoints
- Error responses via RFC 9457 ProblemDetail
- @Version for optimistic locking on policy updates
- Use @EntityGraph to prevent N+1 on policy-document associations
Step 1.2: Structured Prompt for Scheduled Job
You are implementing a scheduled retention enforcement job.
**Context:**
- Spring Boot 3.3, @Scheduled with ShedLock for distributed locking
- Runs nightly at 02:00 UTC
**Task:** Implement the document retention scanner.
**Requirements:**
1. Find all active policies where documents exceed retention_days
2. For ARCHIVE action: move document metadata to archive table, move file to cold storage
3. For DELETE action with requires_approval=false: hard-delete file, soft-delete metadata
4. For DELETE action with requires_approval=true: create approval request, notify ORG_ADMINs
5. Batch processing: process 100 documents per batch to avoid memory pressure
6. Audit log every action: policy_id, document_id, action, timestamp, initiated_by="system"
7. Stop processing if error rate exceeds 5% in a batch (circuit breaker)
**Constraints:**
- Use ShedLock to prevent duplicate runs across instances
- Use @Transactional per batch, not per entire job
- Publish ApplicationEvent for each action (ArchiveEvent, DeleteEvent, ApprovalRequestEvent)
- Side effects (email, S3 operations) happen AFTER_COMMIT via @TransactionalEventListener
- Log structured context: job_run_id, batch_number, documents_processed, errors
- Never delete files before metadata is committed (metadata first, file second)
Step 1.3: Record Prompt References
AI-Usage: claude
AI-Prompt-Ref: by-language/java/secure-endpoint + by-framework/spring-boot/endpoint-implementation (retention CRUD),
by-framework/spring-boot/component-implementation (scheduled job)
AI-Confidence: high — CRUD endpoints, medium — batch job with approval workflow
Phase 2: Human-in-the-Loop Review (PRD-STD-002)
Step 2.1: Review AI Output Against Checklist
Using the Java PR Risk Review prompt (prompt-library/by-language/java/pr-risk-review.md):
Critical items for this feature:
| Check | What to Verify | Status |
|---|---|---|
| Auth bypass | Is @PreAuthorize on every mutation endpoint? Is org_id filtered from JWT claim? | |
| Missing @Valid | Does every @RequestBody have @Valid? (The #1 AI mistake in Spring Boot) | |
| Entity exposure | Are JPA entities absent from controller signatures? Using record DTOs? | |
| SQL injection | All @Query methods use :paramName — no string concatenation? | |
| Transaction boundary | Is @Transactional per-batch, not wrapping the entire nightly job? | |
| Event ordering | Are file deletions in @TransactionalEventListener(AFTER_COMMIT)? | |
| Optimistic locking | Is @Version on the entity? Is OptimisticLockException handled? | |
| Audit completeness | Is every retention action logged with policy_id, document_id, and action? | |
| Soft-delete integrity | Is the policy soft-deleted (deactivated), not hard-deleted? |
Step 2.2: Java/Spring-Specific AI Pitfalls to Check
From the Java anti-patterns table (prompt-library/by-language/java.md) and Spring Boot pitfalls (prompt-library/by-framework/spring-boot.md):
- No field injection (
@Autowiredon fields) — constructor injection only - No
@Transactionalon private methods (Spring proxies can't intercept them) - No returning
nullfrom service methods — throw domain exceptions - No bare
catch (Exception e)— catch specific exception types - No
@SuppressWarningshiding real issues - DTOs are Java records, not mutable POJOs
-
@Transactional(readOnly = true)on all read-only service methods -
@EntityGraphorJOIN FETCHused to prevent N+1 queries
Phase 3: Testing (PRD-STD-003)
Step 3.1: Generate Test Matrix
Use the Java Risk-Based Test Matrix prompt (prompt-library/by-language/java/test-matrix.md) combined with Spring Boot Testing Strategy (prompt-library/by-framework/spring-boot/testing-strategy.md):
Feature: Document retention policy CRUD + nightly enforcement job
Changes: JPA entity, controller, service, repository, scheduled job, event handlers
Generate a layered test strategy following the Spring Boot testing pyramid:
1. Unit tests: service logic with Mockito, DTO validation, event publishing
2. Slice tests: @WebMvcTest for controller, @DataJpaTest for repository, @JsonTest for DTOs
3. Integration tests: @SpringBootTest with Testcontainers for full lifecycle
4. Security tests: auth enforcement at every endpoint
Expected test coverage:
| Test Type | Count | What It Covers |
|---|---|---|
| Unit (Mockito) | 15-20 | Service logic, validation, event publishing, batch processing |
| Slice — @WebMvcTest | 10-14 | Controller endpoints, request validation, auth enforcement |
| Slice — @DataJpaTest | 6-8 | Custom queries, constraints, @EntityGraph behavior |
| Slice — @JsonTest | 4-6 | DTO serialization, missing fields, date formats |
| Integration | 5-8 | Full CRUD lifecycle, scheduled job, event flow |
Step 3.2: Verify AI-Generated Tests
Common issues with AI-generated Spring Boot tests (from prompt-library/by-framework/spring-boot/testing-strategy.md):
- @WebMvcTest includes SecurityConfig — tests auth enforcement
- @DataJpaTest uses Testcontainers, NOT H2 (
@AutoConfigureTestDatabase(replace = NONE)) - Service unit tests use
@ExtendWith(MockitoExtension.class), not@SpringBootTest - @Valid tests send invalid payloads and assert 400 (not just happy path)
- Tests assert exact HTTP status codes (201, 204) not just "2xx success"
- No
Thread.sleep()— use Awaitility for async assertions - Tests cover both @WithMockUser and unauthenticated scenarios
Phase 4: Security Scanning (PRD-STD-004)
Step 4.1: Automated CI Checks
Your CI pipeline catches:
# These run automatically on every PR
- SpotBugs: Null dereference, SQL injection, serialization issues
- OWASP Dependency-Check: Known CVEs in Java dependencies
- Semgrep: Spring Security misconfigurations, injection patterns
- Checkstyle: Code style enforcement
Step 4.2: Compliance-Specific Security Review
Document retention is a compliance feature. Use the Spring Boot Security Review prompt (prompt-library/by-framework/spring-boot/security-review.md) to verify:
- Retention policies cannot be modified after documents have been processed under them (immutability after activation)
- Audit log entries are append-only — no update/delete API for audit records
- Two-admin approval flow cannot be bypassed (same admin cannot approve their own request)
- Scheduled job uses ShedLock to prevent duplicate runs across instances
- Actuator endpoints for job status are not exposed publicly
- Hard-deleted files are unrecoverable (S3 object deleted, not just hidden)
- Soft-deleted metadata retains the audit trail reference
Phase 5: Quality Gates (PRD-STD-007)
Step 5.1: PR Checklist
| Gate | Tool | Pass Criteria |
|---|---|---|
| Compilation | gradle compileJava | Zero errors |
| Lint | Checkstyle + SpotBugs | Zero errors |
| Unit tests | gradle test | 100% passing, new code covered |
| Slice tests | gradle test | All @WebMvcTest and @DataJpaTest passing |
| Integration tests | gradle integrationTest | Full lifecycle tests passing |
| Security scan | OWASP Dependency-Check | Zero high/critical CVEs |
| API contract | springdoc OpenAPI diff | No unintentional breaking changes |
| Build | gradle bootJar | Successful |
Step 5.2: PR Metadata
## Changes
- Add RetentionPolicy JPA entity with Flyway migration V7__retention_policies
- Add CRUD endpoints: POST/GET/PATCH/DELETE /api/v1/retention-policies
- Add approval workflow for deletion policies (requires two ORG_ADMINs)
- Add nightly retention enforcement job with ShedLock
- Add audit trail for all retention actions
- Add ApplicationEvents: ArchiveEvent, DeleteEvent, ApprovalRequestEvent
## AI Disclosure
- AI-Usage: claude
- AI-Prompt-Ref: by-language/java/secure-endpoint + by-framework/spring-boot/endpoint-implementation (CRUD),
by-framework/spring-boot/component-implementation (scheduled job)
- AI-Review: Used by-language/java/pr-risk-review for self-review
- Human-Review: Approval workflow manually verified, audit trail completeness reviewed
## Testing
- 18 unit tests (service logic, validation, events, batch processing)
- 12 controller slice tests (CRUD + auth + validation)
- 7 repository slice tests (custom queries, constraints)
- 5 JSON serialization tests (DTO shape, date formats)
- 6 integration tests (full lifecycle, scheduled job, events)
Phase 6: Dependency Compliance (PRD-STD-008)
Use the Java Dependency Risk Check (prompt-library/by-language/java/dependency-check.md) if new dependencies were added:
Review these dependency additions:
- net.javacrumbs.shedlock:shedlock-spring (distributed job locking)
- net.javacrumbs.shedlock:shedlock-provider-jdbc-template (JDBC lock provider)
- org.awaitility:awaitility (async test assertions)
Check: license, CVEs, maintenance status, Spring Boot version compatibility, alternatives.
Phase 7: Documentation (PRD-STD-005)
Use the Java Change Runbook (prompt-library/by-language/java/change-runbook.md) to generate:
- Migration notes: Flyway migration V7 must run before deployment; ShedLock table DDL required
- Environment variables:
RETENTION_JOB_CRON(default:0 0 2 * * *),RETENTION_BATCH_SIZE(default: 100),RETENTION_ERROR_THRESHOLD_PERCENT(default: 5) - Rollback procedure: Revert Flyway migration, redeploy previous JAR, ShedLock table can remain (no-op if job doesn't exist)
- Monitoring:
- Alert on retention job failure (ShedLock timeout or error rate breach)
- Alert on approval queue depth > 50 (pending deletions not being reviewed)
- Dashboard: documents archived/deleted per day, approval queue depth, job duration trend
- Compliance notes:
- Audit log entries are immutable — no API for modification or deletion
- Retention reports available via
/api/v1/retention-policies/{id}/audit-log - Document deletion is irreversible — ensure policies are tested before activation
Summary: Standards Applied
| Standard | How It Was Applied | Evidence |
|---|---|---|
| PRD-STD-001 (Prompt Engineering) | Structured prompts from Java/Spring Boot templates | PR description AI-Prompt-Ref |
| PRD-STD-002 (Code Review) | AI + human review with compliance focus | Review comments on PR |
| PRD-STD-003 (Testing) | Full testing pyramid with Testcontainers, 48+ tests | CI test results |
| PRD-STD-004 (Security) | Automated scans + compliance-specific review | CI scan output + review notes |
| PRD-STD-005 (Documentation) | Generated runbook with compliance notes | PR description + runbook |
| PRD-STD-007 (Quality Gates) | All gates including API contract check | CI status checks |
| PRD-STD-008 (Dependencies) | Dependency risk check for new packages | PR comment with assessment |
What This Demonstrates
- @Valid is non-negotiable — the most common AI mistake in Spring Boot is omitting @Valid; the review checklist catches this every time
- Testing pyramid saves CI time — unit tests (fast) catch logic errors, slice tests (medium) catch Spring wiring issues, integration tests (slow) catch lifecycle issues
- Compliance features need extra governance — retention policies with legal implications require audit trails, two-admin approval, and immutability guarantees
- Events decouple side effects safely — @TransactionalEventListener(AFTER_COMMIT) ensures files are only deleted after metadata is committed
- Enterprise scale doesn't mean enterprise overhead — 48 tests and 7 standards applied in a single PR without blocking the team
Apply This Pattern in Your Repo
Use this scenario as a reference pattern, then choose an implementation path:
- Day 1 / small team: Starter Config Files + CI/CD Pipeline Starter + Policy Templates
- Live role-based workflow (same repo, 4-role baseline -> extended roles): AEEF CLI Wrapper and Agent Orchestration Model
- Transformation rollout (program path): Tier 2: Transformation Apply Path for phased governance rollout
- Production rollout (regulated / enterprise): Tier 3: Production Apply Path for overlays, monitoring, and full 11-agent controls
Next Steps
- Walk through the Django Monolith Scenario for a Python monolith example
- Walk through the Go Microservice Scenario for a Go concurrency example
- Review the full Production Standards to identify any gaps for your team