Skip to content

Refactor user package structure and add DTOs#30

Open
apaegs wants to merge 10 commits intomainfrom
feature/dtos
Open

Refactor user package structure and add DTOs#30
apaegs wants to merge 10 commits intomainfrom
feature/dtos

Conversation

@apaegs
Copy link
Copy Markdown
Contributor

@apaegs apaegs commented Apr 6, 2026

Summary by CodeRabbit

  • Refactor

    • Reorganized user and case packages and tightened constructor/field visibility to improve wiring and imports; removed obsolete/duplicate user types.
  • New Features

    • Added DTOs for users, cases, comments, and uploaded files.
    • Introduced mappers and service wiring to convert between domain entities and DTOs for consistent API responses.
  • Tests

    • Added unit tests covering mapper conversions and mapping behaviors.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

Restructures package names from org.example.untitled.Userorg.example.untitled.user, removes two legacy placeholder classes, and adds DTOs, mappers, repository/service annotations, constructor injection, and unit tests for mapping logic.

Changes

Cohort / File(s) Summary
Removed placeholders
src/main/java/org/example/untitled/User/Mapper/UserMapper.java, src/main/java/org/example/untitled/User/service/UserService.java
Deleted legacy placeholder UserMapper and stub UserService.
Package renames (User domain)
src/main/java/org/example/untitled/user/User.java, src/main/java/org/example/untitled/user/Role.java
Changed package declarations from org.example.untitled.Userorg.example.untitled.user.
User API & wiring
src/main/java/org/example/untitled/user/controller/UserController.java, src/main/java/org/example/untitled/user/service/UserService.java, src/main/java/org/example/untitled/user/repository/UserRepository.java
Controller constructor made public and userService set to private final; added new @Service UserService with constructor injection of UserRepository and UserMapper; updated repository package/imports.
User mapper & DTO
src/main/java/org/example/untitled/user/mapper/UserMapper.java, src/main/java/org/example/untitled/user/dto/UserDto.java
Added Spring @Component UserMapper with toDto/toEntity methods and a new UserDto class with fields, constructors, getters/setters.
Case DTOs & mapper
src/main/java/org/example/untitled/usercase/dto/CaseEntityDto.java, src/main/java/org/example/untitled/usercase/dto/CommentDto.java, src/main/java/org/example/untitled/usercase/dto/UploadedFileDto.java, src/main/java/org/example/untitled/usercase/mapper/CaseMapper.java
Added DTOs and CaseMapper @Component with toDto conversions, including conditional mapping of related users and case IDs.
Case service & repo annotations
src/main/java/org/example/untitled/usercase/repository/CaseRepository.java, src/main/java/org/example/untitled/usercase/service/CaseService.java
Added @Repository to CaseRepository and @Service to CaseService; added constructor injection and private final dependencies for CaseService.
Updated imports in case entities
src/main/java/org/example/untitled/usercase/AuditLog.java, src/main/java/org/example/untitled/usercase/CaseEntity.java, src/main/java/org/example/untitled/usercase/Comment.java, src/main/java/org/example/untitled/usercase/UploadedFile.java
Updated imports to reference org.example.untitled.user.User (lowercase package).
Tests
src/test/java/org/example/untitled/user/mapper/UserMapperTest.java, src/test/java/org/example/untitled/usercase/mapper/CaseMapperTest.java
Added unit tests for UserMapper.toEntity and CaseMapper.toDto behaviors.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Controller as UserController
    participant Service as UserService
    participant Mapper as UserMapper
    participant Repo as UserRepository
    participant DB as Database

    Client->>Controller: HTTP request (user operation)
    Controller->>Service: invoke service method
    Service->>Repo: query or persist User
    Repo->>DB: CRUD operation
    Service->>Mapper: convert entity <-> dto
    Mapper-->>Service: DTO/entity
    Service-->>Controller: return DTO/result
    Controller-->>Client: HTTP response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • created basic structure.  #28: Refactors/relocates user types into org.example.untitled.user, overlapping with removal/replacement of placeholder UserMapper and UserService.

Suggested reviewers

  • Xeutos

Poem

🐰 I hopped from User to user with care,
Mappers stitched fields with deft little paws,
Services lined up, repos found their lair,
Tests peered in corners, checking mapping laws,
A carrot-coded cheer — tidy burrow applause 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: refactoring the user package structure (moving from User/Mapper/Repository/service to user/mapper/repository/service) and adding DTOs (UserDto, CaseEntityDto, CommentDto, UploadedFileDto).

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/dtos

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 (1)
src/main/java/org/example/untitled/usercase/mapper/CaseMapper.java (1)

22-29: Optional: cache nested relations to reduce repeated dereferences.

This slightly improves readability and avoids repeated getter calls on Lines 22/23/24, 26/27/28, 39/40/41, 43/44, and 55/56/57, 59/60.

♻️ Proposed refactor
-        if (entity.getOwner() != null) {
-            dto.setOwnerId(entity.getOwner().getId());
-            dto.setOwnerUsername(entity.getOwner().getUsername());
+        var owner = entity.getOwner();
+        if (owner != null) {
+            dto.setOwnerId(owner.getId());
+            dto.setOwnerUsername(owner.getUsername());
         }
-        if (entity.getAssignedTo() != null) {
-            dto.setAssignedToId(entity.getAssignedTo().getId());
-            dto.setAssignedToUsername(entity.getAssignedTo().getUsername());
+        var assignedTo = entity.getAssignedTo();
+        if (assignedTo != null) {
+            dto.setAssignedToId(assignedTo.getId());
+            dto.setAssignedToUsername(assignedTo.getUsername());
         }
@@
-        if (comment.getAuthor() != null) {
-            dto.setAuthorId(comment.getAuthor().getId());
-            dto.setAuthorUsername(comment.getAuthor().getUsername());
+        var author = comment.getAuthor();
+        if (author != null) {
+            dto.setAuthorId(author.getId());
+            dto.setAuthorUsername(author.getUsername());
         }
-        if (comment.getCaseEntity() != null) {
-            dto.setCaseId(comment.getCaseEntity().getId());
+        var caseEntity = comment.getCaseEntity();
+        if (caseEntity != null) {
+            dto.setCaseId(caseEntity.getId());
         }
@@
-        if (file.getUploadedBy() != null) {
-            dto.setUploadedById(file.getUploadedBy().getId());
-            dto.setUploadedByUsername(file.getUploadedBy().getUsername());
+        var uploadedBy = file.getUploadedBy();
+        if (uploadedBy != null) {
+            dto.setUploadedById(uploadedBy.getId());
+            dto.setUploadedByUsername(uploadedBy.getUsername());
         }
-        if (file.getAssociatedCase() != null) {
-            dto.setCaseId(file.getAssociatedCase().getId());
+        var associatedCase = file.getAssociatedCase();
+        if (associatedCase != null) {
+            dto.setCaseId(associatedCase.getId());
         }

Also applies to: 39-45, 55-60

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

In `@src/main/java/org/example/untitled/usercase/mapper/CaseMapper.java` around
lines 22 - 29, In CaseMapper, avoid repeated dereferences by caching nested
relation results into local variables: e.g., replace repeated entity.getOwner()
and entity.getAssignedTo() calls with local variables like Owner owner =
entity.getOwner(); and User assigned = entity.getAssignedTo(); then use
owner.getId()/owner.getUsername() and assigned.getId()/assigned.getUsername() to
call dto.setOwnerId, dto.setOwnerUsername, dto.setAssignedToId,
dto.setAssignedToUsername; apply the same pattern to the other similar blocks
referenced (lines 39-45 and 55-60) so each nested relation is retrieved once and
reused for setting DTO fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/org/example/untitled/user/mapper/UserMapper.java`:
- Around line 24-27: Update the mapping to avoid mass-assigning
client-controlled fields: modify UserMapper.toEntity (and any mapper methods
that call user.setId(...) or user.setRole(...)) to only map safe fields (e.g.,
username, email) and stop copying id/role from UserDto; introduce separate
request DTOs like CreateUserRequest and UpdateUserRequest that do not include id
or role, and ensure UserService assigns/overwrites id and role server-side after
authorization checks.

---

Nitpick comments:
In `@src/main/java/org/example/untitled/usercase/mapper/CaseMapper.java`:
- Around line 22-29: In CaseMapper, avoid repeated dereferences by caching
nested relation results into local variables: e.g., replace repeated
entity.getOwner() and entity.getAssignedTo() calls with local variables like
Owner owner = entity.getOwner(); and User assigned = entity.getAssignedTo();
then use owner.getId()/owner.getUsername() and
assigned.getId()/assigned.getUsername() to call dto.setOwnerId,
dto.setOwnerUsername, dto.setAssignedToId, dto.setAssignedToUsername; apply the
same pattern to the other similar blocks referenced (lines 39-45 and 55-60) so
each nested relation is retrieved once and reused for setting DTO fields.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8df40cb7-610d-4f6b-bea6-b26d5b248749

📥 Commits

Reviewing files that changed from the base of the PR and between 6402afa and 32ccbd4.

📒 Files selected for processing (19)
  • src/main/java/org/example/untitled/User/Mapper/UserMapper.java
  • src/main/java/org/example/untitled/User/service/UserService.java
  • src/main/java/org/example/untitled/user/Role.java
  • src/main/java/org/example/untitled/user/User.java
  • src/main/java/org/example/untitled/user/controller/UserController.java
  • src/main/java/org/example/untitled/user/dto/UserDto.java
  • src/main/java/org/example/untitled/user/mapper/UserMapper.java
  • src/main/java/org/example/untitled/user/repository/UserRepository.java
  • src/main/java/org/example/untitled/user/service/UserService.java
  • src/main/java/org/example/untitled/usercase/AuditLog.java
  • src/main/java/org/example/untitled/usercase/CaseEntity.java
  • src/main/java/org/example/untitled/usercase/Comment.java
  • src/main/java/org/example/untitled/usercase/UploadedFile.java
  • src/main/java/org/example/untitled/usercase/dto/CaseEntityDto.java
  • src/main/java/org/example/untitled/usercase/dto/CommentDto.java
  • src/main/java/org/example/untitled/usercase/dto/UploadedFileDto.java
  • src/main/java/org/example/untitled/usercase/mapper/CaseMapper.java
  • src/main/java/org/example/untitled/usercase/repository/CaseRepository.java
  • src/main/java/org/example/untitled/usercase/service/CaseService.java
💤 Files with no reviewable changes (2)
  • src/main/java/org/example/untitled/User/Mapper/UserMapper.java
  • src/main/java/org/example/untitled/User/service/UserService.java

@apaegs apaegs linked an issue Apr 6, 2026 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.

🧹 Nitpick comments (1)
src/test/java/org/example/untitled/user/mapper/UserMapperTest.java (1)

21-40: Strengthen tests with positive mapping assertions to avoid false positives.

Right now, both tests only check nullability of excluded fields. A regressed mapper that returns an almost-empty User could still pass. Add assertions for mapped fields (username/email) and assertNotNull(user).

♻️ Proposed test hardening
@@
     void toEntity_shouldNotMapId() {
         UserDto dto = new UserDto();
         dto.setId(99L);
         dto.setUsername("alice");
+        dto.setEmail("alice@example.com");

         User user = userMapper.toEntity(dto);

+        assertNotNull(user);
         assertNull(user.getId());
+        assertEquals("alice", user.getUsername());
+        assertEquals("alice@example.com", user.getEmail());
     }
@@
     void toEntity_shouldNotMapRole() {
         UserDto dto = new UserDto();
         dto.setRole(Role.ADMIN);
         dto.setUsername("alice");
+        dto.setEmail("alice@example.com");

         User user = userMapper.toEntity(dto);

+        assertNotNull(user);
         assertNull(user.getRole());
+        assertEquals("alice", user.getUsername());
+        assertEquals("alice@example.com", user.getEmail());
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/example/untitled/user/mapper/UserMapperTest.java` around
lines 21 - 40, Update the two tests in UserMapperTest (toEntity_shouldNotMapId
and toEntity_shouldNotMapRole) to assert the mapped fields and non-null result:
after calling userMapper.toEntity(dto) assertNotNull(user) and assertEquals on
fields you expect mapped (e.g., assertEquals(dto.getUsername(),
user.getUsername()) and if you set dto.setEmail(...)
assertEquals(dto.getEmail(), user.getEmail())), while still keeping the existing
assertNull checks for id and role; this ensures userMapper.toEntity actually
maps intended properties rather than returning an empty object.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/test/java/org/example/untitled/user/mapper/UserMapperTest.java`:
- Around line 21-40: Update the two tests in UserMapperTest
(toEntity_shouldNotMapId and toEntity_shouldNotMapRole) to assert the mapped
fields and non-null result: after calling userMapper.toEntity(dto)
assertNotNull(user) and assertEquals on fields you expect mapped (e.g.,
assertEquals(dto.getUsername(), user.getUsername()) and if you set
dto.setEmail(...) assertEquals(dto.getEmail(), user.getEmail())), while still
keeping the existing assertNull checks for id and role; this ensures
userMapper.toEntity actually maps intended properties rather than returning an
empty object.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e18c2a98-5b23-4ee8-b3e0-094cc3fc5a40

📥 Commits

Reviewing files that changed from the base of the PR and between 4a93d66 and 8de49db.

📒 Files selected for processing (2)
  • src/test/java/org/example/untitled/user/mapper/UserMapperTest.java
  • src/test/java/org/example/untitled/usercase/mapper/CaseMapperTest.java
✅ Files skipped from review due to trivial changes (1)
  • src/test/java/org/example/untitled/usercase/mapper/CaseMapperTest.java

@apaegs apaegs linked an issue Apr 6, 2026 that may be closed by this pull request
@apaegs apaegs changed the title Feature/dtos Refactor user package structure and add DTOs Apr 6, 2026
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.

Create a Mapper class for translation between DTOs and Entities Create DTO for entities

1 participant