Skip to content

chore: Simplify find nearby candidate query#981

Open
skanderm wants to merge 2 commits intomainfrom
skander/simplify-find-nearby-candidate-query
Open

chore: Simplify find nearby candidate query#981
skanderm wants to merge 2 commits intomainfrom
skander/simplify-find-nearby-candidate-query

Conversation

@skanderm
Copy link
Copy Markdown
Contributor

@skanderm skanderm commented Oct 29, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new action to find nearby candidates with enhanced search capabilities.
  • Improvements

    • Strengthened argument validation by making the feed_id parameter mandatory and timestamp validation more robust, improving reliability and consistency.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 29, 2025

Walkthrough

A single Elixir module is refactored to expose a find_nearby_candidate public action with declarative filter expressions, replacing manual query preparation logic and adding required feed_id and non-nullable timestamp arguments.

Changes

Cohort / File(s) Summary
Refactor find_nearby_candidate action
server/lib/orcasite/radio/candidate.ex
Introduces code interface with public find_nearby_candidate read action; tightens timestamp to non-nullable; adds required feed_id string argument; replaces manual prepare block with declarative filter expression using datetime_add for time constraint calculations

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Single file with focused, homogeneous changes
  • Logic migration is straightforward (prepare to filter expression)
  • Primary review concern: verify filter logic equivalence between old manual calculations and new datetime_add-based approach

Poem

🐰 From queries prepared by hand so fine,
To filters that declare their design,
With feed_id required and timestamp tight,
The action now shines crystal bright!
No more manual math, just elegance clear—
Orcasite's radio logic draws near!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore: Simplify find nearby candidate query" directly and accurately reflects the primary change in the pull request. The main modification is replacing a complex prepare-based query construction with a declarative filter expression for the find_nearby_candidate function, which is fundamentally a simplification of the query logic. The title is concise, specific to the function being modified, and avoids vague or generic terminology while remaining clear enough for someone scanning commit history to understand the intent.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch skander/simplify-find-nearby-candidate-query

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.

@paulcretu paulcretu temporarily deployed to orcasite-pr-981 October 29, 2025 01:53 Inactive
Copy link
Copy Markdown
Contributor

@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 details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bb6a2f and cdceb62.

📒 Files selected for processing (1)
  • server/lib/orcasite/radio/candidate.ex (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: test
🔇 Additional comments (2)
server/lib/orcasite/radio/candidate.ex (2)

98-100: LGTM: Code interface addition improves programmatic access.

Exposing find_nearby_candidate via the code interface is a clean way to make this query accessible throughout the application.


152-152: LGTM: Strengthened validation for required parameter.

Setting allow_nil?: false on the timestamp argument ensures the query has the necessary data to function correctly.

Comment on lines +154 to +161
argument :feed_id, :string, allow_nil?: false

filter expr(
feed_id == ^arg(:feed_id) and
category == ^arg(:category) and
min_time <= datetime_add(^arg(:timestamp), ^arg(:within_minutes), :minute) and
max_time >= datetime_add(^arg(:timestamp), -(^arg(:within_minutes)), :minute)
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify type handling and caller updates for the refactored query.

The declarative filter approach is cleaner than manual preparation logic. However, please verify:

  1. Type compatibility: The feed_id argument is defined as :string (line 154), but the belongs_to :feed relationship (line 70) typically creates a UUID foreign key. Confirm that Ash properly converts the string argument to UUID when evaluating the filter expression at line 157.

  2. Caller updates: Since feed_id moved from internal logic to a required argument, ensure all call sites have been updated to pass this parameter.

  3. Filter behavior: The time overlap logic appears sound, but verify that the filter returns expected results, especially around edge cases at the exact within_minutes boundary.

Run the following script to find all usages of this action and verify they've been updated:


🏁 Script executed:

#!/bin/bash
# Find all calls to find_nearby_candidate to verify they pass feed_id

# Search for direct function calls
rg -n -C3 'find_nearby_candidate' --type=ex -g '!**/candidate.ex'

# Search for Ash.Query.for_read calls targeting this action
rg -n -C3 "for_read.*:find_nearby_candidate" --type=ex

# Search for any GraphQL queries that might use this action
rg -n -C3 "findNearbyCandidate" --type=ex --type=graphql

Length of output: 80


Let me fix the search command with proper file patterns:


🏁 Script executed:

#!/bin/bash
# Find all calls to find_nearby_candidate using correct file patterns

# Search for direct Elixir function calls to find_nearby_candidate
rg -n -C3 'find_nearby_candidate' -g '*.ex' -g '*.exs' -g '!**/candidate.ex'

# Also search for camelCase GraphQL naming
rg -n -C3 'findNearbyCandidate' -g '*.ex' -g '*.exs' -g '*.graphql'

Length of output: 746


Good! Found one caller. Let me verify the type of feed_id in the Detection resource and check for any other callers:


🏁 Script executed:

#!/bin/bash
# Find the Detection resource to check feed_id type
fd 'detection.ex' -g '*.ex' | head -5

# Also search more broadly for any other potential calls to find_nearby_candidate
rg -n 'find_nearby_candidate' -g '*.ex' -g '*.exs'

# Check for Ash.Query.for_read usage with find_nearby_candidate across the codebase
rg -n 'for_read.*find_nearby_candidate' -g '*.ex' -g '*.exs'

Length of output: 493



🏁 Script executed:

#!/bin/bash
# Find Detection resource file
find . -path ./node_modules -prune -o -name "*.ex" -type f -print | xargs grep -l "defmodule.*Detection" | grep -v candidate.ex | head -5

# Also check the candidate.ex file for the attribute_types definition
grep -n "attribute_types\|feed_id.*:id\|feed_id.*:uuid" server/lib/orcasite/radio/candidate.ex

Length of output: 350


🏁 Script executed:

#!/bin/bash
# Check the exact argument definition at line 154 in candidate.ex
sed -n '150,165p' server/lib/orcasite/radio/candidate.ex

# Check feed_id definition in detection.ex
grep -n "feed_id" server/lib/orcasite/radio/detection.ex | head -10

Length of output: 1013


🌐 Web query:

Ash framework UUID string type coercion arguments comparison

💡 Result:

Short answer — Ash's :uuid type accepts UUID string representations (and UUID values handled by the underlying type) for arguments and attributes; Ash will coerce input when possible via its UUID type and SQL queries generated by ash_postgres cast values to ::uuid for comparisons.

Details and practical notes:

  • Define arguments/attributes as :uuid (or {:array, :uuid} for lists). Passing a UUID string (e.g. "550e8400-e29b-41d4-a716-446655440000") is the usual way; Ash.Type.UUID handles casting. [1][2]
  • In actions/filters use arg(:id) or regular attribute comparison (e.g. filter expr(id == ^arg(:id))) — the generated SQL shows the value cast to ::uuid so comparisons are done as uuid DB type. [1][3]
  • If you expect complex shapes (maps) instead of plain UUID strings, use the appropriate type (e.g. :map) — supplying the wrong shape (map vs string) will yield an “invalid” validation error. Example threads show {:array, :uuid} expecting a list of UUID strings and failing when given maps. [1]
    References:
  • Ash resource/action examples (argument :id, :uuid; expr filter example). [1]
  • Ash types reference (Ash.Type.UUID). [2]
  • Example generated SQL showing ::uuid casts in comparisons. [3]

Change argument type from :string to :uuid for proper type compatibility.

Type mismatch found: The feed_id argument at line 154 is defined as :string, but the feed_id attribute (line 205) is an :id type (UUID). The caller in server/lib/orcasite/radio/detection/changes/update_candidate.ex:13 passes detection.feed_id, which is also a UUID. Change the argument definition to :uuid to align with Ash's type system and ensure proper SQL casting in the filter expression.

🤖 Prompt for AI Agents
In server/lib/orcasite/radio/candidate.ex around lines 154 to 161, the argument
:feed_id is currently defined as :string but must be :uuid to match the resource
attribute (id/UUID) and callers that pass UUIDs; change the argument type from
:string to :uuid (keeping allow_nil?: false) so Ash generates correct SQL
casting and the filter expression compares UUIDs correctly.

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