From 517dbeaca2854c5a5fa45ab3eedbc7286080b753 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 16:34:42 +0000 Subject: [PATCH 1/2] Initial plan From 40d3c63a9b1c69a66ecb47a7a3b96110189b9072 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 16:39:26 +0000 Subject: [PATCH 2/2] Add path-specific instructions, code-reviewer agent, prompts, and copilot setup workflow Co-authored-by: yortch <4576246+yortch@users.noreply.github.com> --- .github/agents/code-reviewer.agent.md | 84 +++++++++++++++++++ .github/copilot-setup-steps.yml | 26 ++++++ .../instructions/code-review.instructions.md | 44 ++++++++++ .github/instructions/docker.instructions.md | 48 +++++++++++ .../documentation.instructions.md | 43 ++++++++++ .../instructions/java-testing.instructions.md | 46 ++++++++++ .github/instructions/java.instructions.md | 62 ++++++++++++++ .github/instructions/react.instructions.md | 37 ++++++++ .github/prompts/code-review.prompt.md | 65 ++++++++++++++ .github/prompts/java-docs.prompt.md | 62 ++++++++++++++ .github/prompts/java-junit.prompt.md | 69 +++++++++++++++ .github/prompts/java-springboot.prompt.md | 76 +++++++++++++++++ 12 files changed, 662 insertions(+) create mode 100644 .github/agents/code-reviewer.agent.md create mode 100644 .github/copilot-setup-steps.yml create mode 100644 .github/instructions/code-review.instructions.md create mode 100644 .github/instructions/docker.instructions.md create mode 100644 .github/instructions/documentation.instructions.md create mode 100644 .github/instructions/java-testing.instructions.md create mode 100644 .github/instructions/java.instructions.md create mode 100644 .github/instructions/react.instructions.md create mode 100644 .github/prompts/code-review.prompt.md create mode 100644 .github/prompts/java-docs.prompt.md create mode 100644 .github/prompts/java-junit.prompt.md create mode 100644 .github/prompts/java-springboot.prompt.md diff --git a/.github/agents/code-reviewer.agent.md b/.github/agents/code-reviewer.agent.md new file mode 100644 index 0000000..11bbcf1 --- /dev/null +++ b/.github/agents/code-reviewer.agent.md @@ -0,0 +1,84 @@ +--- +name: 'Code Reviewer' +description: 'Code review specialist for Three Rivers Bank. Reviews PRs for Java/Spring Boot best practices, React patterns, security, testing coverage, and project conventions.' +model: Claude Sonnet 4 +tools: ['codebase', 'search', 'changes'] +--- + +## Your Mission + +You are a thorough code review specialist for the Three Rivers Bank credit card comparison platform. Your job is to review code changes for quality, security, and adherence to project standards. Provide clear, actionable feedback with severity levels. + +Always respect the `applyTo`-scoped instruction files in `.github/instructions/` — those files define the authoritative rules for each area of the codebase. + +--- + +## Review Checklist + +### 🔴 Critical — Must Fix Before Merge + +#### Java / Spring Boot +- [ ] No wildcard imports (`import java.util.*`, etc.) — every import must be explicit +- [ ] No JPA entities exposed directly in controller responses or request bodies — use DTOs +- [ ] No hardcoded secrets, credentials, or API keys anywhere in source code +- [ ] No `System.out.println` — use SLF4J with parameterized messages +- [ ] No hardcoded BIAN API base URLs — must come from `application.yml` +- [ ] All BIAN API calls go through the Resilience4j circuit breaker + +#### Security +- [ ] No SQL injection risks — all queries use parameterized statements or Spring Data JPA +- [ ] No XSS vulnerabilities in React components +- [ ] No secrets or credentials embedded in Docker image layers + +--- + +### 🟡 Warning — Should Fix + +#### Java / Spring Boot +- [ ] Constructor-based dependency injection with `private final` fields +- [ ] `@Transactional` on service methods that modify data +- [ ] `@ControllerAdvice` global exception handler returns structured error responses +- [ ] SLF4J logger declared as `private static final Logger` +- [ ] Java Bean Validation (`@Valid`, `@NotNull`, `@Size`) used on DTOs +- [ ] Configuration in `application.yml`; `@ConfigurationProperties` for type-safe binding + +#### React / Frontend +- [ ] React Query used for server state — no raw `fetch`/`axios` outside query functions +- [ ] MUI components use the Three Rivers Bank theme from `frontend/src/theme.js` +- [ ] Functional components with hooks only — no class components +- [ ] Page components in `pages/`, reusable components in `components/{cards,common,layout}` + +#### Testing +- [ ] New features or bug fixes include corresponding tests +- [ ] Test naming follows `methodName_should_expectedBehavior_when_scenario` +- [ ] Controller tests use `@WebMvcTest`; repository tests use `@DataJpaTest` +- [ ] Mockito used for unit test mocks; WireMock used for BIAN API integration mocks +- [ ] No wildcard imports in test files + +#### Docker / Infrastructure +- [ ] Dockerfiles use multi-stage builds +- [ ] Base images pinned to explicit versions (not `:latest`) +- [ ] Containers run as non-root users +- [ ] `HEALTHCHECK` instructions present + +--- + +### 🟢 Suggestion — Nice to Have + +- [ ] `@DisplayName` annotations on JUnit test methods for readability +- [ ] `assertAll` used to group related assertions +- [ ] Javadoc on all `public` and `protected` members (`@param`, `@return`, `@throws`) +- [ ] `@param` and `@return` JSDoc on React component props +- [ ] Consistent use of Three Rivers Bank brand colors (`#003366`, `#008080`) + +--- + +## Output Format + +Structure your review as: + +1. **Summary** — one paragraph overview of the changes and overall quality +2. **Critical Issues** 🔴 — list each issue with file, line reference, explanation, and suggested fix +3. **Warnings** 🟡 — list each issue with file, line reference, and suggested improvement +4. **Suggestions** 🟢 — optional improvements that would enhance quality +5. **Verdict** — `✅ Approved`, `⚠️ Approved with suggestions`, or `❌ Changes requested` diff --git a/.github/copilot-setup-steps.yml b/.github/copilot-setup-steps.yml new file mode 100644 index 0000000..920428b --- /dev/null +++ b/.github/copilot-setup-steps.yml @@ -0,0 +1,26 @@ +name: "Copilot Setup Steps" +on: workflow_dispatch + +jobs: + copilot-setup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + - name: Cache Maven packages + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + - name: Build backend + run: cd backend && mvn clean install -DskipTests + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + - name: Install frontend dependencies + run: cd frontend && npm install diff --git a/.github/instructions/code-review.instructions.md b/.github/instructions/code-review.instructions.md new file mode 100644 index 0000000..51e2183 --- /dev/null +++ b/.github/instructions/code-review.instructions.md @@ -0,0 +1,44 @@ +--- +description: 'Standards that Copilot should enforce during pull request code reviews' +applyTo: '**' +--- + +# Code Review Standards + +## Security + +- Flag any hardcoded secrets, passwords, API keys, or tokens — these must come from environment variables or a secrets manager. +- Check for SQL injection risks; all queries must use parameterized statements or Spring Data JPA. +- Check for XSS vulnerabilities in React components; sanitize any user-supplied HTML. + +## Java / Spring Boot + +- **Reject wildcard imports** — every Java file must use explicit, per-class imports. No `import java.util.*` or similar. +- Verify DTOs are used in all controller request/response bodies — never expose JPA entities directly. +- Check that all BIAN API calls go through the Resilience4j circuit breaker. +- Flag any hardcoded BIAN API URLs — base URLs must come from `application.yml` configuration. +- Flag any `System.out.println` usage — use SLF4J logger with parameterized messages instead. +- Confirm `@Transactional` is present on service methods that modify data. + +## React / Frontend + +- Verify React components use React Query for server state — flag raw `fetch` or `axios` calls outside query functions. +- Check that MUI components use the Three Rivers Bank theme from `frontend/src/theme.js`. + +## Error Handling & Logging + +- Ensure exceptions are handled explicitly and not silently swallowed. +- Verify SLF4J is used for logging in all Java classes, not `System.out`. + +## Testing + +- Verify that new features or bug fixes are accompanied by tests. +- Check that test naming follows the `methodName_should_expectedBehavior_when_scenario` convention. +- Confirm controller tests use `@WebMvcTest` and repository tests use `@DataJpaTest`. + +## Docker / Infrastructure + +- Verify Dockerfiles use multi-stage builds. +- Check that base images are pinned to explicit versions, not `:latest`. +- Confirm no secrets or credentials are embedded in Docker images. +- Verify health check instructions are present. diff --git a/.github/instructions/docker.instructions.md b/.github/instructions/docker.instructions.md new file mode 100644 index 0000000..3b67673 --- /dev/null +++ b/.github/instructions/docker.instructions.md @@ -0,0 +1,48 @@ +--- +description: 'Dockerfile and Docker best practices' +applyTo: 'docker/**' +--- + +# Docker / Dockerfile Standards + +## Multi-Stage Builds + +- Use multi-stage builds to minimize final image size. +- Separate the build stage from the runtime stage. +- Only copy artifacts needed at runtime into the final stage. + +## Base Image Versions + +- Pin base image versions explicitly — do **not** use `:latest` for production images. +- Example: `FROM eclipse-temurin:17-jre-jammy` instead of `FROM eclipse-temurin:latest`. + +## Non-Root Users + +- Run container processes as a non-root user. +- Create a dedicated application user in the Dockerfile and switch to it with `USER`. + +## Image Naming + +- Follow the naming convention: `threeriversbank/{backend|frontend}:latest`. +- Tag release images with a version in addition to `latest`. + +## Backend (Java) + +- Use a Java 17+ JRE runtime image (not JDK) in the final stage. +- H2 in-memory database is embedded — no external database container needed for the backend. + +## Frontend (Nginx) + +- Serve the Vite static build output via Nginx in the final stage. +- Copy only the `dist/` directory into the Nginx image. + +## Health Checks + +- Add a `HEALTHCHECK` instruction to every service image. +- Backend health check should target `/actuator/health`. +- Frontend health check should verify the Nginx process is responding. + +## Secrets + +- Never embed secrets, credentials, or API keys in Dockerfile instructions or image layers. +- Use environment variables (injected at runtime) or a secrets manager for sensitive values. diff --git a/.github/instructions/documentation.instructions.md b/.github/instructions/documentation.instructions.md new file mode 100644 index 0000000..6e8d990 --- /dev/null +++ b/.github/instructions/documentation.instructions.md @@ -0,0 +1,43 @@ +--- +description: 'Documentation and Javadoc standards' +applyTo: 'backend/src/main/**/*.java' +--- + +# Java Documentation (Javadoc) Standards + +## Coverage + +- All `public` and `protected` members (classes, methods, constructors, fields) must have Javadoc comments. +- Document package-private and private members when they are complex or non-obvious. + +## Summary Sentence + +- The first sentence of a Javadoc comment is the summary description. +- It must be concise, describe what the member does, and end with a period. + +## Standard Tags + +- Use `@param ` for every method parameter. Descriptions start with a lowercase letter and do not end with a period. +- Use `@return` for methods with a non-void return type. +- Use `@throws` (or `@exception`) for every checked exception a method declares, and for significant unchecked exceptions. +- Use `@see` to reference related types or members. +- Use `@since` to indicate the version when a feature was introduced. + +## Inline Tags + +- Use `{@code SomeType}` for inline references to code elements (types, methods, variables). +- Use `
{@code ... }
` for multi-line code examples. + +## Inheritance + +- Use `{@inheritDoc}` to inherit documentation from a superclass or interface. +- If the subclass overrides behavior significantly, document the differences rather than using `{@inheritDoc}`. + +## Generic Types + +- Use `@param ` to document type parameters on generic classes or methods. + +## Deprecation + +- Use `@deprecated` to mark members that should no longer be used. +- Always include an explanation and reference to the preferred alternative in the `@deprecated` description. diff --git a/.github/instructions/java-testing.instructions.md b/.github/instructions/java-testing.instructions.md new file mode 100644 index 0000000..641d678 --- /dev/null +++ b/.github/instructions/java-testing.instructions.md @@ -0,0 +1,46 @@ +--- +description: 'JUnit 5 testing standards for the Spring Boot backend' +applyTo: 'backend/src/test/**/*.java' +--- + +# JUnit 5 Testing Standards + +## Imports + +- **NEVER use wildcard imports** in test files. Use explicit imports for every class. + +## Test Structure + +- Follow the **Arrange-Act-Assert (AAA)** pattern in every test method. +- Test class naming: `{Class}Test.java` (e.g., `CreditCardServiceTest.java`). +- Test method naming: `methodName_should_expectedBehavior_when_scenario`. +- Use `@DisplayName` annotations for human-readable test descriptions. + +## Test Slices + +- Use `@WebMvcTest` for controller tests — loads only the web layer. +- Use `@DataJpaTest` for repository tests — loads only the JPA layer. +- Use `@SpringBootTest` only for full integration tests that need the entire context. + +## Mocking + +- Use Mockito for mocking dependencies: `@Mock`, `@InjectMocks`, `@MockBean`. +- Use WireMock to mock external BIAN API calls in integration tests. + +## Assertions + +- Keep tests focused on a single behavior per method when practical. +- Use `assertAll` to group related assertions so all failures are reported together. +- Use descriptive failure messages in assertions. +- Use `assertThrows` to verify exception behavior. + +## Test Organization + +- Place test files under `backend/src/test/java` mirroring the main source structure. +- Use `@Nested` inner classes to group related test scenarios. +- Use `@Tag` to categorize tests (e.g., `@Tag("unit")`, `@Tag("integration")`). +- Use `@Disabled` with an explanatory reason when temporarily skipping tests. + +## Data-Driven Tests + +- Use `@ParameterizedTest` with `@ValueSource`, `@CsvSource`, or `@MethodSource` for data-driven scenarios. diff --git a/.github/instructions/java.instructions.md b/.github/instructions/java.instructions.md new file mode 100644 index 0000000..da6bc0e --- /dev/null +++ b/.github/instructions/java.instructions.md @@ -0,0 +1,62 @@ +--- +description: 'Java coding standards for the Three Rivers Bank Spring Boot backend' +applyTo: 'backend/**/*.java' +--- + +# Java / Spring Boot Coding Standards + +## Imports + +- **NEVER use wildcard imports** (e.g., `import java.util.*`). Always use explicit, per-class imports. This is a hard enterprise requirement. + +## Dependency Injection + +- Use constructor-based dependency injection for all required dependencies. +- Declare injected fields as `private final`. +- Do not use field injection (`@Autowired` on fields). + +## Component Stereotypes + +- Use `@Service` for business-logic classes. +- Use `@Repository` for data-access classes. +- Use `@RestController` for REST endpoint classes. + +## DTOs + +- Never expose JPA entities directly in controller responses or request bodies. +- Use DTOs (`model/dto`) for all API inputs and outputs. +- Map between entities and DTOs in the service layer. + +## Service Layer + +- Encapsulate all business logic in `@Service` classes; keep controllers thin. +- Annotate service methods that modify data with `@Transactional`. +- Services must be stateless. + +## Logging + +- Use SLF4J for all logging: `private static final Logger logger = LoggerFactory.getLogger(MyClass.class);` +- Use parameterized messages: `logger.info("Processing card {}", cardId);` — never string concatenation. +- Do **not** use `System.out.println`. + +## Configuration + +- Store all configuration in `application.yml`. +- Use `@ConfigurationProperties` for type-safe binding of configuration properties. +- Do not hardcode URLs, credentials, or environment-specific values in source code. + +## Validation + +- Apply Java Bean Validation annotations (`@Valid`, `@NotNull`, `@Size`, etc.) on DTO classes. +- Trigger validation on controller method parameters with `@Valid`. + +## Error Handling + +- Implement a single global exception handler using `@ControllerAdvice` and `@ExceptionHandler`. +- Return consistent, structured error responses from the global handler. + +## External API Calls (BIAN) + +- All calls to the BIAN API must go through the Resilience4j circuit breaker. +- Never call the BIAN API directly from a controller or repository. +- BIAN API base URLs must come from configuration, never hardcoded. diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md new file mode 100644 index 0000000..ae1b09b --- /dev/null +++ b/.github/instructions/react.instructions.md @@ -0,0 +1,37 @@ +--- +description: 'React coding standards for the Three Rivers Bank frontend' +applyTo: 'frontend/src/**/*.{jsx,js}' +--- + +# React / Frontend Coding Standards + +## State Management + +- Use **React Query (TanStack Query)** for all server state — do NOT use Redux or raw `fetch`/`axios` calls outside of query functions. +- Use React built-in hooks (`useState`, `useReducer`) for local UI state only. + +## UI Components + +- Use **Material-UI (MUI)** components for all UI elements. +- Import and apply the custom Three Rivers Bank theme from `frontend/src/theme.js`. +- Use the bank's brand colors: Navy `#003366` (primary) and Teal `#008080` (secondary). + +## Routing + +- Use **React Router v6** for all client-side navigation. +- Use `` and `useNavigate` for programmatic navigation. + +## Component Style + +- Use **functional components with hooks** exclusively — no class components. +- Page-level components go in `frontend/src/pages/`. +- Reusable components go in `frontend/src/components/{cards,common,layout}`. + +## Props Documentation + +- Document component props with JSDoc `@param` comments or PropTypes declarations. + +## Theme Usage + +- Always import the theme from `frontend/src/theme.js` when referencing design tokens. +- Do not hardcode color values that are already defined in the theme. diff --git a/.github/prompts/code-review.prompt.md b/.github/prompts/code-review.prompt.md new file mode 100644 index 0000000..20e387e --- /dev/null +++ b/.github/prompts/code-review.prompt.md @@ -0,0 +1,65 @@ +--- +description: 'Run a comprehensive code review on the current changes' +mode: 'agent' +--- + +# Comprehensive Code Review + +Review the current code changes thoroughly, checking for compliance with the Three Rivers Bank project standards defined in `.github/instructions/`. + +## What to Check + +### Java / Spring Boot (`backend/**/*.java`) +Follow the standards in `.github/instructions/java.instructions.md`: +- No wildcard imports — every import must be explicit +- Constructor-based DI with `private final` fields +- DTOs used in all controller request/response bodies — no JPA entities exposed directly +- Business logic in `@Service` classes; controllers are thin +- `@Transactional` on service methods that modify data +- SLF4J logger used with parameterized messages — no `System.out.println` +- BIAN API calls go through the Resilience4j circuit breaker +- BIAN API base URLs come from configuration, not hardcoded + +### JUnit Tests (`backend/src/test/**/*.java`) +Follow the standards in `.github/instructions/java-testing.instructions.md`: +- No wildcard imports in test files +- AAA pattern followed in each test method +- Test naming: `methodName_should_expectedBehavior_when_scenario` +- `@WebMvcTest` for controllers, `@DataJpaTest` for repositories +- Mockito for unit mocks, WireMock for BIAN API mocks + +### React / Frontend (`frontend/src/**/*.{jsx,js}`) +Follow the standards in `.github/instructions/react.instructions.md`: +- React Query used for server state — no raw `fetch`/`axios` outside query functions +- MUI components use the Three Rivers Bank theme from `frontend/src/theme.js` +- Functional components with hooks only +- Components organized into correct directories (`pages/`, `components/`) + +### Security (all files) +Follow the standards in `.github/instructions/code-review.instructions.md`: +- No hardcoded secrets, passwords, or API keys +- No SQL injection risks +- No XSS vulnerabilities in React components + +### Docker (`docker/**`) +Follow the standards in `.github/instructions/docker.instructions.md`: +- Multi-stage builds used +- Base images pinned to explicit versions (not `:latest`) +- Containers run as non-root users +- `HEALTHCHECK` instructions present +- No secrets in image layers + +### Documentation (`backend/src/main/**/*.java`) +Follow the standards in `.github/instructions/documentation.instructions.md`: +- All `public` and `protected` members have Javadoc +- `@param`, `@return`, `@throws` tags present where applicable + +## Output Format + +Structure your review as: + +1. **Summary** — one paragraph overview of the changes and overall quality +2. **Critical Issues** 🔴 — must be fixed before merge (file, line, explanation, fix) +3. **Warnings** 🟡 — should be addressed (file, line, suggested improvement) +4. **Suggestions** 🟢 — optional quality improvements +5. **Verdict** — `✅ Approved`, `⚠️ Approved with suggestions`, or `❌ Changes requested` diff --git a/.github/prompts/java-docs.prompt.md b/.github/prompts/java-docs.prompt.md new file mode 100644 index 0000000..eeb7c07 --- /dev/null +++ b/.github/prompts/java-docs.prompt.md @@ -0,0 +1,62 @@ +--- +description: 'Javadoc documentation best practices for Java code' +mode: 'agent' +--- + +# Java Documentation (Javadoc) Best Practices + +Your goal is to ensure that Java code in the Three Rivers Bank backend is well-documented following Javadoc best practices. + +## Coverage + +- All `public` and `protected` members (classes, constructors, methods, fields) must have Javadoc comments. +- Document package-private and `private` members when they are complex or non-obvious. + +## Summary Sentence + +- The first sentence of a Javadoc comment is the summary description. +- It must be a concise overview of what the member does and end with a period. + +## Standard Tags + +- Use `@param ` for every method parameter. Descriptions start with a lowercase letter and do not end with a period. +- Use `@return` for methods with a non-`void` return type. +- Use `@throws` (or `@exception`) for every checked exception a method declares, and for significant unchecked exceptions. +- Use `@see` to reference related types or members. +- Use `@since` to indicate when the feature was introduced (e.g., version number). +- Use `@version` to specify the current version when relevant. +- Use `@author` to attribute authorship when appropriate. + +## Inline Tags + +- Use `{@code SomeType}` for inline references to code elements (types, methods, variables). +- Use `
{@code ... }
` for multi-line code examples. + +## Inheritance + +- Use `{@inheritDoc}` to inherit documentation from a superclass or interface, unless the subclass overrides behavior significantly. +- When overriding behavior, document the differences explicitly rather than relying on `{@inheritDoc}`. + +## Generic Types + +- Use `@param ` to document type parameters on generic classes or methods. + +## Deprecation + +- Use `@deprecated` to mark members that should no longer be used. +- Always include in the `@deprecated` description an explanation and a reference to the preferred alternative. + +## Example + +```java +/** + * Retrieves a credit card by its unique identifier. + * + * @param cardId the unique identifier of the credit card + * @return the {@code CreditCardDto} matching the given identifier + * @throws CreditCardNotFoundException if no card with the given identifier exists + */ +public CreditCardDto findById(Long cardId) { + // ... +} +``` diff --git a/.github/prompts/java-junit.prompt.md b/.github/prompts/java-junit.prompt.md new file mode 100644 index 0000000..d25b009 --- /dev/null +++ b/.github/prompts/java-junit.prompt.md @@ -0,0 +1,69 @@ +--- +description: 'JUnit 5 testing best practices for backend tests' +mode: 'agent' +--- + +# JUnit 5+ Best Practices + +Your goal is to help write effective unit and integration tests for the Three Rivers Bank backend using JUnit 5, covering both standard and data-driven testing approaches. + +## Project Setup + +- Place test source code in `backend/src/test/java`. +- Include dependencies for `junit-jupiter-api`, `junit-jupiter-engine`, and `junit-jupiter-params` for parameterized tests. +- Run tests with: `mvn test`. + +## Imports + +- **NEVER use wildcard imports** in test files. Use explicit, per-class imports for every type. + +## Test Structure + +- Test class naming: `{Class}Test.java` (e.g., `CreditCardServiceTest.java`). +- Use `@Test` for standard test methods. +- Follow the **Arrange-Act-Assert (AAA)** pattern in every test method. +- Test method naming convention: `methodName_should_expectedBehavior_when_scenario`. +- Use `@BeforeEach` and `@AfterEach` for per-test setup and teardown. +- Use `@BeforeAll` and `@AfterAll` for per-class setup and teardown (must be `static`). +- Use `@DisplayName` to provide human-readable names for test classes and methods. + +## Test Slices + +- Use `@WebMvcTest` for controller tests — loads only the web layer. +- Use `@DataJpaTest` for repository tests — loads only the JPA layer with an in-memory database. +- Use `@SpringBootTest` only for full integration tests that require the complete application context. + +## Standard Tests + +- Keep tests focused on a single behavior per method. +- Avoid testing multiple unrelated conditions in one test method. +- Make tests independent and idempotent (can run in any order). +- Avoid test interdependencies. + +## Data-Driven (Parameterized) Tests + +- Use `@ParameterizedTest` to mark a method as parameterized. +- Use `@ValueSource` for simple literal values. +- Use `@MethodSource` for complex arguments provided by a factory method. +- Use `@CsvSource` for inline comma-separated values. +- Use `@EnumSource` to test all enum constants. + +## Assertions + +- Use `org.junit.jupiter.api.Assertions` static methods (`assertEquals`, `assertTrue`, `assertNotNull`). +- Use `assertAll` to group related assertions so all failures are reported together. +- Use `assertThrows` to verify exception behavior. +- Include descriptive failure messages in assertions. + +## Mocking and Isolation + +- Use Mockito for mocking dependencies: `@Mock`, `@InjectMocks`, `@MockBean`. +- Use WireMock to mock external BIAN API HTTP calls in integration tests. +- Use interfaces to facilitate mocking. + +## Test Organization + +- Mirror the main source package structure under `src/test/java`. +- Use `@Nested` inner classes to group related test scenarios. +- Use `@Tag` to categorize tests: `@Tag("unit")`, `@Tag("integration")`. +- Use `@Disabled` with an explanatory reason when temporarily skipping a test. diff --git a/.github/prompts/java-springboot.prompt.md b/.github/prompts/java-springboot.prompt.md new file mode 100644 index 0000000..aa29752 --- /dev/null +++ b/.github/prompts/java-springboot.prompt.md @@ -0,0 +1,76 @@ +--- +description: 'Spring Boot best practices for the Three Rivers Bank backend' +mode: 'agent' +--- + +# Spring Boot Best Practices + +Your goal is to help write high-quality Spring Boot applications for the Three Rivers Bank backend by following established best practices. + +## Project Setup & Structure + +- **Build Tool:** Use Maven (`pom.xml`) for dependency management. +- **Starters:** Use Spring Boot starters (e.g., `spring-boot-starter-web`, `spring-boot-starter-data-jpa`) to simplify dependency management. +- **Package Structure:** Follow the project's layer-based layout: `com.threeriversbank/{controller,service,repository,model/{entity,dto},client,config}`. + +## Imports + +- **NEVER use wildcard imports** (e.g., `import java.util.*`). Always use explicit, per-class imports. This is a hard enterprise requirement. + +## Dependency Injection & Components + +- **Constructor Injection:** Always use constructor-based injection for required dependencies. This makes components easier to test and dependencies explicit. +- **Immutability:** Declare dependency fields as `private final`. +- **Component Stereotypes:** Use `@Component`, `@Service`, `@Repository`, and `@Controller`/`@RestController` annotations appropriately to define beans. + +## Configuration + +- **Externalized Configuration:** Use `application.yml` for configuration. YAML is preferred for readability and hierarchical structure. +- **Type-Safe Properties:** Use `@ConfigurationProperties` to bind configuration to strongly-typed Java objects. +- **Profiles:** Use Spring Profiles (`application-dev.yml`, `application-prod.yml`) to manage environment-specific configurations. +- **Secrets Management:** Do not hardcode secrets. Use environment variables or a dedicated secret management tool. + +## Web Layer (Controllers) + +- **RESTful APIs:** Design clear and consistent RESTful endpoints. +- **DTOs (Data Transfer Objects):** Use DTOs to expose and consume data in the API layer. Do not expose JPA entities directly to the client. +- **Validation:** Use Java Bean Validation (JSR 380) with annotations (`@Valid`, `@NotNull`, `@Size`) on DTOs to validate request payloads. +- **Error Handling:** Implement a global exception handler using `@ControllerAdvice` and `@ExceptionHandler` to provide consistent error responses. + +## Service Layer + +- **Business Logic:** Encapsulate all business logic within `@Service` classes. +- **Statelessness:** Services should be stateless. +- **Transaction Management:** Use `@Transactional` on service methods to manage database transactions declaratively. + +## Data Layer (Repositories) + +- **Spring Data JPA:** Use Spring Data JPA repositories by extending `JpaRepository` or `CrudRepository` for standard database operations. +- **Custom Queries:** For complex queries, use `@Query` or the JPA Criteria API. +- **Projections:** Use DTO projections to fetch only the necessary data from the database. + +## Logging + +- **SLF4J:** Use the SLF4J API for logging. +- **Logger Declaration:** `private static final Logger logger = LoggerFactory.getLogger(MyClass.class);` +- **Parameterized Logging:** Use parameterized messages (`logger.info("Processing card {}...", cardId);`) instead of string concatenation. +- **No System.out:** Never use `System.out.println` — always use the SLF4J logger. + +## External API Calls (BIAN) + +- All calls to the BIAN API must go through the Resilience4j circuit breaker (3 retries, 5s timeout). +- Configure the Feign client base URL from `application.yml` — never hardcode `https://virtserver.swaggerhub.com/...`. +- Use `@Cacheable` with appropriate TTLs: 5 minutes for transactions, 1 hour for billing data. +- Implement fallback methods that return H2 database data when the BIAN API is unavailable. + +## Testing + +- **Unit Tests:** Write unit tests for services and components using JUnit 5 and Mockito. +- **Integration Tests:** Use `@SpringBootTest` for integration tests that load the Spring application context. +- **Test Slices:** Use `@WebMvcTest` (for controllers) or `@DataJpaTest` (for repositories) to test specific layers in isolation. +- **WireMock:** Use WireMock to mock external BIAN API calls in integration tests. + +## Security + +- **Input Sanitization:** Prevent SQL injection by using Spring Data JPA or parameterized queries. +- **No Hardcoded Credentials:** Never commit API keys, passwords, or tokens to source code.