Skip to content

KikoDevv/exercise8#223

Open
kikoDevv wants to merge 14 commits intofungover:mainfrom
kikoDevv:KikoDevv/exercise8
Open

KikoDevv/exercise8#223
kikoDevv wants to merge 14 commits intofungover:mainfrom
kikoDevv:KikoDevv/exercise8

Conversation

@kikoDevv
Copy link
Copy Markdown

@kikoDevv kikoDevv commented Nov 29, 2025

### This PR adds a web interface using Thymeleaf templates with CSS styling, input validation, and improved test coverage.

Changes

  • Web UI: Added HomeController with Thymeleaf templates (index.html, login.html) featuring gradient styling and accessibility improvements
  • REST API: Added POST /api/cats endpoint with Jakarta validation @notblank@min
  • Security: Custom login page, CSRF disabled for API endpoints, fixed ApiKeyFilter for web routes
  • Testing: Updated CatControllerTest to properly test API key authentication, removed @WithMockUser
  • DevTools: Added Spring Boot DevTools for live reload during development
Screenshot 2025-11-29 at 06 46 00 Screenshot 2025-11-29 at 06 46 29

Summary by CodeRabbit

  • New Features

    • Cat management web app with responsive UI to view/add cats, plus REST API endpoints protected by API-key and login-based auth
    • App bootstrapped as a Spring Boot service with DB migrations and dev data initializer
  • Documentation

    • API usage examples added for cat endpoints
  • Tests

    • New unit and integration tests validating API and application behavior
  • Chores

    • Docker Compose and workspace settings added; .gitignore updated

✏️ Tip: You can customize this high-level summary in your review settings.

@kikoDevv kikoDevv self-assigned this Nov 29, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 29, 2025

Walkthrough

Project converted from a simple Java template into a Spring Boot web application: adds Spring Boot parent POM, JPA entities and repositories for Cat/Food, REST and MVC controllers, security (API-key + form login), Flyway migrations, Docker Compose configs, Thymeleaf UI, dev data initializer, and new tests.

Changes

Cohort / File(s) Summary
Build & IDE
\.gitignore, .vscode/settings.json, pom.xml
Added ignore for exercise2025.iml; added VSCode Java settings; replaced generic POM with Spring Boot parent POM, swapped dependencies to Spring Boot starters (web, data-jpa, security, validation, flyway, mysql), removed many classic Maven plugins in favor of spring-boot-maven-plugin, updated project coordinates and metadata.
Docker & Deployment
docker-compose.yml, deploy/docker-compose.yml
Added MySQL service (image mysql:9.5.0) with env vars and port mapping; deploy compose adds spring-boot service image exercise2025:0.0.1-SNAPSHOT mapping port 8080 and passing DB credentials.
Database Migrations
src/main/resources/db/migration/V1__Initial.sql, V2__food.sql, V3__favorites.sql
Added Flyway migrations: create cat table (id, name, age, created_at), food table (id, name), and cat_favorites join table with FK constraints.
Application Configuration
src/main/resources/application.properties, src/main/resources/application-dev.properties
Added datasource config (MySQL URL, env-based credentials), Flyway locations, app name, virtual threads; dev profile enables SQL logging, formatted SQL, Thymeleaf cache disabled, and security DEBUG.
Domain Entities
src/main/java/org/example/entities/Cat.java, .../Food.java
Added JPA entities Cat and Food with IDs, relationships (Cat.favorites one-to-many), constructors, getters/setters, and proxy-aware equals/hashCode.
Repositories
src/main/java/org/example/CatRepository.java, .../FoodRepository.java
Added CatRepository (extends ListCrudRepository) with custom queries: findCatByName, JPQL findBy(name), findCatsAndFood (fetch join), findCatsBy with @EntityGraph; added FoodRepository as JpaRepository.
REST API & DTO
src/main/java/org/example/CatController.java, src/main/java/org/example/Cat.java
Added REST controller exposing GET /api/cats, GET /api/cats/{name}, POST /api/cats with validation and role check (API); added Cat record DTO with @NotBlank and @Min constraints and List<Food> field.
Web MVC & Templates
src/main/java/org/example/HomeController.java, src/main/resources/templates/index.html, login.html
Added MVC controller for /, /login, and POST /cats; added Thymeleaf templates: index (cat list, add form, age slider) and login page.
Security & Filters
src/main/java/org/example/config/SecurityConfig.java, src/main/java/org/example/filters/ApiKeyFilter.java
New security config with two SecurityFilterChain beans (API paths using ApiKeyFilter, web form login), in-memory UserDetailsService, password encoder, custom AuthenticationManager; ApiKeyFilter authenticates requests with X-API-KEY.
Bootstrap & Dev Init
src/main/java/org/example/Exercise2025Application.java, src/main/java/org/example/config/DevDataInitializer.java, .../JavaMigrationsFlywayCustomizer.java
Added Spring Boot application entry point; dev-only DevDataInitializer populates sample Food and Cat data on startup; Flyway customizer file present but commented out/stubbed.
HTTP Snippets
cats.http
Added API request examples for GET/POST /api/cats including X-API-KEY header and sample JSON payload.
Tests & Test Resources
src/test/java/org/example/CatControllerTest.java, Exercise2025ApplicationTest.java, src/test/resources/org/example/cats.sql
Added unit tests for CatController (API key auth cases) and integration test using Testcontainers MySQL + TestRestTemplate validating /api/cats; added SQL fixture inserting ("Misse",10).
Removed / Deleted
src/main/java/org/example/App.java, src/test/java/org/example/AppTest.java, src/test/java/org/example/AppIT.java
Removed original template application entry and simple placeholder tests.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ApiKeyFilter
    participant SecurityConfig
    participant CatController
    participant CatRepository
    participant Database

    Client->>ApiKeyFilter: Request /api/cats (X-API-KEY)
    ApiKeyFilter->>SecurityConfig: validate key
    SecurityConfig-->>ApiKeyFilter: set Authentication (ROLE_API)
    ApiKeyFilter->>CatController: forward authenticated request
    CatController->>CatRepository: findCatsBy()
    CatRepository->>Database: SELECT ... (fetch/graph)
    Database-->>CatRepository: rows
    CatRepository-->>CatController: entities
    CatController-->>Client: 200 OK (DTOs)

    Client->>ApiKeyFilter: Request /api/cats (no key)
    ApiKeyFilter->>SecurityConfig: no auth
    SecurityConfig-->>Client: 403 Forbidden
Loading
sequenceDiagram
    participant User
    participant FormLogin
    participant SecurityConfig
    participant HomeController
    participant CatRepository
    participant Database

    User->>FormLogin: POST /login (username/password)
    FormLogin->>SecurityConfig: authenticate (in-memory)
    SecurityConfig-->>FormLogin: Authentication success
    FormLogin-->>User: Redirect /

    User->>HomeController: GET /
    HomeController->>CatRepository: findAll()
    CatRepository->>Database: SELECT * FROM cat
    Database-->>CatRepository: results
    CatRepository-->>HomeController: list
    HomeController-->>User: 200 OK (index.html)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus review areas:
    • pom.xml: dependency changes, Spring Boot parent/version and plugin configuration.
    • SecurityConfig & ApiKeyFilter: correct filter ordering, authentication correctness, and password encoding.
    • Entity mappings and equals/hashCode implementations (proxy handling and relationship mapping).
    • Flyway migrations and join table FK constraints for correctness with JPA mapping.
    • Tests: Testcontainers setup, @Sql resource path, and API key header usage.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kikoDevv kikoDevv linked an issue Nov 29, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (15)
src/test/resources/org/example/cats.sql (1)

1-2: Prefer single quotes for string literals.

While MySQL accepts double quotes for string literals by default, single quotes are the SQL standard and more portable across databases.

Apply this diff:

-insert into cat (name, age)
-values ("Misse",10);
+insert into cat (name, age)
+values ('Misse', 10);
src/main/resources/db/migration/V2__food.sql (1)

3-3: Consider consistent ID types across tables.

The food table uses BIGINT for the id, while the cat table (V1__Initial.sql) uses INT. This inconsistency may complicate foreign key relationships and joins.

For consistency, consider using INT for both tables unless you expect more than ~2.1 billion records:

-    id   BIGINT AUTO_INCREMENT NOT NULL,
+    id   INT AUTO_INCREMENT NOT NULL,
cats.http (1)

1-17: Align POST example JSON with actual Cat DTO fields

The POST example only shows name and age, while the Cat DTO also exposes a foodList field and your POST test payload includes foodList: []. For clarity and to avoid confusion when clients mirror this file, consider either:

  • Adding foodList: [] to this example payload, or
  • Explicitly documenting that foodList is optional and defaults to null/empty on the server side.
src/main/resources/db/migration/V3__favorites.sql (1)

1-14: Verify cardinality: UNIQUE on favorites_id restricts favorites to a single cat

uc_cat_favorites_favorites UNIQUE (favorites_id) enforces that a given food.id can appear only once in cat_favorites. That models:

  • One cat → many favorites
  • One favorite (food) → at most one cat

If you intended a many‑to‑many relationship where multiple cats can share the same favorite food, this unique constraint will block that. In that case, consider:

-- Option A: Composite PK
ALTER TABLE cat_favorites
    ADD CONSTRAINT pk_cat_favorites PRIMARY KEY (cat_id, favorites_id);

-- and drop the single-column unique
ALTER TABLE cat_favorites
    DROP INDEX uc_cat_favorites_favorites;

or at least a composite UNIQUE (cat_id, favorites_id) instead of only favorites_id.

If one‑to‑many is intentional, it’s fine as is, but a primary key (single or composite) is still generally a good idea for this table.

src/main/java/org/example/config/JavaMigrationsFlywayCustomizer.java (1)

1-14: Remove or properly enable the commented‑out Flyway customizer

This class is completely commented out, so it has no effect but still shows up in the tree. To reduce noise:

  • Either delete the file until you actually need a FlywayConfigurationCustomizer, or
  • Uncomment it, add the correct package/imports, and include a brief comment/TODO describing what Java migrations you plan to register.
src/test/java/org/example/CatControllerTest.java (1)

20-69: Solid API‑key coverage; consider asserting response payload and repository interactions

These tests nicely exercise the security behavior around X-API-KEY for both GET and POST. To strengthen them further (optional):

  • For getCats_withApiKey_shouldReturnOk, also assert on the JSON body (e.g., cat name/age) to verify the controller’s mapping, not just the status.
  • For postCat_withApiKey_shouldReturnCreated, you could:
    • Assert that repository.save(...) was called with expected values, and/or
    • Assert response headers (e.g., Location) or body if you return one.

This would catch regressions in DTO/entity mapping and controller wiring, not only security.

src/main/resources/templates/login.html (1)

1-275: Add lang attribute for accessibility (and optional small UX polish)

The login template looks good and already includes several a11y touches (alerts, labels, ARIA, CSRF). Two small improvements:

  • Add a language attribute to <html> so screen readers know how to interpret the content, e.g.:
-<html xmlns:th="http://www.thymeleaf.org">
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
  • (Optional) The error text “Wrong credential, check example” could be slightly clearer for users, e.g. “Invalid username or password. See example accounts below.”
src/main/java/org/example/Cat.java (1)

1-13: Clarify Cat DTO vs entity naming and consider foodList nullability

Two design aspects worth revisiting:

  1. Naming collision
    This record org.example.Cat coexists with org.example.entities.Cat (the JPA entity). Sharing the simple name Cat across DTO and entity can easily lead to import mistakes and subtle bugs. Consider renaming the record to something like CatDto or CatView to make the roles explicit.

  2. foodList constraints
    foodList currently has no validation and can be null if omitted in JSON. If your controller or frontend assumes a non‑null list, you might:

    • Add @jakarta.validation.constraints.NotNull to foodList, and/or
    • Normalize null to List.of() in the mapping layer.

Align this with how CatController and templates actually use the list.

src/main/java/org/example/filters/ApiKeyFilter.java (1)

36-40: Path matching may miss /api without trailing slash.

The check !request.getRequestURI().startsWith("/api/") will skip filtering for a request to /api (without trailing slash). If any endpoint is mapped directly at /api, it won't be processed by this filter.

Consider adjusting the condition to handle both cases:

     protected boolean shouldNotFilter(HttpServletRequest request) {
         // Only apply this filter to /api/** paths
-        return !request.getRequestURI().startsWith("/api/");
+        String uri = request.getRequestURI();
+        return !uri.startsWith("/api/") && !uri.equals("/api");
     }
src/main/java/org/example/config/DevDataInitializer.java (1)

44-44: Use logger instead of System.out.println.

A logger is already defined in this class. Replace the debug print statement with a log call for consistency.

-            System.out.println("Food 1 id= " + food1.getId());
+            log.debug("Food 1 id= {}", food1.getId());
src/main/java/org/example/HomeController.java (1)

31-36: Missing input validation for cat creation.

The name parameter could be empty/blank, and age could be negative. While the form has required attribute, server-side validation is still recommended for robustness.

Consider adding basic validation:

+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
+
     @PostMapping("/cats")
-    public String addCat(@RequestParam String name, @RequestParam int age) {
+    public String addCat(@RequestParam @NotBlank String name, 
+                         @RequestParam @Min(0) int age) {
         Cat cat = new Cat(name, age, java.util.List.of());
         repository.save(cat);
         return "redirect:/";
     }

Alternatively, use @Valid with a form-backing object for more comprehensive validation.

src/main/java/org/example/entities/Food.java (2)

14-15: Field visibility inconsistency.

foodName has package-private access while id is private. For consistency and encapsulation, consider making foodName private as well.

     @Column(name = "name")
-    String foodName;
+    private String foodName;

10-12: ID type differs from Cat entity.

Food uses Long for id while Cat uses Integer. This inconsistency could cause confusion. Consider aligning the id types across entities.

Verify if this is intentional or if the types should be unified for consistency.

src/main/java/org/example/config/SecurityConfig.java (1)

77-94: Minor: return UserDetails as principal instead of username + encoded password

authenticationManager2 currently returns a UsernamePasswordAuthenticationToken with the username as principal and the encoded password as credentials. It’s more idiomatic (and avoids carrying even hashed passwords in the Authentication) to return the UserDetails as principal and set credentials to null once authenticated:

-            if (passwordEncoder.matches(rawPassword, user.getPassword())) {
-                return new UsernamePasswordAuthenticationToken(
-                        username, user.getPassword(), user.getAuthorities());
-            }
+            if (passwordEncoder.matches(rawPassword, user.getPassword())) {
+                return new UsernamePasswordAuthenticationToken(
+                        user, null, user.getAuthorities());
+            }

The in-memory users with hard-coded passwords are fine for this training repo. Based on learnings, this is acceptable here.

src/main/java/org/example/entities/Cat.java (1)

29-47: Verify favorites join-table mapping matches Flyway migration

The unidirectional @OneToMany on favorites without an explicit @JoinTable lets Hibernate generate the join-table name and column names by convention. Since you already have a Flyway migration creating a cat_favorites table, it’s worth double-checking that Hibernate’s conventions line up with that DDL; if not, you should add an explicit @JoinTable so the mapping and schema stay in sync.

Optionally, you could also make name, age, createdAt, and favorites private for consistency with Food.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8618163 and caada9b.

📒 Files selected for processing (31)
  • .gitignore (1 hunks)
  • .vscode/settings.json (1 hunks)
  • cats.http (1 hunks)
  • deploy/docker-compose.yml (1 hunks)
  • docker-compose.yml (1 hunks)
  • pom.xml (1 hunks)
  • src/main/java/org/example/App.java (0 hunks)
  • src/main/java/org/example/Cat.java (1 hunks)
  • src/main/java/org/example/CatController.java (1 hunks)
  • src/main/java/org/example/CatRepository.java (1 hunks)
  • src/main/java/org/example/Exercise2025Application.java (1 hunks)
  • src/main/java/org/example/FoodRepository.java (1 hunks)
  • src/main/java/org/example/HomeController.java (1 hunks)
  • src/main/java/org/example/config/DevDataInitializer.java (1 hunks)
  • src/main/java/org/example/config/JavaMigrationsFlywayCustomizer.java (1 hunks)
  • src/main/java/org/example/config/SecurityConfig.java (1 hunks)
  • src/main/java/org/example/entities/Cat.java (1 hunks)
  • src/main/java/org/example/entities/Food.java (1 hunks)
  • src/main/java/org/example/filters/ApiKeyFilter.java (1 hunks)
  • src/main/resources/application-dev.properties (1 hunks)
  • src/main/resources/application.properties (1 hunks)
  • src/main/resources/db/migration/V1__Initial.sql (1 hunks)
  • src/main/resources/db/migration/V2__food.sql (1 hunks)
  • src/main/resources/db/migration/V3__favorites.sql (1 hunks)
  • src/main/resources/templates/index.html (1 hunks)
  • src/main/resources/templates/login.html (1 hunks)
  • src/test/java/org/example/AppIT.java (0 hunks)
  • src/test/java/org/example/AppTest.java (0 hunks)
  • src/test/java/org/example/CatControllerTest.java (1 hunks)
  • src/test/java/org/example/Exercise2025ApplicationTest.java (1 hunks)
  • src/test/resources/org/example/cats.sql (1 hunks)
💤 Files with no reviewable changes (3)
  • src/test/java/org/example/AppTest.java
  • src/main/java/org/example/App.java
  • src/test/java/org/example/AppIT.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-16T13:56:11.263Z
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.

Applied to files:

  • src/main/java/org/example/Exercise2025Application.java
  • src/main/resources/application.properties
  • src/test/java/org/example/Exercise2025ApplicationTest.java
  • .gitignore
  • pom.xml
📚 Learning: 2025-11-21T16:16:54.793Z
Learnt from: LolloGro
Repo: fungover/exercise2025 PR: 211
File: src/main/resources/templates/listOfBooks.html:11-12
Timestamp: 2025-11-21T16:16:54.793Z
Learning: In the repository fungover/exercise2025, the Author DTO uses NotEmpty validation on firstName and lastName fields, and BookDto uses NotNull validation on the author field. This validation architecture ensures that books always have complete author information, making null-safety checks in Thymeleaf templates unnecessary.

Applied to files:

  • pom.xml
🧬 Code graph analysis (2)
src/main/java/org/example/entities/Cat.java (1)
src/main/java/org/example/entities/Food.java (1)
  • Entity (8-55)
src/main/java/org/example/entities/Food.java (1)
src/main/java/org/example/entities/Cat.java (1)
  • Entity (13-97)
🪛 GitHub Actions: .github/workflows/ci.yml
src/test/java/org/example/Exercise2025ApplicationTest.java

[error] 47-47: Test failed: contextLoads - Expecting ArrayList to contain ["Misse"] but was [] (extracted: name).

pom.xml

[error] Command failed: mvn -B --no-transfer-progress test. There are test failures (1 of 5 tests failed) and the build finished with a non-zero exit code.

🔇 Additional comments (17)
.gitignore (1)

3-3: LGTM!

Adding IntelliJ IDEA module files to .gitignore is standard practice.

.vscode/settings.json (1)

1-4: LGTM!

The VSCode Java settings are appropriate for development. Interactive build configuration and automatic null analysis will help catch issues early.

src/main/resources/db/migration/V1__Initial.sql (1)

1-8: LGTM!

The cat table schema is well-structured with appropriate constraints and data types.

docker-compose.yml (1)

1-10: LGTM!

The MySQL service configuration is appropriate for local development. The credentials align with the defaults in application.properties, and exposing port 3306 facilitates local database access.

Based on learnings, hard-coded credentials are acceptable for this exercise project.

src/main/java/org/example/FoodRepository.java (1)

1-7: LGTM!

The FoodRepository interface follows Spring Data JPA conventions correctly, with the Long type parameter matching the BIGINT id column in the food table.

src/main/resources/application.properties (1)

1-6: LGTM!

The application configuration is well-structured:

  • Virtual threads enabled for better concurrency performance.
  • Datasource configuration uses environment variables with sensible defaults that align with docker-compose.yml.
  • The datasource URL uses the Docker service name "mysql", which correctly leverages Docker networking.

Based on learnings, hard-coded credential defaults are acceptable for this exercise project.

src/main/resources/application-dev.properties (1)

1-8: Dev profile settings look appropriate; just ensure profile scoping

These properties (Docker lifecycle, SQL logging, security DEBUG, disabled Thymeleaf cache) are well-suited for development and debugging. Just confirm that:

  • application-dev.properties is only activated via the dev profile, and
  • No equivalent DEBUG / no-cache settings leak into application-prod or default properties.
deploy/docker-compose.yml (1)

1-17: mysql:9.5.0 is a valid, currently available image tag on Docker Hub

The Docker image mysql:9.5.0 was released on October 22, 2025, and is available on the official Docker Hub repository. The suggested concern that docker-compose up will fail due to an invalid image tag is incorrect.

Since this is clearly a dev setup, hard‑coded credentials are acceptable, but ensure they're not reused in any non‑dev environment.

src/main/java/org/example/filters/ApiKeyFilter.java (1)

23-34: Filter continues chain regardless of authentication outcome.

The filter always calls filterChain.doFilter() even when the API key is missing or invalid. This is correct if downstream security configuration (e.g., SecurityConfig) enforces access control for /api/** endpoints. Just ensure the security filter chain properly denies unauthenticated requests.

src/main/java/org/example/Exercise2025Application.java (1)

6-11: LGTM!

Standard Spring Boot application entry point with correct structure.

src/main/java/org/example/config/DevDataInitializer.java (1)

34-48: force-init may create duplicate data.

When force-init is passed but the repository is not empty, data will be added without clearing existing entries, potentially causing duplicates or constraint violations.

Consider whether force-init should first clear existing data, or document this behavior clearly.

src/main/java/org/example/HomeController.java (1)

19-24: LGTM!

Clean implementation for listing cats with proper model binding for the Thymeleaf template.

src/main/resources/templates/index.html (1)

319-319: LGTM on CSRF protection.

Using th:action="@{/cats}" ensures Spring Security's CSRF token is automatically included in the form when CSRF protection is enabled for web routes.

src/main/java/org/example/CatController.java (1)

21-27: LGTM on secured endpoint with proper DTO mapping.

The getAll endpoint correctly uses @PreAuthorize for role-based access and maps entities to DTOs, avoiding direct entity exposure.

src/main/java/org/example/entities/Food.java (1)

40-54: LGTM on proxy-safe equals/hashCode implementation.

The implementation correctly handles Hibernate proxies and follows the recommended pattern for JPA entities using identifier-based equality.

pom.xml (1)

29-105: POM looks consistent; verify java.version against your JDKs

The Spring Boot parent and the chosen dependencies line up well with the new web/API/security stack and Testcontainers setup.

With <java.version>25</java.version>, just make sure your local and CI environments actually build with a JDK that supports --release 25; if they’re still on 21 or 17, you may want to lower this property to match the JDK that’s actually installed. If CI is green once the test issue is fixed, you’re fine to keep it as-is.

src/test/java/org/example/Exercise2025ApplicationTest.java (1)

21-48: I'll help you verify the review comment. Let me start by exploring the codebase to validate the concerns raised.
<function_calls>

Find relevant files for verification

#!/bin/bash

Find the repository and related files

find . -type f -name ".java" | grep -E "(CatRepository|Exercise2025Application)" | head -20
find . -type f -name "
.sql" | head -20


</function_calls>
<function_calls>

Check test file and locate key components

#!/bin/bash

List Java test files to understand structure

find . -type f -path "/test/" -name "*.java" | head -20


</function_calls>

Comment thread src/main/java/org/example/CatController.java
Comment thread src/main/java/org/example/CatRepository.java
Comment thread src/main/resources/templates/index.html
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/org/example/CatController.java (1)

39-47: Consider extracting a small mapper to reduce duplication

createCat repeats the same entity↔API mapping pattern used in the GET methods (new Cat(...) / new org.example.entities.Cat(...)). To keep things DRY and easier to change later, consider introducing small private helpers like toApiCat(entity) and toEntity(cat) and reusing them across all three endpoints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between caada9b and c918d4a.

📒 Files selected for processing (3)
  • src/main/java/org/example/CatController.java (1 hunks)
  • src/main/java/org/example/CatRepository.java (1 hunks)
  • src/main/resources/templates/index.html (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/example/CatRepository.java
  • src/main/resources/templates/index.html
🔇 Additional comments (1)
src/main/java/org/example/CatController.java (1)

22-37: GET endpoints: security and 404 handling look solid

Both /api/cats and /api/cats/{name} are properly protected with @PreAuthorize("hasRole('API')"), and the not-found case now returns a clear 404 via ResponseStatusException, which addresses the earlier concern about leaking a 500 on missing cats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exercise 8 - Spring Boot

2 participants