Skip to content

filter: Add FilterTime #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

filter: Add FilterTime #145

wants to merge 1 commit into from

Conversation

adrianizen
Copy link

@adrianizen adrianizen commented Aug 18, 2025

Adding filter time function to retrieve specific records within time range

For External Submissions:

  • Have you followed the guidelines in our Contributing file?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • If it's a non-trivial change, I've linked a new or existing issue to this PR
  • I have performed a self-review of my code
  • Does your submission pass existing tests?
  • Have you written new tests for your new changes, if applicable?
  • Have you added an explanation of what your changes do and why you'd like us to include them?

Summary by CodeRabbit

  • New Features

    • Added time-based filters to listings: filter records by Created At (After/Before) to narrow results by creation date.
    • Supported across in-memory and SQL backends, compatible with existing ordering and pagination.
  • Tests

    • Added unit and integration tests covering Created At filters, including enablement, value handling, matching behaviour, and edge cases.

Copy link

coderabbitai bot commented Aug 18, 2025

Walkthrough

The change introduces time-based filtering by CreatedAt across the stack. A new FilterTime type and related constructors (FilterByCreatedAtAfter/Before) are added to filter.go, with accessors on recordFilters. Tests in filter_test.go cover enablement, values, and matching. The in-memory adapter (memrecordstore) applies CreatedAtAfter/Before during List. The SQL adapter adds whereBuilder.AddCondition and applies created_at > / < conditions in List, importing fmt. Adapter tests add a List test case seeding 100 records and verifying CreatedAt filter scenarios. No exported signatures changed except the new public filtering API and whereBuilder method.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A whisker twitch, a tick of time,
I hop between the before and prime;
After the minute, before the dawn,
Records align where clocks are drawn.
With paws on filters, I sift and sort—
CreatedAt whispers: “report, report!”
Thump-thump—tests pass; I bound forth.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 0

🧹 Nitpick comments (4)
filter.go (2)

83-106: Avoid magic numbers and prefer Before/After over Compare for clarity and wider Go compatibility

Relying on time.Time.Compare with sentinel values -1/+1 is less readable and may limit compatibility depending on the Go toolchain. Using Before/After communicates intent and removes the need to remember the compare contract.

Apply this diff to make Matches self-documenting and avoid magic numbers:

 func (f FilterTime) Matches(findValue time.Time) bool {
-	if f.value.Compare(findValue) == f.compare {
-		return true
-	}
-	return false
+	switch f.compare {
+	case -1: // match strictly after f.value
+		return findValue.After(f.value)
+	case 1: // match strictly before f.value
+		return findValue.Before(f.value)
+	default:
+		return false
+	}
 }

Optional, but recommended: add short doc comments to the exported type and helpers to clarify exclusivity semantics and compare meanings:

-func makeFilterTime(compare int, value time.Time) FilterTime {
+// makeFilterTime constructs a FilterTime.
+// compare: -1 means "match strictly after value"; +1 means "match strictly before value".
+func makeFilterTime(compare int, value time.Time) FilterTime {
  	return FilterTime{
  		Enabled: true,
  		compare: compare,
  		value:   value,
  	}
  }
 
-type FilterTime struct {
+// FilterTime represents an enabled time-based filter.
+// It matches values either strictly after or strictly before the configured value.
+type FilterTime struct {
  	Enabled bool
  	compare int
  	value   time.Time
  }
 
+// Value returns the configured boundary time for this filter.
 func (f FilterTime) Value() time.Time {
 	return f.value
 }

167-178: Constructors read well; consider a convenience “between” helper and document exclusivity

The After/Before constructors are fine. Consider adding a combined convenience to reduce caller boilerplate and make intent explicit. Also, a brief doc comment stating the comparisons are exclusive would prevent ambiguity.

Proposed helper (outside these lines, for your consideration):

// FilterByCreatedAtBetween returns records with CreatedAt strictly after start and strictly before end.
func FilterByCreatedAtBetween(start, end time.Time) RecordFilter {
	return func(filters *recordFilters) {
		filters.byCreatedAtAfter = makeFilterTime(-1, start)
		filters.byCreatedAtBefore = makeFilterTime(1, end)
	}
}
filter_test.go (1)

63-75: Add explicit boundary assertions to lock in exclusive semantics

The production code uses strict comparisons. Add assertions that equality does not match to prevent future regressions.

Apply this diff:

 	t.Run("Matches", func(t *testing.T) {
 		t0 := time.Date(2025, time.August, 1, 0, 0, 0, 0, time.UTC)
 		t1 := time.Date(2025, time.August, 10, 0, 0, 0, 0, time.UTC)
 
 		filter := workflow.MakeFilter(workflow.FilterByStatus(9),
 			workflow.FilterByCreatedAtAfter(t0),
 			workflow.FilterByCreatedAtBefore(t1))
 		require.True(t, filter.ByStatus().Matches("9"))
 
 		match := time.Date(2025, time.August, 5, 0, 0, 0, 0, time.UTC)
 		require.True(t, filter.ByCreatedAtAfter().Matches(match))
 		require.True(t, filter.ByCreatedAtBefore().Matches(match))
+
+		// Boundaries are exclusive by design.
+		require.False(t, filter.ByCreatedAtAfter().Matches(t0))
+		require.False(t, filter.ByCreatedAtBefore().Matches(t1))
 	})
adapters/sqlstore/sqlstore.go (1)

207-211: Add whitespace around the placeholder in AddCondition to avoid dialect quirks

Some SQL dialects/parsers are finicky about "?>". Adding spaces improves readability and avoids edge parsing issues.

Apply this diff:

 func (fq *whereBuilder) AddCondition(field string, comparison string, value any) {
-	condition := fmt.Sprintf("(%s %s?)", field, comparison)
+	condition := fmt.Sprintf("(%s %s ?)", field, comparison)
 	fq.conditions = append(fq.conditions, condition)
 	fq.params = append(fq.params, value)
 }

Optional hardening: if this builder ever accepts external input, restrict comparison to a small allowlist (e.g., ">", "<") before formatting the SQL.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 376999d and 37cb15d.

📒 Files selected for processing (5)
  • adapters/adaptertest/recordstore.go (1 hunks)
  • adapters/memrecordstore/memrecordstore.go (1 hunks)
  • adapters/sqlstore/sqlstore.go (3 hunks)
  • filter.go (5 hunks)
  • filter_test.go (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
adapters/adaptertest/recordstore.go (4)
adapters/memrecordstore/memrecordstore.go (1)
  • Store (51-66)
adapters/webui/internal/api/list.go (1)
  • List (43-110)
order.go (1)
  • OrderTypeAscending (7-7)
filter.go (2)
  • FilterByCreatedAtAfter (168-172)
  • FilterByCreatedAtBefore (174-178)
filter_test.go (1)
filter.go (4)
  • MakeFilter (11-18)
  • FilterByCreatedAtAfter (168-172)
  • FilterByCreatedAtBefore (174-178)
  • FilterByStatus (128-146)
🔇 Additional comments (6)
filter.go (2)

6-6: Import looks good

time is correctly imported for the new time-based filters.


20-26: Clean integration of CreatedAt filter fields and accessors

The new byCreatedAtAfter/byCreatedAtBefore fields and their accessors are coherent with existing filter patterns and keep the API consistent.

Also applies to: 40-46

adapters/memrecordstore/memrecordstore.go (1)

228-234: LGTM: Correct application of time filters in the in-memory List path

The new checks short-circuit correctly and preserve existing behaviour. Ordering/pagination paths remain unchanged.

filter_test.go (1)

49-61: Solid coverage for constructor enablement and values

These tests validate enablement and the configured boundary. Clear and deterministic by using a fixed UTC date.

adapters/sqlstore/sqlstore.go (1)

173-179: Correct mapping of CreatedAt filters to SQL predicates

Using created_at > ? and created_at < ? mirrors the exclusive semantics of the in-memory filters.

adapters/adaptertest/recordstore.go (1)

390-438: Good end-to-end coverage for CreatedAt filtering in adapters

The three scenarios exercise the AND-combination, lower-bound only, and upper-bound only cases. Using a ±1m window avoids flakiness and matches both in-memory and SQL adapters.

@echarrod
Copy link
Contributor

LGTM

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