Skip to content

refactor(database): simplify session store appends#79

Merged
omarluq merged 3 commits into
mainfrom
refactor/database-session-store-builder
Jun 2, 2026
Merged

refactor(database): simplify session store appends#79
omarluq merged 3 commits into
mainfrom
refactor/database-session-store-builder

Conversation

@omarluq
Copy link
Copy Markdown
Owner

@omarluq omarluq commented Jun 2, 2026

Summary

  • reduce repetitive append boilerplate in session_store.go
  • add a small append options builder path for session entries
  • keep behavior unchanged while clarifying append flow

Validation

  • mise exec -- go test ./internal/database
  • mise exec -- task ci

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

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: aac69fcb-610b-4947-ade7-3bb4b8fc3c2b

📥 Commits

Reviewing files that changed from the base of the PR and between fbd2c97 and 0919595.

📒 Files selected for processing (1)
  • internal/database/session_repository_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/database/session_repository_test.go

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Centralized construction and storage of session entries to enforce consistent fields and timestamps.
  • Bug Fixes
    • Preserve and normalize explicit message timestamps to UTC when entries are saved, preventing unintended changes.
  • Tests
    • Added a unit test verifying input timestamps (including non-UTC) are retained and persisted as UTC for stored session messages.

Walkthrough

Centralizes session entry construction in internal/database/session_store.go by adding appendEntryOptions and appendBuiltEntry; refactors multiple append methods to use the helper; adds a test ensuring input timestamps are preserved and normalized to UTC.

Changes

Entry Append Refactoring

Layer / File(s) Summary
Helper and options struct
internal/database/session_store.go
Adds time import, appendEntryOptions and newAppendEntryOptions, and appendBuiltEntry which computes a single UTC timestamp, constructs EntryEntity, and conditionally sets CustomType, normalized DataJSON, and Summary.
Refactor append methods
internal/database/session_store.go
Updates AppendMessage, AppendCustomEntry, AppendCustomMessage, AppendModelChange, AppendThinkingLevelChange, and appendSummaryEntry to populate appendEntryOptions and delegate entry creation to appendBuiltEntry.
Tests: preserve input timestamp
internal/database/session_repository_test.go
Adds TestSessionRepository_AppendMessagePreservesInputTimestamp which appends a message with explicit UTC and non-UTC timestamps and asserts stored entry/message CreatedAt equals the input timestamp converted to UTC.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • omarluq/librecode#68: Both PRs refactor internal/database/session_store.go to centralize how session entry append helpers construct their underlying entry/data entities via new helper/struct patterns.
  • omarluq/librecode#15: The refactor centralizes EntryEntity/EntryDataEntity field construction (notably DataJSON, CustomType) which directly supports session-entry metadata enrichment work.

Poem

🐰 I built one gate where timestamps meet,

options gather, entries hop in neat,
Six paths now point to one soft door,
Stored times stay true—no scatter more,
A little rabbit cheers, refactor complete.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactoring work of simplifying session store append methods through a helper function and options builder.
Description check ✅ Passed The description directly relates to the changeset, explaining the reduction of boilerplate in session_store.go and the addition of an append options builder.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 refactor/database-session-store-builder

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 2, 2026

Codecov Report

❌ Patch coverage is 92.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.76%. Comparing base (b491ff0) to head (0919595).

Files with missing lines Patch % Lines
internal/database/session_store.go 92.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #79      +/-   ##
==========================================
+ Coverage   66.69%   66.76%   +0.06%     
==========================================
  Files         207      207              
  Lines       17884    17869      -15     
==========================================
+ Hits        11928    11930       +2     
+ Misses       4854     4841      -13     
+ Partials     1102     1098       -4     
Flag Coverage Δ
unittests 66.76% <92.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 02324a32-f155-4e34-973d-2cf4fcfb40ca

📥 Commits

Reviewing files that changed from the base of the PR and between b491ff0 and 35bc08e.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (1)
  • internal/database/session_store.go

Comment thread internal/database/session_store.go
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)
internal/database/session_repository_test.go (1)

90-117: ⚡ Quick win

Broaden this into a table-driven timestamp persistence test.

This only covers a UTC input, so it won’t catch regressions in the non-zero timestamp normalization path. Please add at least one non-UTC case and assert the persisted entry’s CreatedAt after a repository read as well, not just the returned struct and session_messages row.

Suggested shape
-func TestSessionRepository_AppendMessagePreservesInputTimestamp(t *testing.T) {
+func TestSessionRepository_AppendMessagePreservesInputTimestamp(t *testing.T) {
 	t.Parallel()

-	repository := newTestSessionRepository(t)
-	ctx := context.Background()
-
-	createdSession, err := repository.CreateSession(ctx, "/work", "timestamp", "")
-	require.NoError(t, err)
-
-	timestamp := time.Date(2026, time.May, 31, 12, 34, 56, 789000000, time.UTC)
-	message := database.MessageEntity{
-		Timestamp: timestamp,
-		Role:      database.RoleUser,
-		Content:   "hello",
-		Provider:  "",
-		Model:     "",
-	}
-
-	entry, err := repository.AppendMessage(ctx, createdSession.ID, nil, &message)
-	require.NoError(t, err)
-	assert.Equal(t, timestamp, entry.CreatedAt)
-	assert.Equal(t, timestamp, entry.Message.Timestamp)
-
-	storedMessage, found, err := repository.MessageForEntry(ctx, createdSession.ID, entry.ID)
-	require.NoError(t, err)
-	require.True(t, found)
-	assert.Equal(t, timestamp, storedMessage.CreatedAt)
+	testCases := []struct {
+		name      string
+		inputTime time.Time
+		wantTime  time.Time
+	}{
+		{
+			name:      "utc timestamp",
+			inputTime: time.Date(2026, time.May, 31, 12, 34, 56, 789000000, time.UTC),
+			wantTime:  time.Date(2026, time.May, 31, 12, 34, 56, 789000000, time.UTC),
+		},
+		{
+			name:      "offset timestamp is normalized to utc",
+			inputTime: time.Date(2026, time.May, 31, 5, 34, 56, 789000000, time.FixedZone("UTC-7", -7*60*60)),
+			wantTime:  time.Date(2026, time.May, 31, 12, 34, 56, 789000000, time.UTC),
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			repository := newTestSessionRepository(t)
+			ctx := context.Background()
+
+			createdSession, err := repository.CreateSession(ctx, "/work", "timestamp", "")
+			require.NoError(t, err)
+
+			message := database.MessageEntity{
+				Timestamp: tc.inputTime,
+				Role:      database.RoleUser,
+				Content:   "hello",
+			}
+
+			entry, err := repository.AppendMessage(ctx, createdSession.ID, nil, &message)
+			require.NoError(t, err)
+			assert.Equal(t, tc.wantTime, entry.CreatedAt)
+			assert.Equal(t, tc.wantTime, entry.Message.Timestamp)
+
+			storedEntry, found, err := repository.Entry(ctx, createdSession.ID, entry.ID)
+			require.NoError(t, err)
+			require.True(t, found)
+			assert.Equal(t, tc.wantTime, storedEntry.CreatedAt)
+
+			storedMessage, found, err := repository.MessageForEntry(ctx, createdSession.ID, entry.ID)
+			require.NoError(t, err)
+			require.True(t, found)
+			assert.Equal(t, tc.wantTime, storedMessage.CreatedAt)
+		})
+	}
 }

As per coding guidelines, **/*_test.go: Prefer table-driven tests for core behavior and regression tests for terminal rendering bugs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/database/session_repository_test.go` around lines 90 - 117, Convert
TestSessionRepository_AppendMessagePreservesInputTimestamp into a table-driven
test that iterates over at least two cases (UTC and a non-UTC timezone
timestamp); for each case call repository.AppendMessage (using the same
MessageEntity.Timestamp values) and assert both the returned entry.CreatedAt and
entry.Message.Timestamp, then read back the persisted row via
repository.MessageForEntry and assert the persisted storedMessage.CreatedAt
equals the original timestamp (normalized as expected) to cover the non-zero
timezone normalization path; keep the test name and use
repository.CreateSession, repository.AppendMessage, and
repository.MessageForEntry to locate the code under test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/database/session_repository_test.go`:
- Around line 90-117: Convert
TestSessionRepository_AppendMessagePreservesInputTimestamp into a table-driven
test that iterates over at least two cases (UTC and a non-UTC timezone
timestamp); for each case call repository.AppendMessage (using the same
MessageEntity.Timestamp values) and assert both the returned entry.CreatedAt and
entry.Message.Timestamp, then read back the persisted row via
repository.MessageForEntry and assert the persisted storedMessage.CreatedAt
equals the original timestamp (normalized as expected) to cover the non-zero
timezone normalization path; keep the test name and use
repository.CreateSession, repository.AppendMessage, and
repository.MessageForEntry to locate the code under test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 04473572-6399-4d21-817e-7c9e29ca244e

📥 Commits

Reviewing files that changed from the base of the PR and between 35bc08e and fbd2c97.

📒 Files selected for processing (2)
  • internal/database/session_repository_test.go
  • internal/database/session_store.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/database/session_store.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 2, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 2, 2026

@omarluq omarluq merged commit cd27685 into main Jun 2, 2026
13 checks passed
@omarluq omarluq deleted the refactor/database-session-store-builder branch June 2, 2026 16:15
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