Skip to content

feat: Add Basic CRUD for Ratings#11

Merged
StoynovAngel merged 25 commits into
mainfrom
feat/basic-crud
Apr 9, 2026
Merged

feat: Add Basic CRUD for Ratings#11
StoynovAngel merged 25 commits into
mainfrom
feat/basic-crud

Conversation

@StoynovAngel
Copy link
Copy Markdown
Owner

@StoynovAngel StoynovAngel commented Apr 9, 2026

Summary by CodeRabbit

  • New Features
    • Added Ratings, Drivers, Orders, and Payments APIs (create, fetch, list).
  • Validation
    • Request DTOs validated (required fields, ranges, patterns, max lengths).
  • Behavior
    • New users default to Customer role; seed data updated to match.
  • Error Handling
    • Authorization failures return 403; malformed requests return 400; missing resources return 404.
  • Tests
    • Extensive unit and integration tests plus shared test utilities for new flows.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds new Order/Payment/Driver/Rating features: controllers, services, MapStruct mappers, DTOs, repositories; validation and role-based access on endpoints; test utilities plus extensive unit and integration tests; updates to Role/UserService authority handling, seed data, test properties, and global exception mappings.

Changes

Cohort / File(s) Summary
Rating feature
backend/src/main/java/.../rating/RatingController.java, backend/src/main/java/.../rating/RatingService.java, backend/src/main/java/.../rating/RatingRepository.java, backend/src/main/java/.../rating/RatingMapper.java, backend/src/main/java/.../rating/RatingRequestDTO.java, backend/src/main/java/.../rating/RatingResponseDTO.java
New rating controller, service, repository, MapStruct mapper, request/response DTOs, and validation; endpoints secured by roles; service uses OrderRepository for order existence checks.
Order feature
backend/src/main/java/.../order/OrderController.java, backend/src/main/java/.../order/OrderService.java, backend/src/main/java/.../order/OrderRepository.java, backend/src/main/java/.../order/OrderMapper.java, backend/src/main/java/.../order/OrderRequestDTO.java, backend/src/main/java/.../order/OrderResponseDTO.java
New order controller, service, repository, mapper, request/response DTOs; create/get/list flows with user/driver/vehicle lookups and role restrictions.
Payment feature
backend/src/main/java/.../payment/PaymentController.java, backend/src/main/java/.../payment/PaymentService.java, backend/src/main/java/.../payment/PaymentRepository.java, backend/src/main/java/.../payment/PaymentMapper.java, backend/src/main/java/.../payment/PaymentRequestDTO.java, backend/src/main/java/.../payment/PaymentResponseDTO.java
New payment controller, service, repository, mapper, request/response DTOs; create/get/list flows with order existence checks and role-based access.
Driver feature
backend/src/main/java/.../driver/DriverController.java, backend/src/main/java/.../driver/DriverService.java, backend/src/main/java/.../driver/DriverRepository.java, backend/src/main/java/.../driver/DriverMapper.java, backend/src/main/java/.../driver/DriverRequestDTO.java, backend/src/main/java/.../driver/DriverResponseDTO.java
New driver controller, service, repository, MapStruct mapper, request/response DTOs; endpoints for create/get/list with validation and role guards.
Mapping & DTOs (common patterns)
backend/src/main/java/.../...Mapper.java, backend/src/main/java/.../*RequestDTO.java, backend/src/main/java/.../*ResponseDTO.java
Multiple MapStruct mappers map nested entity IDs to flat DTO fields; request DTOs include Jakarta Bean Validation annotations; response DTOs use Lombok @Builder.
Tests & Test Utilities
backend/src/test/java/.../data/TestData.java, backend/src/test/java/.../rating/*, backend/src/test/java/.../order/*, backend/src/test/java/.../payment/*, backend/src/test/java/.../driver/*
Added TestData factory and JWT RequestPostProcessors; many new Mockito unit tests and MockMvc integration tests covering happy paths, auth/role scenarios, validation, and not-found cases.
Config & Seed
backend/src/test/resources/application-test.properties, backend/src/main/resources/data.sql
Test properties to disable SQL init and docker-compose for tests; seed data updated to use ROLE_CUSTOMER for specified users.
Auth/Role changes
backend/src/main/java/.../user/role/Role.java, backend/src/main/java/.../user/UserService.java
Role enum adds getAuthority() returning ROLE_...; UserService now uses Role.CUSTOMER.getAuthority() as default authority.
Exception handling
backend/src/main/java/.../exception/GlobalControllerExceptionHandler.java
Added handlers mapping AuthorizationDeniedException→403, HttpMessageNotReadableException→400, MethodArgumentTypeMismatchException→400, and NoResourceFoundException→404.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Controller as RatingController
  participant Service as RatingService
  participant OrderRepo as OrderRepository
  participant RatingRepo as RatingRepository
  participant RatingMapper as RatingMapper
  participant DB as Database

  Client->>Controller: POST /api/ratings (RatingRequestDTO)
  Controller->>Service: createRating(request)
  Service->>OrderRepo: findById(request.orderId)
  OrderRepo->>DB: SELECT order by id
  DB-->>OrderRepo: order row / empty
  alt order found
    OrderRepo-->>Service: Optional<OrderEntity>
    Service->>RatingMapper: toEntity(request)
    RatingMapper-->>Service: RatingEntity
    Service->>RatingRepo: save(ratingEntity with order)
    RatingRepo->>DB: INSERT rating
    DB-->>RatingRepo: saved rating row
    RatingRepo-->>Service: saved RatingEntity
    Service->>RatingMapper: toDTO(saved RatingEntity)
    RatingMapper-->>Service: RatingResponseDTO
    Service-->>Controller: Optional<RatingResponseDTO>
    Controller-->>Client: 201 Created + body
  else order missing
    OrderRepo-->>Service: Optional.empty
    Service-->>Controller: Optional.empty
    Controller-->>Client: 400 Bad Request
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Add entity layer #1 — Introduced domain entities (e.g., OrderEntity, RatingEntity, PaymentEntity, DriverEntity) that these new repositories, services, and mappers depend on.

Poem

🐰 I hopped through lines to wire each route,

Orders, payments, drivers, ratings — all set out,
Mappers stitched and tests in neat array,
Roles checked, seeds updated — hip hooray! 🌷

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'feat: Add Basic CRUD for Ratings' is partially related to the changeset. While it accurately describes the rating-specific changes (RatingController, RatingService, RatingRepository, DTOs, tests), the PR also introduces significant changes beyond ratings: OrderController, OrderService, OrderMapper, OrderRepository, OrderRequestDTO, OrderResponseDTO, DriverController, DriverService, DriverMapper, DriverRepository, DriverRequestDTO, DriverResponseDTO, PaymentController, PaymentService, PaymentMapper, PaymentRepository, PaymentRequestDTO, PaymentResponseDTO, exception handler updates, user authority changes, and comprehensive test suites for all three modules. The title does not reflect the substantial scope of order and payment functionality added alongside ratings. Revise the title to reflect the broader scope of changes. Consider 'feat: Add CRUD operations for Ratings, Orders, Drivers, and Payments' or break this into multiple focused PRs, each with a title matching its specific domain.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/basic-crud

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.

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: 1

🧹 Nitpick comments (4)
backend/src/main/java/com/angel/autonow/rating/RatingController.java (1)

19-23: Consider returning 404 when orderId does not exist on create.

For POST /api/ratings, mapping missing related order to 400 blurs client input errors vs missing server resource. Returning 404 Not Found improves API semantics.

♻️ Suggested adjustment
 	`@PostMapping`
 	public ResponseEntity<RatingResponseDTO> createRating(`@Valid` `@RequestBody` RatingRequestDTO request) {
 		return ratingService.createRating(request)
 				.map(rating -> ResponseEntity.status(HttpStatus.CREATED).body(rating))
-				.orElse(ResponseEntity.badRequest().build());
+				.orElse(ResponseEntity.notFound().build());
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/rating/RatingController.java` around
lines 19 - 23, The createRating controller currently maps any absent result from
ratingService.createRating(request) to 400, which hides "order not found" cases;
update the service (ratingService.createRating) to return a distinct outcome for
missing related order (e.g., Optional.empty() vs a specific error
enum/exception) or throw a dedicated NotFound exception when the provided
orderId doesn't exist, and change the controller method createRating in
RatingController to return ResponseEntity.status(HttpStatus.NOT_FOUND) when the
service indicates the order is missing while still returning 400 for other
client validation errors and 201 for success (keep using RatingRequestDTO and
RatingResponseDTO types).
backend/src/test/java/com/angel/autonow/data/TestData.java (1)

17-23: Make test user email configurable to avoid data collisions.

Using a single hardcoded email can fail tests that persist more than one user in the same DB state. Consider accepting an email parameter (or generating one) in the factory.

♻️ Suggested adjustment
+import java.util.UUID;
@@
-	public static UserEntity createUserEntity() {
+	public static UserEntity createUserEntity() {
+		return createUserEntity("test+" + UUID.randomUUID() + "@example.com");
+	}
+
+	public static UserEntity createUserEntity(String email) {
 		return UserEntity.builder()
-				.email("test@example.com")
+				.email(email)
 				.password("encodedPassword")
 				.authorities(Set.of("ROLE_USER"))
 				.build();
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/test/java/com/angel/autonow/data/TestData.java` around lines 17 -
23, The factory method createUserEntity currently returns a UserEntity with a
hardcoded email leading to test collisions; change the method signature to
accept a String email parameter (e.g., createUserEntity(String email)) and use
that value in UserEntity.builder().email(...), or add an overloaded
createUserEntity() that generates a unique email (e.g., using UUID) and
delegates to createUserEntity(email); update usages in tests to pass or accept
the generated email accordingly so each test can supply or receive a unique
address.
backend/src/main/java/com/angel/autonow/rating/RatingService.java (1)

19-31: Consider handling duplicate rating scenario.

The RatingEntity has a unique constraint on order_id (from RatingEntity.java:37-38). If a rating already exists for an order, save() will throw a DataIntegrityViolationException. Consider either:

  1. Checking for existing rating before save and returning an appropriate response
  2. Catching the exception and converting it to a meaningful error

Also, consider adding @Transactional to ensure atomicity of the read-then-write operation.

♻️ Suggested improvement
+import org.springframework.transaction.annotation.Transactional;
+
 `@Service`
 `@RequiredArgsConstructor`
 public class RatingService {
 
 	private final RatingRepository ratingRepository;
 	private final RatingMapper ratingMapper;
 	private final OrderRepository orderRepository;
 
+	`@Transactional`
 	public Optional<RatingResponseDTO> createRating(RatingRequestDTO request) {
 		Optional<OrderEntity> order = orderRepository.findById(request.orderId());
 
 		if (order.isEmpty()) {
 			return Optional.empty();
 		}
+
+		if (ratingRepository.findByOrderId(request.orderId()).isPresent()) {
+			return Optional.empty(); // Or throw a custom exception for duplicate rating
+		}
 
 		RatingEntity rating = ratingMapper.toEntity(request);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/rating/RatingService.java` around
lines 19 - 31, createRating currently reads the order then saves a new
RatingEntity which can violate the unique order_id constraint; before saving,
check for an existing rating via ratingRepository (e.g., findByOrderId or
findByOrder(order.get())) and return an appropriate Optional.empty() or a
domain-specific error DTO, or wrap the save in a try/catch that converts
DataIntegrityViolationException into a meaningful response; also annotate
createRating (or the service class) with `@Transactional` to make the
read-then-write atomic and use the ratingMapper, ratingRepository and
orderRepository symbols when locating code to modify.
backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java (1)

128-134: Consider returning 404 for "not found" scenarios.

The test expects 200 OK with an empty body when a rating is not found. From a REST API design perspective, returning 404 Not Found would be more semantically correct for resource retrieval when the resource doesn't exist. This would require updating both the controller and these tests.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java`
around lines 128 - 134, Update the controller to return 404 when a rating is not
found and update the integration test accordingly: change the RatingController
endpoint handler (the method handling GET /api/ratings/{id}, e.g.,
getRatingById) to return ResponseEntity.notFound() (or throw a
ResponseStatusException with HttpStatus.NOT_FOUND) when the service (e.g.,
ratingService.findById or repository lookup) yields no result, and then modify
the test RatingControllerIT.getRatingById_notFound_returnsOkEmpty to expect
status().isNotFound() (and no body) instead of status().isOk(); ensure any
helper/service methods used (ratingService.findById) are updated/mocked to
reflect the not-found behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/src/main/java/com/angel/autonow/rating/RatingController.java`:
- Around line 25-33: Change the endpoints to return 404 when the rating is
missing instead of 200 with a null body: update getRatingById and
getRatingByOrderId to return ResponseEntity.notFound() (or use
ResponseEntity.of(Optional)) when ratingService.getRatingById(id) /
ratingService.getRatingByOrderId(orderId) is empty, and return
ResponseEntity.ok(...) when present; reference the methods getRatingById,
getRatingByOrderId and the calls to ratingService.getRatingById(...) and
ratingService.getRatingByOrderId(...) to locate the changes.

---

Nitpick comments:
In `@backend/src/main/java/com/angel/autonow/rating/RatingController.java`:
- Around line 19-23: The createRating controller currently maps any absent
result from ratingService.createRating(request) to 400, which hides "order not
found" cases; update the service (ratingService.createRating) to return a
distinct outcome for missing related order (e.g., Optional.empty() vs a specific
error enum/exception) or throw a dedicated NotFound exception when the provided
orderId doesn't exist, and change the controller method createRating in
RatingController to return ResponseEntity.status(HttpStatus.NOT_FOUND) when the
service indicates the order is missing while still returning 400 for other
client validation errors and 201 for success (keep using RatingRequestDTO and
RatingResponseDTO types).

In `@backend/src/main/java/com/angel/autonow/rating/RatingService.java`:
- Around line 19-31: createRating currently reads the order then saves a new
RatingEntity which can violate the unique order_id constraint; before saving,
check for an existing rating via ratingRepository (e.g., findByOrderId or
findByOrder(order.get())) and return an appropriate Optional.empty() or a
domain-specific error DTO, or wrap the save in a try/catch that converts
DataIntegrityViolationException into a meaningful response; also annotate
createRating (or the service class) with `@Transactional` to make the
read-then-write atomic and use the ratingMapper, ratingRepository and
orderRepository symbols when locating code to modify.

In `@backend/src/test/java/com/angel/autonow/data/TestData.java`:
- Around line 17-23: The factory method createUserEntity currently returns a
UserEntity with a hardcoded email leading to test collisions; change the method
signature to accept a String email parameter (e.g., createUserEntity(String
email)) and use that value in UserEntity.builder().email(...), or add an
overloaded createUserEntity() that generates a unique email (e.g., using UUID)
and delegates to createUserEntity(email); update usages in tests to pass or
accept the generated email accordingly so each test can supply or receive a
unique address.

In `@backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java`:
- Around line 128-134: Update the controller to return 404 when a rating is not
found and update the integration test accordingly: change the RatingController
endpoint handler (the method handling GET /api/ratings/{id}, e.g.,
getRatingById) to return ResponseEntity.notFound() (or throw a
ResponseStatusException with HttpStatus.NOT_FOUND) when the service (e.g.,
ratingService.findById or repository lookup) yields no result, and then modify
the test RatingControllerIT.getRatingById_notFound_returnsOkEmpty to expect
status().isNotFound() (and no body) instead of status().isOk(); ensure any
helper/service methods used (ratingService.findById) are updated/mocked to
reflect the not-found behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 11d9043f-6c16-419a-908c-35bfbf2c79cf

📥 Commits

Reviewing files that changed from the base of the PR and between 1a03fa9 and 4b661ef.

📒 Files selected for processing (11)
  • backend/src/main/java/com/angel/autonow/order/OrderRepository.java
  • backend/src/main/java/com/angel/autonow/rating/RatingController.java
  • backend/src/main/java/com/angel/autonow/rating/RatingMapper.java
  • backend/src/main/java/com/angel/autonow/rating/RatingRepository.java
  • backend/src/main/java/com/angel/autonow/rating/RatingRequestDTO.java
  • backend/src/main/java/com/angel/autonow/rating/RatingResponseDTO.java
  • backend/src/main/java/com/angel/autonow/rating/RatingService.java
  • backend/src/test/java/com/angel/autonow/data/TestData.java
  • backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java
  • backend/src/test/java/com/angel/autonow/rating/RatingServiceTest.java
  • backend/src/test/resources/application-test.properties

@StoynovAngel StoynovAngel changed the title feat: Add Basic CRUD for rating feat: Add Basic CRUD Apr 9, 2026
@StoynovAngel StoynovAngel changed the title feat: Add Basic CRUD feat: Add Basic CRUD for Ratings Apr 9, 2026
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: 5

🧹 Nitpick comments (7)
backend/src/main/java/com/angel/autonow/payment/PaymentResponseDTO.java (1)

11-11: Consider using BigDecimal for monetary amounts instead of Double.

Double can introduce floating-point precision errors in financial calculations (e.g., 0.1 + 0.2 ≠ 0.3). For payment amounts, BigDecimal is the standard practice to ensure accurate representation and avoid rounding issues in display or downstream calculations.

If the underlying PaymentEntity also uses Double, this would need to be addressed there as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentResponseDTO.java` at
line 11, PaymentResponseDTO currently declares the monetary field as Double
(amount) which can cause precision errors; change the type of the amount field
in PaymentResponseDTO to java.math.BigDecimal (and update any getters/setters,
constructors, builder methods, and equals/hashCode that reference amount) and
ensure JSON serialization/deserialization is handled (e.g., Jackson will map
BigDecimal automatically or add appropriate annotations if custom formatting is
needed); if PaymentEntity or other layers still use Double, update those
corresponding fields and conversion logic to use BigDecimal as well to keep
types consistent across mapping methods (e.g., any fromEntity/toDto converters).
backend/src/main/java/com/angel/autonow/exception/GlobalControllerExceptionHandler.java (1)

103-107: Inconsistent logging: NoResourceFoundException handler omits the log statement.

All other exception handlers in this class log the exception before returning the ProblemDetail. This handler is missing the log.warn() call, which creates an inconsistency. If this is intentional (e.g., to reduce noise from 404s), consider adding a brief comment explaining why.

♻️ Suggested fix for consistency
 `@ResponseStatus`(HttpStatus.NOT_FOUND)
 `@ExceptionHandler`(NoResourceFoundException.class)
 public ProblemDetail handleNoResourceFoundException(NoResourceFoundException e) {
+	log.warn(e.getMessage(), HttpStatus.NOT_FOUND, e);
 	return handle(e, HttpStatus.NOT_FOUND);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/com/angel/autonow/exception/GlobalControllerExceptionHandler.java`
around lines 103 - 107, The NoResourceFoundException handler
handleNoResourceFoundException currently returns a ProblemDetail without
logging, causing inconsistency with other handlers; update
handleNoResourceFoundException to call log.warn(...) (including the exception
and a brief message) before returning handle(e, HttpStatus.NOT_FOUND) to match
the pattern used by the other exception handlers, or if 404 noise suppression is
intentional, add a short explanatory comment above the method mentioning that
logging is intentionally omitted.
backend/src/main/java/com/angel/autonow/payment/PaymentRequestDTO.java (1)

11-13: Same concern: consider BigDecimal for monetary amounts.

Consistent with the note on PaymentResponseDTO, using BigDecimal would prevent floating-point precision issues when clients submit payment amounts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentRequestDTO.java`
around lines 11 - 13, Change the amount field in PaymentRequestDTO from Double
to BigDecimal to avoid floating‑point precision issues: update the declaration
in class PaymentRequestDTO (field "amount") to use java.math.BigDecimal, adjust
imports, and ensure validation annotations are compatible (keep `@NotNull` and
replace or keep `@Positive/`@DecimalMin as appropriate for BigDecimal); also
update any constructors, getters/setters, and JSON (de)serialization code that
consume or produce this field so callers and Jackson map BigDecimal correctly.
backend/src/test/java/com/angel/autonow/driver/DriverServiceTest.java (1)

30-56: Consider verifying mock interactions.

The test validates the return value but doesn't verify that the mapper and repository were called with expected arguments. Adding verify() calls would strengthen the test.

♻️ Suggested improvement
 		assertTrue(result.isPresent());
 		assertEquals(1L, result.get().id());
 		assertEquals("Michael", result.get().firstName());
+
+		verify(driverMapper).toEntity(request);
+		verify(driverRepository).save(entity);
+		verify(driverMapper).toDTO(saved);
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/test/java/com/angel/autonow/driver/DriverServiceTest.java` around
lines 30 - 56, The test createDriver_returnDriverResponse in DriverServiceTest
should also assert mock interactions: after calling
driverService.createDriver(request) add verify(driverMapper).toEntity(request),
verify(driverRepository).save(entity), and verify(driverMapper).toDTO(saved) to
ensure the mapper and repository were invoked with the expected arguments;
optionally add verifyNoMoreInteractions(driverMapper, driverRepository) to catch
unexpected calls.
backend/src/main/java/com/angel/autonow/order/OrderController.java (1)

24-30: Consider distinguishing error types in createOrder response.

Returning 400 Bad Request when createOrder returns empty is ambiguous—it could indicate the referenced user/driver/vehicle doesn't exist, not just a validation error. Consider throwing a specific exception (e.g., EntityNotFoundException) that maps to 404 for missing references, or 422 Unprocessable Entity for business rule violations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/order/OrderController.java` around
lines 24 - 30, The controller currently treats any empty Optional from
orderService.createOrder(request) as a 400; instead have the service surface
specific failures (e.g., throw EntityNotFoundException when referenced
User/Driver/Vehicle is missing, or a BusinessRuleException for domain
violations) and update OrderController.createOrder to let those exceptions
propagate (or catch and rethrow as ResponseStatusException), and add global
handlers (or `@ExceptionHandler` methods / a `@ControllerAdvice`) that map
EntityNotFoundException -> 404 NOT_FOUND and BusinessRuleException -> 422
UNPROCESSABLE_ENTITY so callers get precise status codes rather than a generic
400; key symbols: OrderController.createOrder, orderService.createOrder,
EntityNotFoundException, BusinessRuleException, and your global exception
handler class or `@ExceptionHandler` methods.
backend/src/main/java/com/angel/autonow/order/OrderRequestDTO.java (1)

23-36: Consider adding range validation for coordinates.

Latitude must be between -90 and 90, longitude between -180 and 180. Invalid coordinates could cause issues with mapping services or distance calculations.

♻️ Suggested improvement
+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.DecimalMin;
+
 		`@NotNull`(message = "Pickup latitude is required")
+		`@DecimalMin`(value = "-90.0", message = "Latitude must be >= -90")
+		`@DecimalMax`(value = "90.0", message = "Latitude must be <= 90")
 		Double pickupLatitude,
 
 		`@NotNull`(message = "Pickup longitude is required")
+		`@DecimalMin`(value = "-180.0", message = "Longitude must be >= -180")
+		`@DecimalMax`(value = "180.0", message = "Longitude must be <= 180")
 		Double pickupLongitude,

Apply similar constraints to dropoffLatitude and dropoffLongitude.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/order/OrderRequestDTO.java` around
lines 23 - 36, Add range validation to the coordinate fields in OrderRequestDTO:
annotate pickupLatitude and dropoffLatitude with `@DecimalMin`(value = "-90") and
`@DecimalMax`(value = "90"), and annotate pickupLongitude and dropoffLongitude
with `@DecimalMin`(value = "-180") and `@DecimalMax`(value = "180"); ensure you
import javax.validation.constraints.DecimalMin and DecimalMax (or the project's
equivalent) so invalid lat/lon outside the allowed ranges are rejected during
validation.
backend/src/test/java/com/angel/autonow/order/OrderServiceTest.java (1)

83-112: Add a negative-path test for invalid driverId/vehicleId.

Please add a case where IDs are provided but repositories return empty, then assert createOrder fails (or behaves as explicitly intended). This will lock down the edge-case contract.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/test/java/com/angel/autonow/order/OrderServiceTest.java` around
lines 83 - 112, Add negative-path tests in OrderServiceTest for missing
driver/vehicle: create new test(s) (e.g.,
createOrder_withMissingDriver_returnsEmpty and
createOrder_withMissingVehicle_returnsEmpty) that build an OrderRequestDTO like
the existing createOrder_withDriverAndVehicle, mock userRepository.findById(1L)
to return the user but mock driverRepository.findById(2L) (or
vehicleRepository.findById(3L)) to return Optional.empty(), call
orderService.createOrder(request) and assert the result is empty
(result.isPresent() == false); use the same test fixtures (OrderRequestDTO,
UserEntity, OrderEntity mapping mocks) and the existing repository/matcher
symbols (driverRepository, vehicleRepository, orderMapper, orderRepository) to
locate and implement the tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/src/main/java/com/angel/autonow/driver/DriverController.java`:
- Around line 34-41: The controller methods getDriverById and
getDriverByLicenseNumber currently return null when the Optional from
driverService (driverService.getDriverById /
driverService.getDriverByLicenseNumber) is empty; change these methods to return
a 404 instead of null by converting the return type to
ResponseEntity<DriverResponseDTO> (or throw new
ResponseStatusException(HttpStatus.NOT_FOUND)) and return
ResponseEntity.ok(body) when present or ResponseEntity.notFound().build() (or
throw the NOT_FOUND exception) when the Optional is empty so missing drivers
produce HTTP 404.

In `@backend/src/main/java/com/angel/autonow/order/OrderController.java`:
- Around line 32-36: The getOrderById controller currently returns null when
orderService.getOrderById(id) is empty; change OrderController.getOrderById to
return a 404 instead of null by detecting the Optional absence and either
throwing a ResponseStatusException(HttpStatus.NOT_FOUND, "...") or returning a
ResponseEntity.notFound().build(); locate the getOrderById method and replace
the .orElse(null) return with one of these patterns so missing orders yield HTTP
404.

In `@backend/src/main/java/com/angel/autonow/order/OrderService.java`:
- Around line 33-39: The code currently ignores unresolved driverId/vehicleId by
using findById(...).ifPresent(...), so if the client supplied an ID that doesn't
exist the order is created silently; change this to fail fast: when
request.driverId() != null use
driverRepository.findById(request.driverId()).orElseThrow(...) and set the
driver on the order (e.g., order.setDriver(foundDriver)), and similarly when
request.vehicleId() != null use
vehicleRepository.findById(request.vehicleId()).orElseThrow(...) and set the
vehicle; choose an appropriate exception type (e.g., IllegalArgumentException,
EntityNotFoundException, or your API BadRequest/NotFound exception) so the
controller returns an error instead of dropping the unresolved reference.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentController.java`:
- Around line 32-42: The controller currently returns null for missing payments
in PaymentController.getPaymentById and getPaymentByOrderId which yields 200;
change these methods to return ResponseEntity<PaymentResponseDTO> and map the
Optional results from paymentService.getPaymentById(id) and
paymentService.getPaymentByOrderId(orderId) to ResponseEntity.ok(...) when
present or ResponseEntity.notFound().build() when empty (or use
ResponseEntity.of(Optional)). Update method signatures and imports accordingly
so missing resources produce 404 Not Found.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentService.java`:
- Around line 19-31: The createPayment method in PaymentService must check for
an existing payment and run in a transaction: before mapping/saving, use
paymentRepository (e.g. existsByOrderId or findByOrder) to detect an existing
PaymentEntity for the given order and return an appropriate result (or throw a
DuplicatePaymentException) instead of relying on the DB unique constraint on
PaymentEntity.order; annotate the method (or the PaymentService class) with
`@Transactional` to ensure the find and save run in one transactional boundary,
and add a defensive catch for DataIntegrityViolationException around
paymentRepository.save(...) to translate DB errors into a clear
application-level error.

---

Nitpick comments:
In
`@backend/src/main/java/com/angel/autonow/exception/GlobalControllerExceptionHandler.java`:
- Around line 103-107: The NoResourceFoundException handler
handleNoResourceFoundException currently returns a ProblemDetail without
logging, causing inconsistency with other handlers; update
handleNoResourceFoundException to call log.warn(...) (including the exception
and a brief message) before returning handle(e, HttpStatus.NOT_FOUND) to match
the pattern used by the other exception handlers, or if 404 noise suppression is
intentional, add a short explanatory comment above the method mentioning that
logging is intentionally omitted.

In `@backend/src/main/java/com/angel/autonow/order/OrderController.java`:
- Around line 24-30: The controller currently treats any empty Optional from
orderService.createOrder(request) as a 400; instead have the service surface
specific failures (e.g., throw EntityNotFoundException when referenced
User/Driver/Vehicle is missing, or a BusinessRuleException for domain
violations) and update OrderController.createOrder to let those exceptions
propagate (or catch and rethrow as ResponseStatusException), and add global
handlers (or `@ExceptionHandler` methods / a `@ControllerAdvice`) that map
EntityNotFoundException -> 404 NOT_FOUND and BusinessRuleException -> 422
UNPROCESSABLE_ENTITY so callers get precise status codes rather than a generic
400; key symbols: OrderController.createOrder, orderService.createOrder,
EntityNotFoundException, BusinessRuleException, and your global exception
handler class or `@ExceptionHandler` methods.

In `@backend/src/main/java/com/angel/autonow/order/OrderRequestDTO.java`:
- Around line 23-36: Add range validation to the coordinate fields in
OrderRequestDTO: annotate pickupLatitude and dropoffLatitude with
`@DecimalMin`(value = "-90") and `@DecimalMax`(value = "90"), and annotate
pickupLongitude and dropoffLongitude with `@DecimalMin`(value = "-180") and
`@DecimalMax`(value = "180"); ensure you import
javax.validation.constraints.DecimalMin and DecimalMax (or the project's
equivalent) so invalid lat/lon outside the allowed ranges are rejected during
validation.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentRequestDTO.java`:
- Around line 11-13: Change the amount field in PaymentRequestDTO from Double to
BigDecimal to avoid floating‑point precision issues: update the declaration in
class PaymentRequestDTO (field "amount") to use java.math.BigDecimal, adjust
imports, and ensure validation annotations are compatible (keep `@NotNull` and
replace or keep `@Positive/`@DecimalMin as appropriate for BigDecimal); also
update any constructors, getters/setters, and JSON (de)serialization code that
consume or produce this field so callers and Jackson map BigDecimal correctly.

In `@backend/src/main/java/com/angel/autonow/payment/PaymentResponseDTO.java`:
- Line 11: PaymentResponseDTO currently declares the monetary field as Double
(amount) which can cause precision errors; change the type of the amount field
in PaymentResponseDTO to java.math.BigDecimal (and update any getters/setters,
constructors, builder methods, and equals/hashCode that reference amount) and
ensure JSON serialization/deserialization is handled (e.g., Jackson will map
BigDecimal automatically or add appropriate annotations if custom formatting is
needed); if PaymentEntity or other layers still use Double, update those
corresponding fields and conversion logic to use BigDecimal as well to keep
types consistent across mapping methods (e.g., any fromEntity/toDto converters).

In `@backend/src/test/java/com/angel/autonow/driver/DriverServiceTest.java`:
- Around line 30-56: The test createDriver_returnDriverResponse in
DriverServiceTest should also assert mock interactions: after calling
driverService.createDriver(request) add verify(driverMapper).toEntity(request),
verify(driverRepository).save(entity), and verify(driverMapper).toDTO(saved) to
ensure the mapper and repository were invoked with the expected arguments;
optionally add verifyNoMoreInteractions(driverMapper, driverRepository) to catch
unexpected calls.

In `@backend/src/test/java/com/angel/autonow/order/OrderServiceTest.java`:
- Around line 83-112: Add negative-path tests in OrderServiceTest for missing
driver/vehicle: create new test(s) (e.g.,
createOrder_withMissingDriver_returnsEmpty and
createOrder_withMissingVehicle_returnsEmpty) that build an OrderRequestDTO like
the existing createOrder_withDriverAndVehicle, mock userRepository.findById(1L)
to return the user but mock driverRepository.findById(2L) (or
vehicleRepository.findById(3L)) to return Optional.empty(), call
orderService.createOrder(request) and assert the result is empty
(result.isPresent() == false); use the same test fixtures (OrderRequestDTO,
UserEntity, OrderEntity mapping mocks) and the existing repository/matcher
symbols (driverRepository, vehicleRepository, orderMapper, orderRepository) to
locate and implement the tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 15bc7c9c-956b-46f7-a005-f3a730c97d4b

📥 Commits

Reviewing files that changed from the base of the PR and between 4c4b3fb and 6d92ae9.

📒 Files selected for processing (29)
  • backend/src/main/java/com/angel/autonow/driver/DriverController.java
  • backend/src/main/java/com/angel/autonow/driver/DriverMapper.java
  • backend/src/main/java/com/angel/autonow/driver/DriverRepository.java
  • backend/src/main/java/com/angel/autonow/driver/DriverRequestDTO.java
  • backend/src/main/java/com/angel/autonow/driver/DriverResponseDTO.java
  • backend/src/main/java/com/angel/autonow/driver/DriverService.java
  • backend/src/main/java/com/angel/autonow/exception/GlobalControllerExceptionHandler.java
  • backend/src/main/java/com/angel/autonow/order/OrderController.java
  • backend/src/main/java/com/angel/autonow/order/OrderMapper.java
  • backend/src/main/java/com/angel/autonow/order/OrderRepository.java
  • backend/src/main/java/com/angel/autonow/order/OrderRequestDTO.java
  • backend/src/main/java/com/angel/autonow/order/OrderResponseDTO.java
  • backend/src/main/java/com/angel/autonow/order/OrderService.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentController.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentMapper.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentRepository.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentRequestDTO.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentResponseDTO.java
  • backend/src/main/java/com/angel/autonow/payment/PaymentService.java
  • backend/src/main/java/com/angel/autonow/rating/RatingResponseDTO.java
  • backend/src/test/java/com/angel/autonow/data/TestData.java
  • backend/src/test/java/com/angel/autonow/driver/DriverControllerIT.java
  • backend/src/test/java/com/angel/autonow/driver/DriverServiceTest.java
  • backend/src/test/java/com/angel/autonow/order/OrderControllerIT.java
  • backend/src/test/java/com/angel/autonow/order/OrderServiceTest.java
  • backend/src/test/java/com/angel/autonow/payment/PaymentControllerIT.java
  • backend/src/test/java/com/angel/autonow/payment/PaymentServiceTest.java
  • backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java
  • backend/src/test/java/com/angel/autonow/rating/RatingServiceTest.java
✅ Files skipped from review due to trivial changes (1)
  • backend/src/main/java/com/angel/autonow/rating/RatingResponseDTO.java
🚧 Files skipped from review as they are similar to previous changes (4)
  • backend/src/main/java/com/angel/autonow/order/OrderRepository.java
  • backend/src/test/java/com/angel/autonow/rating/RatingControllerIT.java
  • backend/src/test/java/com/angel/autonow/rating/RatingServiceTest.java
  • backend/src/test/java/com/angel/autonow/data/TestData.java

Comment thread backend/src/main/java/com/angel/autonow/order/OrderController.java
Comment thread backend/src/main/java/com/angel/autonow/order/OrderService.java
Comment thread backend/src/main/java/com/angel/autonow/payment/PaymentService.java
@StoynovAngel StoynovAngel merged commit d6bf442 into main Apr 9, 2026
6 checks passed
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.

1 participant