Skip to content

Feature/ut ctime#87

Merged
HerrKanin merged 4 commits into
mainfrom
feature/UTCtime
Apr 15, 2026
Merged

Feature/ut ctime#87
HerrKanin merged 4 commits into
mainfrom
feature/UTCtime

Conversation

@HerrKanin

@HerrKanin HerrKanin commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor

    • Upgraded timestamp handling across the application to use UTC-aware timestamps, improving consistency and precision across all system entities.
  • UI Updates

    • Enhanced date and time display formatting on dashboard and incident pages to include hour and minute information, providing more detailed timestamp visibility.

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request systematically migrates timestamp fields across the application from java.time.LocalDateTime to java.time.Instant, updates corresponding DTO and entity accessor/mutator signatures, adds a database migration to convert timestamp columns to TIMESTAMPTZ, and refactors HTML templates to use consistent client-side date formatting helpers.

Changes

Cohort / File(s) Summary
Entity & DTO Timestamp Refactoring
src/main/java/org/example/team6backend/activity/dto/ActivityLogResponse.java, src/main/java/org/example/team6backend/activity/entity/ActivityLog.java, src/main/java/org/example/team6backend/incident/entity/Incident.java, src/main/java/org/example/team6backend/incident/dto/IncidentResponse.java, src/main/java/org/example/team6backend/notification/entity/Notification.java, src/main/java/org/example/team6backend/notification/dto/NotificationResponse.java, src/main/java/org/example/team6backend/user/entity/AppUser.java, src/main/java/org/example/team6backend/user/dto/UserResponse.java
Changed createdAt and/or updatedAt field types from LocalDateTime to Instant across all entities and response DTOs. Updated corresponding getter/setter signatures and lifecycle callback methods to use Instant.now().
Comment Entity, DTO & Controller
src/main/java/org/example/team6backend/comment/entity/Comment.java, src/main/java/org/example/team6backend/comment/dto/CommentResponse.java, src/main/java/org/example/team6backend/comment/controller/CommentController.java
Added new CommentResponse DTO record with nested CommentUserResponse. Updated Comment entity's createdAt to Instant. Modified controller to return ResponseEntity<List<CommentResponse>> via fromEntity() mapping.
Exception Handling & Service Updates
src/main/java/org/example/team6backend/exception/ErrorResponse.java, src/main/java/org/example/team6backend/exception/GlobalExceptionHandler.java, src/main/java/org/example/team6backend/incident/service/IncidentService.java
Updated ErrorResponse timestamp field to Instant and constructor signature. Updated GlobalExceptionHandler to use Instant.now() across all exception handlers. Updated IncidentService to initialize and refresh timestamps using Instant.now().
Database Migration
src/main/resources/db/migration/V10__change_timestamp_to_timestampz.sql
New migration altering created_at columns on incident, comment, activity_log, and app_user tables, plus updated_at on app_user table to TIMESTAMPTZ with UTC timezone.
Template Date Formatting
src/main/resources/templates/admin.html, src/main/resources/templates/dashboard.html, src/main/resources/templates/incidents.html, src/main/resources/templates/profile.html, src/main/resources/templates/viewincident.html
Introduced consistent client-side formatDate() helper function across templates. Replaced inline date formatting (toLocaleDateString() or server-side #temporals) with calls to shared helper using toLocaleString("sv-SE") with year, month, day, hour, and minute options.
Test Updates
src/test/java/org/example/team6backend/user/service/UserServiceTest.java
Updated test helper createTestUser() to use Instant.now() instead of LocalDateTime.now() for timestamp initialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops of joy through time's great hall,
From LocalDateTime's fleeting call,
Instant moments, crisp and true,
UTC zones shine through and through!
Timestamps dance in every place,
A timezone-aware embrace!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.08% 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/ut ctime' is vague and unclear; 'ut ctime' does not convey meaningful information about the changeset without additional context. Rename the title to clearly describe the main change, such as 'Convert timestamp fields from LocalDateTime to Instant for UTC timezone support'.
✅ 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/UTCtime

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/org/example/team6backend/activity/dto/ActivityLogResponse.java (1)

19-19: ⚠️ Potential issue | 🟡 Minor

Typo: "Unknow user" should be "Unknown user".

✏️ Proposed fix
-		response.setUserName(activityLog.getUser() != null ? activityLog.getUser().getName() : "Unknow user");
+		response.setUserName(activityLog.getUser() != null ? activityLog.getUser().getName() : "Unknown user");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/team6backend/activity/dto/ActivityLogResponse.java`
at line 19, The response.setUserName call in ActivityLogResponse mapping uses
the misspelled fallback string "Unknow user"; update the fallback to "Unknown
user" in the ternary expression inside the method where
response.setUserName(...) is called (refer to ActivityLogResponse mapping and
activityLog.getUser()). Optionally, extract the fallback into a constant like
UNKNOWN_USER for reuse, but at minimum correct the string to "Unknown user".
🧹 Nitpick comments (4)
src/test/java/org/example/team6backend/user/service/UserServiceTest.java (1)

33-34: Use a single timestamp value in test fixtures for determinism.

Line 33 and Line 34 call Instant.now() separately, which can create micro-differences between createdAt and updatedAt in tests.

Proposed test fixture tweak
-		user.setCreatedAt(Instant.now());
-		user.setUpdatedAt(Instant.now());
+		Instant now = Instant.now();
+		user.setCreatedAt(now);
+		user.setUpdatedAt(now);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/example/team6backend/user/service/UserServiceTest.java`
around lines 33 - 34, In UserServiceTest, avoid calling Instant.now() twice for
createdAt/updatedAt; instead capture a single Instant (e.g., Instant now =
Instant.now()) and use that same variable in user.setCreatedAt(...) and
user.setUpdatedAt(...) so both timestamps are identical and deterministic for
assertions involving createdAt/updatedAt in the test fixtures.
src/main/resources/templates/incidents.html (1)

359-369: Guard against malformed timestamps in formatDate

Line 362 currently formats any non-empty string; malformed inputs can surface as "Invalid Date" in UI. Add a parse validity check and return "-" fallback.

💡 Suggested hardening
 function formatDate(dateString) {
     if (!dateString) return "-";
+    const parsed = new Date(dateString);
+    if (Number.isNaN(parsed.getTime())) return "-";
 
-    return new Date(dateString).toLocaleString("sv-SE", {
+    return parsed.toLocaleString("sv-SE", {
         year: "numeric",
         month: "2-digit",
         day: "2-digit",
         hour: "2-digit",
         minute: "2-digit"
     });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/templates/incidents.html` around lines 359 - 369, The
formatDate function accepts any non-empty string and can return "Invalid Date"
for malformed timestamps; update formatDate to parse the input into a Date
object (e.g., new Date(dateString)), check its validity (e.g.,
isNaN(date.getTime()) or similar) and return "-" for empty or invalid dates,
otherwise format the valid Date with the existing toLocaleString options; apply
this change inside the formatDate function to ensure malformed timestamps are
guarded against.
src/main/java/org/example/team6backend/comment/dto/CommentResponse.java (1)

7-9: Minor formatting: consider placing the record components on a single line.

The record definition has an unusual line break before the closing parenthesis.

✨ Suggested formatting
-public record CommentResponse(String id, String message, Instant createdAt, CommentUserResponse user
-
-) {
+public record CommentResponse(String id, String message, Instant createdAt, CommentUserResponse user) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/team6backend/comment/dto/CommentResponse.java`
around lines 7 - 9, The CommentResponse record declaration has an unnecessary
line break before the closing parenthesis; update the record declaration for
CommentResponse so all components (String id, String message, Instant createdAt,
CommentUserResponse user) appear on a single line within the parentheses,
removing the stray newline and aligning the declaration cleanly (look for the
record CommentResponse(... ) in this file).
src/main/java/org/example/team6backend/incident/entity/Incident.java (1)

48-52: Consider removing redundant timestamp assignments in service layer.

The @PrePersist callback sets createdAt and updatedAt on entity creation, but IncidentService (lines 78-79 per context snippet) also explicitly sets these values before calling save(). This redundancy is harmless but unnecessary—you could rely solely on the JPA callbacks and remove the manual assignments in the service.

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

In `@src/main/java/org/example/team6backend/incident/entity/Incident.java` around
lines 48 - 52, The entity's `@PrePersist` onCreate() already sets createdAt and
updatedAt, so remove the manual assignments to createdAt and updatedAt in
IncidentService (where the service currently sets them before save()) and let
JPA callbacks handle creation timestamps; if you also need updatedAt to change
on updates, add a `@PreUpdate` method (e.g., onUpdate()) in Incident.java to set
updatedAt = Instant.now().
🤖 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/team6backend/notification/entity/Notification.java`:
- Around line 23-24: The notification.created_at column remains TIMESTAMP while
the entity Notification.createdAt is an Instant; add a migration to convert that
column to TIMESTAMPTZ—either add the provided ALTER TABLE statement to the V10
migration or create a new migration file that runs: ALTER TABLE notification
ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME ZONE 'UTC';
ensure the migration is applied in the same migration framework used by the
project so the DB type matches the Notification.createdAt Instant mapping.

In `@src/main/resources/db/migration/V10__change_timestamp_to_timestampz.sql`:
- Around line 1-14: Migration misses converting incident.updated_at to
TIMESTAMPTZ; add an ALTER TABLE statement to change incident.updated_at to
TIMESTAMPTZ using the same AT TIME ZONE 'UTC' expression (mirror the existing
incident.created_at conversion) so the incident.updated_at column stores UTC
Instants consistently with service flows.
- Around line 1-14: The migration V10__change_timestamp_to_timestampz.sql is
missing the notification.created_at conversion; add an ALTER TABLE statement for
the notification table to convert created_at to TIMESTAMPTZ using "USING
created_at AT TIME ZONE 'UTC'". Update the V10 migration to include: ALTER TABLE
notification ALTER COLUMN created_at TYPE TIMESTAMPTZ USING created_at AT TIME
ZONE 'UTC'; so Notification.createdAt (backed by Instant) is migrated like the
other tables' created_at columns.

---

Outside diff comments:
In
`@src/main/java/org/example/team6backend/activity/dto/ActivityLogResponse.java`:
- Line 19: The response.setUserName call in ActivityLogResponse mapping uses the
misspelled fallback string "Unknow user"; update the fallback to "Unknown user"
in the ternary expression inside the method where response.setUserName(...) is
called (refer to ActivityLogResponse mapping and activityLog.getUser()).
Optionally, extract the fallback into a constant like UNKNOWN_USER for reuse,
but at minimum correct the string to "Unknown user".

---

Nitpick comments:
In `@src/main/java/org/example/team6backend/comment/dto/CommentResponse.java`:
- Around line 7-9: The CommentResponse record declaration has an unnecessary
line break before the closing parenthesis; update the record declaration for
CommentResponse so all components (String id, String message, Instant createdAt,
CommentUserResponse user) appear on a single line within the parentheses,
removing the stray newline and aligning the declaration cleanly (look for the
record CommentResponse(... ) in this file).

In `@src/main/java/org/example/team6backend/incident/entity/Incident.java`:
- Around line 48-52: The entity's `@PrePersist` onCreate() already sets createdAt
and updatedAt, so remove the manual assignments to createdAt and updatedAt in
IncidentService (where the service currently sets them before save()) and let
JPA callbacks handle creation timestamps; if you also need updatedAt to change
on updates, add a `@PreUpdate` method (e.g., onUpdate()) in Incident.java to set
updatedAt = Instant.now().

In `@src/main/resources/templates/incidents.html`:
- Around line 359-369: The formatDate function accepts any non-empty string and
can return "Invalid Date" for malformed timestamps; update formatDate to parse
the input into a Date object (e.g., new Date(dateString)), check its validity
(e.g., isNaN(date.getTime()) or similar) and return "-" for empty or invalid
dates, otherwise format the valid Date with the existing toLocaleString options;
apply this change inside the formatDate function to ensure malformed timestamps
are guarded against.

In `@src/test/java/org/example/team6backend/user/service/UserServiceTest.java`:
- Around line 33-34: In UserServiceTest, avoid calling Instant.now() twice for
createdAt/updatedAt; instead capture a single Instant (e.g., Instant now =
Instant.now()) and use that same variable in user.setCreatedAt(...) and
user.setUpdatedAt(...) so both timestamps are identical and deterministic for
assertions involving createdAt/updatedAt in the test fixtures.
🪄 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: a0d09f55-4abf-4243-ba9c-ca70b631394f

📥 Commits

Reviewing files that changed from the base of the PR and between df2d33c and f2dbc2f.

📒 Files selected for processing (21)
  • src/main/java/org/example/team6backend/activity/dto/ActivityLogResponse.java
  • src/main/java/org/example/team6backend/activity/entity/ActivityLog.java
  • src/main/java/org/example/team6backend/comment/controller/CommentController.java
  • src/main/java/org/example/team6backend/comment/dto/CommentResponse.java
  • src/main/java/org/example/team6backend/comment/entity/Comment.java
  • src/main/java/org/example/team6backend/exception/ErrorResponse.java
  • src/main/java/org/example/team6backend/exception/GlobalExceptionHandler.java
  • src/main/java/org/example/team6backend/incident/dto/IncidentResponse.java
  • src/main/java/org/example/team6backend/incident/entity/Incident.java
  • src/main/java/org/example/team6backend/incident/service/IncidentService.java
  • src/main/java/org/example/team6backend/notification/dto/NotificationResponse.java
  • src/main/java/org/example/team6backend/notification/entity/Notification.java
  • src/main/java/org/example/team6backend/user/dto/UserResponse.java
  • src/main/java/org/example/team6backend/user/entity/AppUser.java
  • src/main/resources/db/migration/V10__change_timestamp_to_timestampz.sql
  • src/main/resources/templates/admin.html
  • src/main/resources/templates/dashboard.html
  • src/main/resources/templates/incidents.html
  • src/main/resources/templates/profile.html
  • src/main/resources/templates/viewincident.html
  • src/test/java/org/example/team6backend/user/service/UserServiceTest.java

Comment thread src/main/resources/db/migration/V10__change_timestamp_to_timestampz.sql Outdated
@HerrKanin
HerrKanin merged commit de86e56 into main Apr 15, 2026
2 checks passed
@kristinaxm
kristinaxm deleted the feature/UTCtime branch April 23, 2026 17:30
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