Skip to content

Feature/entities#1

Merged
simonforsberg merged 14 commits intomainfrom
feature/entities
Mar 30, 2026
Merged

Feature/entities#1
simonforsberg merged 14 commits intomainfrom
feature/entities

Conversation

@FionaSprinkles
Copy link
Copy Markdown
Contributor

@FionaSprinkles FionaSprinkles commented Mar 27, 2026

Initial entity model

Adds core entities for the whistleblower ticket system:

  • Ticket
  • User
  • TicketComment
  • Attachment
  • AuditLog

Additional changes

  • Added Spring Data JPA dependency
  • Added README with small project description
  • Updated .gitignore and removed IntelliJ project files
  • Added placeholder .jte file for CI build

Summary by CodeRabbit

  • New Features

    • Established foundation for the whistleblower reporting system with support for anonymous ticket submission, secure file attachments, ticket comments, role-based access control, and comprehensive audit logging to track all system changes.
  • Documentation

    • Added project README describing the ALFS Whistleblower Ticket System features and audit capabilities.
  • Chores

    • Updated project configuration and dependencies for database integration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5f2b7af-0ed5-4bdd-b1f8-11c5ebbf1046

📥 Commits

Reviewing files that changed from the base of the PR and between 673f5cb and a213d26.

📒 Files selected for processing (5)
  • src/main/java/org/example/alfs/entities/Attachment.java
  • src/main/java/org/example/alfs/entities/AuditLog.java
  • src/main/java/org/example/alfs/entities/Ticket.java
  • src/main/java/org/example/alfs/entities/TicketComment.java
  • src/main/java/org/example/alfs/entities/User.java
✅ Files skipped from review due to trivial changes (2)
  • src/main/java/org/example/alfs/entities/Ticket.java
  • src/main/java/org/example/alfs/entities/User.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/java/org/example/alfs/entities/AuditLog.java
  • src/main/java/org/example/alfs/entities/Attachment.java
  • src/main/java/org/example/alfs/entities/TicketComment.java

📝 Walkthrough

Walkthrough

This pull request establishes the foundational data model and project infrastructure for an ALFS Whistleblower Ticket System. It removes IDE-specific configuration files, adds core JPA entities defining tickets, attachments, users, audit logs, and comments, and includes Maven dependency configuration and project documentation.

Changes

Cohort / File(s) Summary
IDE Configuration Cleanup
.idea/.gitignore, .idea/misc.xml, .idea/project-backend-alfs.iml, .idea/vcs.xml
Removed JetBrains IDE metadata and configuration files to exclude IDE-specific artifacts from version control.
Project Configuration
.gitignore, README.md, pom.xml
Updated .gitignore with environment and runtime exclusions; added Spring Data JPA dependency to pom.xml; created README.md with system overview and audit log example.
JPA Entity Definitions
src/main/java/org/example/alfs/entities/User.java, src/main/java/org/example/alfs/entities/Ticket.java, src/main/java/org/example/alfs/entities/Attachment.java, src/main/java/org/example/alfs/entities/TicketComment.java, src/main/java/org/example/alfs/entities/AuditLog.java
Added five new JPA entities with @PrePersist lifecycle callbacks to auto-set timestamps. Defined relationships: Ticket has one-to-many Attachments and TicketComments, and many-to-one User (assignedHandler); AuditLog associates with Ticket and User via many-to-one mappings.
Template Configuration
src/main/jte/placeholder.jte
Added placeholder JTE template file for CI test verification.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 New entities hop into the database today,
Tickets and attachments ready to stay!
Audit trails log every whistleblower's way,
With timestamps and relationships—hooray, hooray!
Clean IDE files shuffled away.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

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.
Title check ❓ Inconclusive The title 'Feature/entities' is vague and overly generic, using a branch-naming convention rather than a descriptive summary of the actual changes. Consider renaming to something more descriptive like 'Add initial JPA entities for whistleblower ticket system' to clearly convey the primary changes being introduced.
✅ 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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/entities

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

🧹 Nitpick comments (5)
src/main/java/org/example/alfs/entities/SystemUser.java (1)

23-26: Security consideration: Ensure passwords are hashed before persistence.

For a whistleblower system handling sensitive data, ensure the service layer hashes passwords (e.g., with BCrypt via Spring Security's PasswordEncoder) before saving. The entity field itself is fine, but plain-text storage would be a critical vulnerability.

Additionally, consider using an enum for role instead of String to prevent typos and provide compile-time safety.

💡 Optional: Use enum for role
public enum UserRole {
    ADMIN, INVESTIGATOR, VIEWER
}

// In SystemUser:
`@Enumerated`(EnumType.STRING)
private UserRole role;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/SystemUser.java` around lines 23 -
26, The SystemUser entity currently stores a plain-text password in the password
field and uses a String for role; before persisting, ensure passwords are hashed
using a PasswordEncoder (e.g., inject Spring Security's PasswordEncoder in the
service that saves SystemUser and call encoder.encode(password) in the
create/update methods) so the password field never stores raw text, and replace
the String role with a typed enum (e.g., UserRole) annotated with
`@Enumerated`(EnumType.STRING) in SystemUser to enforce compile-time role safety
and avoid typos.
src/main/java/org/example/alfs/entities/Ticket.java (2)

42-43: Field naming: attachment should be attachments.

The field is a List<Attachment> but named singular. For clarity and convention, use plural naming for collection fields.

Also consider adding cascade and orphanRemoval to manage the attachment lifecycle with the ticket.

💡 Proposed change
-    `@OneToMany`(mappedBy = "ticket")
-    private List<Attachment> attachment;
+    `@OneToMany`(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
+    private List<Attachment> attachments;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/Ticket.java` around lines 42 - 43,
Rename the Ticket entity's collection field from "attachment" to "attachments"
and update its accessor methods (getAttachment/getAttachments,
setAttachment/setAttachments or corresponding references) to match; modify the
`@OneToMany`( mappedBy = "ticket") declaration on the Ticket class to include
cascade = CascadeType.ALL and orphanRemoval = true so Attachment lifecycle
follows Ticket, and update any usages (constructors, DTO mappings, repository
queries, serialization) and the Attachment entity if it references the field
name to ensure all references compile.

32-34: Consider using an enum for status and securing reporterToken.

  • status as String allows arbitrary values. An enum (e.g., NEW, IN_PROGRESS, RESOLVED, CLOSED) provides type safety.
  • reporterToken is security-sensitive for anonymous access. Consider adding a unique constraint and ensuring it's generated securely (e.g., UUID or cryptographically random token).
💡 Example enum for status
public enum TicketStatus {
    NEW, IN_PROGRESS, UNDER_INVESTIGATION, RESOLVED, CLOSED
}

// In Ticket:
`@Enumerated`(EnumType.STRING)
private TicketStatus status;

`@Column`(unique = true)
private String reporterToken;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/Ticket.java` around lines 32 - 34,
Convert the loose String fields in the Ticket entity into safer, typed and
constrained fields: replace the String status with a TicketStatus enum (define
enum TicketStatus { NEW, IN_PROGRESS, UNDER_INVESTIGATION, RESOLVED, CLOSED }
and annotate the Ticket.status with `@Enumerated`(EnumType.STRING) to persist
names), and secure reporterToken by adding a uniqueness constraint (e.g.,
`@Column`(unique = true)) and ensure tokens are generated securely when creating
tickets (use UUID.randomUUID() or a cryptographically secure random token
generator in the Ticket factory/constructor or repository before persisting).
src/main/java/org/example/alfs/entities/AuditLog.java (1)

30-32: Consider column length constraints for audit value fields.

oldValue and newValue store arbitrary field values which could be lengthy (e.g., description changes). Without @Column(length=...), the default is typically 255 characters, which may truncate data.

💡 Proposed change
+    `@Column`(length = 4000)
     private String oldValue;
 
+    `@Column`(length = 4000)
     private String newValue;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/AuditLog.java` around lines 30 - 32,
AuditLog's String fields oldValue and newValue may be truncated by default
column length; update the AuditLog entity to annotate these fields (oldValue,
newValue) with an appropriate persistence mapping such as `@Column`(length = 2000)
or use `@Lob` (and optional `@Column`) if values can be very large, so the database
will store full values and avoid silent truncation; apply the annotation
directly to the oldValue and newValue fields in the AuditLog class and adjust
length based on expected max size or DB TEXT support.
src/main/java/org/example/alfs/entities/Attachment.java (1)

35-36: Consider specifying FetchType.LAZY for the relationship.

The @ManyToOne defaults to FetchType.EAGER, which loads the parent Ticket every time an Attachment is fetched. For performance, especially when querying many attachments, consider lazy loading.

💡 Proposed change
-    `@ManyToOne`
+    `@ManyToOne`(fetch = FetchType.LAZY)
     private Ticket ticket;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/Attachment.java` around lines 35 -
36, The Attachment entity's `@ManyToOne` relationship on the field ticket defaults
to EAGER fetching; change the annotation on the ticket field in class Attachment
to specify lazy loading (use `@ManyToOne`(fetch = FetchType.LAZY)) and add the
required FetchType import so the Ticket is not always loaded when an Attachment
is fetched.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Around line 1-4: The README has a heading level skip: the main title "# The
ALFS Whistleblower Ticket System" is followed by "### A secure case management
system built with Spring Boot for handling whistleblower reports." — change that
"###" to "##" so the secondary heading "A secure case management system built
with Spring Boot for handling whistleblower reports." becomes an H2 (use "##")
to maintain proper document structure and hierarchy.

In `@src/main/java/org/example/alfs/entities/TicketComment.java`:
- Line 28: TicketComment is missing a `@PrePersist` lifecycle callback to populate
the createdAt field; add a private method annotated with `@PrePersist` (e.g.,
prePersist or setCreatedAtIfNull) inside the TicketComment class that sets
createdAt = LocalDateTime.now() when createdAt is null so new TicketComment
instances get an automatic timestamp before being persisted.

---

Nitpick comments:
In `@src/main/java/org/example/alfs/entities/Attachment.java`:
- Around line 35-36: The Attachment entity's `@ManyToOne` relationship on the
field ticket defaults to EAGER fetching; change the annotation on the ticket
field in class Attachment to specify lazy loading (use `@ManyToOne`(fetch =
FetchType.LAZY)) and add the required FetchType import so the Ticket is not
always loaded when an Attachment is fetched.

In `@src/main/java/org/example/alfs/entities/AuditLog.java`:
- Around line 30-32: AuditLog's String fields oldValue and newValue may be
truncated by default column length; update the AuditLog entity to annotate these
fields (oldValue, newValue) with an appropriate persistence mapping such as
`@Column`(length = 2000) or use `@Lob` (and optional `@Column`) if values can be very
large, so the database will store full values and avoid silent truncation; apply
the annotation directly to the oldValue and newValue fields in the AuditLog
class and adjust length based on expected max size or DB TEXT support.

In `@src/main/java/org/example/alfs/entities/SystemUser.java`:
- Around line 23-26: The SystemUser entity currently stores a plain-text
password in the password field and uses a String for role; before persisting,
ensure passwords are hashed using a PasswordEncoder (e.g., inject Spring
Security's PasswordEncoder in the service that saves SystemUser and call
encoder.encode(password) in the create/update methods) so the password field
never stores raw text, and replace the String role with a typed enum (e.g.,
UserRole) annotated with `@Enumerated`(EnumType.STRING) in SystemUser to enforce
compile-time role safety and avoid typos.

In `@src/main/java/org/example/alfs/entities/Ticket.java`:
- Around line 42-43: Rename the Ticket entity's collection field from
"attachment" to "attachments" and update its accessor methods
(getAttachment/getAttachments, setAttachment/setAttachments or corresponding
references) to match; modify the `@OneToMany`( mappedBy = "ticket") declaration on
the Ticket class to include cascade = CascadeType.ALL and orphanRemoval = true
so Attachment lifecycle follows Ticket, and update any usages (constructors, DTO
mappings, repository queries, serialization) and the Attachment entity if it
references the field name to ensure all references compile.
- Around line 32-34: Convert the loose String fields in the Ticket entity into
safer, typed and constrained fields: replace the String status with a
TicketStatus enum (define enum TicketStatus { NEW, IN_PROGRESS,
UNDER_INVESTIGATION, RESOLVED, CLOSED } and annotate the Ticket.status with
`@Enumerated`(EnumType.STRING) to persist names), and secure reporterToken by
adding a uniqueness constraint (e.g., `@Column`(unique = true)) and ensure tokens
are generated securely when creating tickets (use UUID.randomUUID() or a
cryptographically secure random token generator in the Ticket
factory/constructor or repository before persisting).
🪄 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: fd4b52d8-8c64-48ca-bad3-4be46b38bc57

📥 Commits

Reviewing files that changed from the base of the PR and between d2e89f9 and fd03ed2.

📒 Files selected for processing (14)
  • .gitignore
  • .idea/.gitignore
  • .idea/misc.xml
  • .idea/modules.xml
  • .idea/project-backend-alfs.iml
  • .idea/vcs.xml
  • README.md
  • pom.xml
  • src/main/java/org/example/alfs/entities/Attachment.java
  • src/main/java/org/example/alfs/entities/AuditLog.java
  • src/main/java/org/example/alfs/entities/SystemUser.java
  • src/main/java/org/example/alfs/entities/Ticket.java
  • src/main/java/org/example/alfs/entities/TicketComment.java
  • src/main/jte/placeholder.jte
💤 Files with no reviewable changes (5)
  • .idea/vcs.xml
  • .idea/misc.xml
  • .idea/modules.xml
  • .idea/project-backend-alfs.iml
  • .idea/.gitignore

Comment on lines +1 to +4
# The ALFS Whistleblower Ticket System

### A secure case management system built with Spring Boot for handling whistleblower reports.
The system allows anonymous reporting, secure file uploads, role-based access control, and full audit logging.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Heading level skip detected.

Line 3 uses ### (h3) directly after # (h1), skipping h2. For proper document structure, consider using ## instead.

📝 Proposed fix
 # The ALFS Whistleblower Ticket System
 
-### A secure case management system built with Spring Boot for handling whistleblower reports.
+## A secure case management system built with Spring Boot for handling whistleblower reports.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# The ALFS Whistleblower Ticket System
### A secure case management system built with Spring Boot for handling whistleblower reports.
The system allows anonymous reporting, secure file uploads, role-based access control, and full audit logging.
# The ALFS Whistleblower Ticket System
## A secure case management system built with Spring Boot for handling whistleblower reports.
The system allows anonymous reporting, secure file uploads, role-based access control, and full audit logging.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)

[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

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

In `@README.md` around lines 1 - 4, The README has a heading level skip: the main
title "# The ALFS Whistleblower Ticket System" is followed by "### A secure case
management system built with Spring Boot for handling whistleblower reports." —
change that "###" to "##" so the secondary heading "A secure case management
system built with Spring Boot for handling whistleblower reports." becomes an H2
(use "##") to maintain proper document structure and hierarchy.

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 (3)
src/main/java/org/example/alfs/entities/Ticket.java (2)

42-43: Define attachment ownership semantics on the @OneToMany side.

If attachments are owned by tickets, add cascade and orphanRemoval to prevent orphaned rows and simplify lifecycle handling.

Suggested change
-    `@OneToMany`(mappedBy = "ticket")
-    private List<Attachment> attachment;
+    `@OneToMany`(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
+    private List<Attachment> attachments;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/Ticket.java` around lines 42 - 43,
The Ticket entity's OneToMany field attachment lacks ownership semantics so
orphaned Attachment rows can persist; update the `@OneToMany` on Ticket.attachment
to include appropriate cascade (e.g., CascadeType.ALL or at least
PERSIST/MERGE/REMOVE) and orphanRemoval = true, and ensure the mappedBy points
to the Attachment.ticket field so lifecycle operations on Ticket cascade and
remove orphaned Attachment entities.

34-34: Add constraints to reporterToken to ensure safe anonymous ticket tracking.

The class comment states that tickets "can be followed by the anonymous reporter by using the reporterToken," indicating this field is essential for anonymous access. To prevent ambiguous lookups and ensure data integrity, the field should be constrained as non-null, unique, and immutable.

Suggested change
-    private String reporterToken;
+    `@Column`(nullable = false, unique = true, length = 128, updatable = false)
+    private String reporterToken;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/Ticket.java` at line 34,
Ticket.reporterToken must be made non-null, unique and immutable: annotate the
field (reporterToken) with JPA constraints (e.g. `@Column`(nullable=false,
unique=true, updatable=false)) and/or Bean Validation (`@NotNull`, `@Size` as
needed), initialize it via the Ticket constructor and remove or avoid any setter
to make it immutable (or declare final and set only in constructor) so the value
cannot be changed after creation; update any constructors/factory methods that
create Ticket to supply a valid reporterToken and adjust persistence code
accordingly.
src/main/java/org/example/alfs/entities/AuditLog.java (1)

40-44: Use lazy loading and explicit join columns for audit relations.

The @ManyToOne fields default to eager loading, which unnecessarily fetches the related Ticket and User entities on every audit query. Add explicit lazy loading and join column mappings:

Suggested change
-    `@ManyToOne`
+    `@ManyToOne`(fetch = FetchType.LAZY)
+    `@JoinColumn`(name = "ticket_id")
     private Ticket ticket;

-    `@ManyToOne`
+    `@ManyToOne`(fetch = FetchType.LAZY)
+    `@JoinColumn`(name = "user_id")
     private User user;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/AuditLog.java` around lines 40 - 44,
The AuditLog entity's `@ManyToOne` associations (fields ticket and user) currently
use default eager loading and lack explicit join mappings; update the mappings
in AuditLog by adding fetch=FetchType.LAZY to both `@ManyToOne` annotations and
add explicit `@JoinColumn` annotations (e.g., name="ticket_id" for ticket and
name="user_id" for user) so JPA uses lazy loading and deterministic foreign-key
column names.
🤖 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/alfs/entities/Ticket.java`:
- Around line 19-43: The Ticket entity currently uses Lombok's `@Data` which
generates toString/equals/hashCode that will recurse over the bidirectional
relationship via the attachment field; replace `@Data` on class Ticket with
explicit Lombok annotations: use `@Getter` and `@Setter`, add `@ToString`(exclude =
"attachment") to avoid recursive toString, and add
`@EqualsAndHashCode`(onlyExplicitlyIncluded = true) with the id field marked as
the included identifier so equals/hashCode only use id. Also update the
`@OneToMany`(mappedBy = "ticket") on the attachment field to include cascade and
orphanRemoval (e.g., cascade = CascadeType.ALL, orphanRemoval = true) if
attachments should be removed with their ticket.

In `@src/main/java/org/example/alfs/entities/User.java`:
- Around line 23-24: In the User entity, rename the field password to
passwordHash and update its getter/setter names accordingly; annotate username
and passwordHash with JPA column constraints (e.g.,
`@Column`(name="password_hash", nullable=false, length=255) for passwordHash and
`@Column`(nullable=false, unique=true) for username) to enforce DB-level
constraints and make it explicit that persisted values are password hashes;
update any imports/usages referencing User.getPassword()/setPassword() to use
getPasswordHash()/setPasswordHash() so persistence and other code compile.
- Around line 14-26: Replace the class-level `@Data` on User with explicit Lombok
annotations to avoid exposing password and fragile JPA equality: remove `@Data`
and add `@Getter` and `@Setter`, keep `@NoArgsConstructor` and `@AllArgsConstructor`,
add `@ToString`(exclude = "password") to prevent password in logs, and add
`@EqualsAndHashCode`(onlyExplicitlyIncluded = true) while annotating the id field
with `@EqualsAndHashCode.Include` so equals/hashCode are based on the identifier
only; ensure the id field still has `@Id` and `@GeneratedValue` and leave password
as a regular field (not included in toString/equals/hashCode).

---

Nitpick comments:
In `@src/main/java/org/example/alfs/entities/AuditLog.java`:
- Around line 40-44: The AuditLog entity's `@ManyToOne` associations (fields
ticket and user) currently use default eager loading and lack explicit join
mappings; update the mappings in AuditLog by adding fetch=FetchType.LAZY to both
`@ManyToOne` annotations and add explicit `@JoinColumn` annotations (e.g.,
name="ticket_id" for ticket and name="user_id" for user) so JPA uses lazy
loading and deterministic foreign-key column names.

In `@src/main/java/org/example/alfs/entities/Ticket.java`:
- Around line 42-43: The Ticket entity's OneToMany field attachment lacks
ownership semantics so orphaned Attachment rows can persist; update the
`@OneToMany` on Ticket.attachment to include appropriate cascade (e.g.,
CascadeType.ALL or at least PERSIST/MERGE/REMOVE) and orphanRemoval = true, and
ensure the mappedBy points to the Attachment.ticket field so lifecycle
operations on Ticket cascade and remove orphaned Attachment entities.
- Line 34: Ticket.reporterToken must be made non-null, unique and immutable:
annotate the field (reporterToken) with JPA constraints (e.g.
`@Column`(nullable=false, unique=true, updatable=false)) and/or Bean Validation
(`@NotNull`, `@Size` as needed), initialize it via the Ticket constructor and remove
or avoid any setter to make it immutable (or declare final and set only in
constructor) so the value cannot be changed after creation; update any
constructors/factory methods that create Ticket to supply a valid reporterToken
and adjust persistence code accordingly.
🪄 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: 8a095f10-d5f3-4fc3-88e9-6c2c66ecd4f5

📥 Commits

Reviewing files that changed from the base of the PR and between fd03ed2 and 673f5cb.

📒 Files selected for processing (4)
  • src/main/java/org/example/alfs/entities/AuditLog.java
  • src/main/java/org/example/alfs/entities/Ticket.java
  • src/main/java/org/example/alfs/entities/TicketComment.java
  • src/main/java/org/example/alfs/entities/User.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/org/example/alfs/entities/TicketComment.java

Comment on lines +19 to +43
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Ticket {

@Id
@GeneratedValue
private Long id;

private String title;

private String description;

private String status;

private String reporterToken;

private LocalDateTime createdAt;
@PrePersist
public void prePersist() {
createdAt = LocalDateTime.now();
}

@OneToMany(mappedBy = "ticket")
private List<Attachment> attachment;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify entity classes combining `@Data` with relational mappings
rg -nP --type=java -C3 '@Entity|@Data|@OneToMany|@ManyToOne'

Repository: ithsjava25/project-backend-alfs

Length of output: 5992


🏁 Script executed:

cat -n src/main/java/org/example/alfs/entities/Attachment.java

Repository: ithsjava25/project-backend-alfs

Length of output: 993


🏁 Script executed:

cat -n src/main/java/org/example/alfs/entities/User.java

Repository: ithsjava25/project-backend-alfs

Length of output: 747


🏁 Script executed:

# Check if any relationship collections have cascade/orphanRemoval settings
rg -nP --type=java '@(OneToMany|OneToOne|ManyToMany)' -A1

Repository: ithsjava25/project-backend-alfs

Length of output: 261


🏁 Script executed:

rg -nP --type=java '@OneToOne' -B2 -A2

Repository: ithsjava25/project-backend-alfs

Length of output: 57


Avoid @Data on JPA entities with bidirectional relationships.

The TicketAttachment bidirectional association (Attachment.java:35) will cause toString(), equals(), and hashCode() generated by @Data to recurse infinitely: Ticket.toString()attachment.toString()ticket.toString() → etc. Additionally, equals() and hashCode() will traverse the entire attachment collection on every comparison.

Replace @Data with explicit @Getter, @Setter, and @ToString (excluding the collection), and configure @EqualsAndHashCode to use only the ID:

Suggested change
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
...
-@Data
+@Getter
+@Setter
+@ToString(exclude = "attachment")
+@EqualsAndHashCode(onlyExplicitlyIncluded = true)
 `@AllArgsConstructor`
 `@NoArgsConstructor`
 public class Ticket {

     `@Id`
     `@GeneratedValue`
+    `@EqualsAndHashCode.Include`
     private Long id;

Also consider adding cascade and orphan removal settings to @OneToMany if attachments should be deleted when their ticket is removed.

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

In `@src/main/java/org/example/alfs/entities/Ticket.java` around lines 19 - 43,
The Ticket entity currently uses Lombok's `@Data` which generates
toString/equals/hashCode that will recurse over the bidirectional relationship
via the attachment field; replace `@Data` on class Ticket with explicit Lombok
annotations: use `@Getter` and `@Setter`, add `@ToString`(exclude = "attachment") to
avoid recursive toString, and add `@EqualsAndHashCode`(onlyExplicitlyIncluded =
true) with the id field marked as the included identifier so equals/hashCode
only use id. Also update the `@OneToMany`(mappedBy = "ticket") on the attachment
field to include cascade and orphanRemoval (e.g., cascade = CascadeType.ALL,
orphanRemoval = true) if attachments should be removed with their ticket.

Comment on lines +14 to +26
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

@GeneratedValue
@Id
private Long id;

private String username;
private String password;

private String role;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify risky pattern usage across entities: `@Data` + password-like fields
rg -nP --type=java -C3 '@Entity|@Data|password|passwordHash'

Repository: ithsjava25/project-backend-alfs

Length of output: 4016


🏁 Script executed:

#!/bin/bash
# Search for password hashing patterns
rg -i 'bcrypt|passwordencoder|hash.*password|encode.*password' --type=java -A 2

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Check User entity usage in services
fd -e java -path '*/service*' -o -path '*/repository*' | head -20

Repository: ithsjava25/project-backend-alfs

Length of output: 243


🏁 Script executed:

#!/bin/bash
# Look for any password-related bean or security configuration
rg -i 'passwordencoder|bcryptpasswordencoder' --type=java -B 2 -A 2

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Find service and controller classes
find . -name '*Service.java' -o -name '*Controller.java' | head -20

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Search for password field being set or used
rg 'setPassword|\.password|password.*=' --type=java -B 2 -A 2

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Look for Spring Security configuration
rg -i 'spring.*security|authenticationmanager|configure.*http' --type=java -B 1 -A 3

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Check for any login/auth/register endpoints
rg -i 'login|register|authenticate' --type=java -B 1 -A 2

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash
# List the project structure
ls -la src/main/java/org/example/alfs/

Repository: ithsjava25/project-backend-alfs

Length of output: 309


🏁 Script executed:

#!/bin/bash
# Read the full User.java file
cat src/main/java/org/example/alfs/entities/User.java

Repository: ithsjava25/project-backend-alfs

Length of output: 551


🏁 Script executed:

#!/bin/bash
# Find all Java files and where they are
find . -name '*.java' -type f | head -30

Repository: ithsjava25/project-backend-alfs

Length of output: 468


Replace @Data on User entity to prevent password exposure in generated methods.

@Data generates toString(), equals(), and hashCode() across all fields, which will expose the plaintext password field in logs and create fragile identity behavior for JPA entities. Use selective annotations and exclude the password field from generated methods.

Suggested change
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;

 `@Entity`
 `@Table`(name="users")
-@Data
+@Getter
+@Setter
+@ToString(exclude = "password")
+@EqualsAndHashCode(onlyExplicitlyIncluded = true)
 `@AllArgsConstructor`
 `@NoArgsConstructor`
 public class User {

     `@GeneratedValue`
     `@Id`
+    `@EqualsAndHashCode.Include`
     private Long id;

     private String username;
+    `@ToString.Exclude`
     private String password;

     private String role;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/User.java` around lines 14 - 26,
Replace the class-level `@Data` on User with explicit Lombok annotations to avoid
exposing password and fragile JPA equality: remove `@Data` and add `@Getter` and
`@Setter`, keep `@NoArgsConstructor` and `@AllArgsConstructor`, add `@ToString`(exclude
= "password") to prevent password in logs, and add
`@EqualsAndHashCode`(onlyExplicitlyIncluded = true) while annotating the id field
with `@EqualsAndHashCode.Include` so equals/hashCode are based on the identifier
only; ensure the id field still has `@Id` and `@GeneratedValue` and leave password
as a regular field (not included in toString/equals/hashCode).

Comment on lines +23 to +24
private String username;
private String password;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether password hashing is enforced in write paths
rg -nP --type=java -C3 'PasswordEncoder|BCryptPasswordEncoder|setPassword\(|passwordHash'

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

cat -n src/main/java/org/example/alfs/entities/User.java

Repository: ithsjava25/project-backend-alfs

Length of output: 747


🏁 Script executed:

rg -n --type=java 'password|Password' src/main/java/org/example/alfs --ignore-case -C 2 | head -80

Repository: ithsjava25/project-backend-alfs

Length of output: 424


🏁 Script executed:

find src/main/java -name "*Service*.java" -o -name "*Controller*.java" -o -name "*Auth*.java" | head -10

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

find src/main/java -type f -name "*Service.java" -o -name "*Controller.java" | xargs ls -la

Repository: ithsjava25/project-backend-alfs

Length of output: 710


🏁 Script executed:

rg -n --type=java 'setPassword|password.*encode|encode.*password|BCrypt|passwordHash' src/main/java

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

rg -n --type=java 'class.*Service|class.*Controller' src/main/java | grep -i user

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

find src/main/java -type f -name "*.java" | sort

Repository: ithsjava25/project-backend-alfs

Length of output: 397


🏁 Script executed:

head -50 pom.xml

Repository: ithsjava25/project-backend-alfs

Length of output: 1794


🏁 Script executed:

rg -n --type=java 'encode|Encode|crypt|Crypt|hash|Hash|security|Security' src/main/java

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

cat -n src/main/java/org/example/alfs/AlfsApplication.java

Repository: ithsjava25/project-backend-alfs

Length of output: 482


🏁 Script executed:

cat -n pom.xml | tail -30

Repository: ithsjava25/project-backend-alfs

Length of output: 1545


🏁 Script executed:

rg -n 'password' src/main/java --ignore-case

Repository: ithsjava25/project-backend-alfs

Length of output: 156


Add JPA constraints and clarify password storage as hash.

The password field lacks database constraints and does not indicate hash storage. Rename to passwordHash and add explicit column constraints to ensure proper persistence:

Suggested change
-    private String password;
+    `@Column`(name = "password_hash", nullable = false, length = 255)
+    private String passwordHash;

This change establishes the contract that stored values are hashes before implementing the authentication service layer.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private String username;
private String password;
private String username;
`@Column`(name = "password_hash", nullable = false, length = 255)
private String passwordHash;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/entities/User.java` around lines 23 - 24, In
the User entity, rename the field password to passwordHash and update its
getter/setter names accordingly; annotate username and passwordHash with JPA
column constraints (e.g., `@Column`(name="password_hash", nullable=false,
length=255) for passwordHash and `@Column`(nullable=false, unique=true) for
username) to enforce DB-level constraints and make it explicit that persisted
values are password hashes; update any imports/usages referencing
User.getPassword()/setPassword() to use getPasswordHash()/setPasswordHash() so
persistence and other code compile.

@simonforsberg simonforsberg merged commit ab800a4 into main Mar 30, 2026
1 check failed
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.

2 participants