Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/main/java/org/example/alfs/entities/Ticket.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/*
Representing a whistleblower report.
Expand All @@ -28,8 +29,8 @@ public class Ticket {
@Column(nullable = false, length = 255)
private String title;

@Lob
@Basic(fetch = FetchType.LAZY)
@Column(nullable = false, columnDefinition="TEXT")
private String description;

@Enumerated(EnumType.STRING)
Expand All @@ -46,19 +47,24 @@ public class Ticket {
@PrePersist
public void prePersist() {
createdAt = LocalDateTime.now();
if (status == null) {
status = TicketStatus.OPEN;
}
if (status == null) status = TicketStatus.OPEN;
if (reporterToken == null || reporterToken.isBlank()) reporterToken = UUID.randomUUID().toString(); // Skapa token för anonyma anmälare
}

@PreUpdate
public void preUpdate() {
updatedAt = LocalDateTime.now();
}

@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
@OneToMany(mappedBy = "ticket")
private List<TicketComment> comments;

@OneToMany(mappedBy = "ticket")
private List<Attachment> attachments;

@OneToMany(mappedBy = "ticket")
private List<AuditLog> auditLogs;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reporter_id", nullable = true) // null if anonymous
private User reporter;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/org/example/alfs/entities/TicketComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public class TicketComment {
@GeneratedValue
private Long id;

@Column(nullable = false, length = 2000)
@Basic(fetch = FetchType.LAZY)
@Column(nullable = false, columnDefinition="TEXT")
private String message;

// Möjlighet att skriva internt meddelande (synligt för utredare/admin, inte för anmälare)
@Column(nullable = false)
private boolean isInternalNote = false;
Comment on lines +29 to +31

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
set -euo pipefail

# 1) Find migration/changelog files that mention this table/column
rg -n --iglob '*.{sql,xml,yml,yaml,json}' 'ticket_comment|is_internal_note|internal_note'

# 2) Inspect likely migration directories if present
fd -i 'migration|migrations|flyway|liquibase|changelog|db'

# 3) Confirm entity-side non-null declaration (for context)
rg -n 'isInternalNote|@Column\(nullable = false\)' src/main/java

Repository: ithsjava25/project-backend-alfs

Length of output: 57


🏁 Script executed:

#!/bin/bash

# Search more broadly for migration infrastructure and configuration
echo "=== Checking for migration infrastructure ==="
fd -i 'pom\.xml|build\.gradle|application\.(yml|yaml|properties)' | head -20

echo -e "\n=== Looking for migration directories ==="
fd -type d -i 'migration|migrations|flyway|liquibase|changelog|db' | head -20

echo -e "\n=== Checking for any SQL files ==="
fd -type f -name '*.sql' | head -30

echo -e "\n=== Checking for Liquibase/Flyway XML/YAML changelogs ==="
fd -type f \( -name '*changelog*' -o -name '*migration*' \) | head -30

Repository: ithsjava25/project-backend-alfs

Length of output: 838


🏁 Script executed:

#!/bin/bash

# Verify the TicketComment entity file exists and inspect it
echo "=== Checking TicketComment entity file ==="
if [ -f "src/main/java/org/example/alfs/entities/TicketComment.java" ]; then
  echo "File exists. Checking for isInternalNote field:"
  grep -n "isInternalNote\|is_internal_note" src/main/java/org/example/alfs/entities/TicketComment.java || echo "Field not found in grep"
  echo -e "\nContext around line 28-30:"
  sed -n '25,35p' src/main/java/org/example/alfs/entities/TicketComment.java
else
  echo "File not found at expected path"
fi

Repository: ithsjava25/project-backend-alfs

Length of output: 569


🏁 Script executed:

#!/bin/bash

echo "=== Checking pom.xml for migration dependencies ==="
grep -i 'flyway\|liquibase\|migration' pom.xml | head -20

echo -e "\n=== Checking application.properties for migration config ==="
cat src/main/resources/application.properties

Repository: ithsjava25/project-backend-alfs

Length of output: 246


🏁 Script executed:

#!/bin/bash

echo "=== Checking for src/main/resources/db directory ==="
if [ -d "src/main/resources/db" ]; then
  echo "Directory exists. Contents:"
  find src/main/resources/db -type f | head -30
else
  echo "No src/main/resources/db directory found"
fi

echo -e "\n=== Checking for any migration-related files across entire repo ==="
find . -type f \( -name '*.sql' -o -name '*migration*' -o -name '*changelog*' \) 2>/dev/null | grep -v node_modules | head -30

Repository: ithsjava25/project-backend-alfs

Length of output: 237


Add/verify DB migration for new non-null column.

The new non-null field isInternalNote at line 30 requires a database migration on existing environments. Currently, the repository has no migration infrastructure (no Flyway, Liquibase, or migration files detected), and no migration for this column exists. This will fail on deployment against databases with historical rows. Either establish migration infrastructure and add a migration that backfills is_internal_note with a default value before enforcing the non-null constraint, or adjust the column definition.

🤖 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/TicketComment.java` around lines 28 -
30, The new non-null field isInternalNote in class TicketComment is being added
with `@Column`(nullable = false) but there is no DB migration to backfill existing
rows, which will cause deployment failures; fix by either 1) adding migration
tooling (e.g., Flyway/Liquibase) and creating a migration that adds the
is_internal_note column (or alters it) with a safe default for all existing rows
and then sets NOT NULL, or 2) relax the Entity definition temporarily by
changing `@Column`(nullable = false) to nullable = true (or add a DB default) so
existing databases won’t fail, then introduce a migration later to backfill and
enforce non-null; locate the change in the TicketComment class and ensure
migration targets the is_internal_note column and uses the same boolean mapping
your JPA provider expects.


private LocalDateTime createdAt;

@PrePersist
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example.alfs.repositories;

import org.example.alfs.entities.Attachment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface AttachmentRepository extends JpaRepository<Attachment, Long> {

// Hämta alla bilagor i ett fall
List<Attachment> findByTicketId(Long ticketId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example.alfs.repositories;

import org.example.alfs.entities.AuditLog;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface AuditLogRepository extends JpaRepository<AuditLog, Long> {

// Hämta logghistoriken i ett fall, nyast först
List<AuditLog> findByTicketIdOrderByCreatedAtDesc(Long ticketId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.example.alfs.repositories;

import org.example.alfs.entities.TicketComment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface TicketCommentRepository extends JpaRepository<TicketComment, Long> {

// Ladda alla kommentarer i ett fall, äldst först
List<TicketComment> findByTicketIdOrderByCreatedAtAsc(Long ticketId);

// Ladda interna meddelanden för utredare/admins, äldst först
List<TicketComment> findByTicketIdAndIsInternalNoteOrderByCreatedAtAsc(Long ticketId, boolean isInternalNote);
}
32 changes: 32 additions & 0 deletions src/main/java/org/example/alfs/repositories/TicketRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.example.alfs.repositories;

import org.example.alfs.entities.Ticket;
import org.example.alfs.enums.TicketStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface TicketRepository extends JpaRepository<Ticket, Long> {

// Anonym anmälare ser sitt fall med token
Optional<Ticket> findByReporterToken(String reporterToken);

// Inloggad anmälare ser sitt/sina fall
List<Ticket> findByReporterId(Long reporterId);

// Utredare ser sina tilldelade fall
List<Ticket> findByInvestigatorId(Long investigatorId);

// Filtrera fall efter status
List<Ticket> findByStatus(TicketStatus status);

// Filtrera fall efter status och utredare
List<Ticket> findByStatusAndInvestigatorId(TicketStatus status, Long investigatorId);

// Hämta alla fall, paginerat
Page<Ticket> findAll(Pageable pageable);

}
10 changes: 10 additions & 0 deletions src/main/java/org/example/alfs/repositories/UserRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.example.alfs.repositories;

import org.example.alfs.entities.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {

}
Loading