Skip to content

refactor: simplify query hooks and use explicit field projections#450

Merged
larryro merged 5 commits into
mainfrom
refactor/simplify-query-hooks
Feb 13, 2026
Merged

refactor: simplify query hooks and use explicit field projections#450
larryro merged 5 commits into
mainfrom
refactor/simplify-query-hooks

Conversation

@larryro
Copy link
Copy Markdown
Collaborator

@larryro larryro commented Feb 13, 2026

Summary

  • Simplify useLiveQuery calls by replacing verbose q.from({ x: collection }).select(({ x }) => x) patterns with direct () => collection references where no filtering/transformation is needed
  • Use explicit field-by-field projections in .select() instead of pass-through selectors for better type safety (customers, custom agents, chat agents)
  • Add optional chaining for safer organization ID access in dashboard route redirects
  • Remove deleted action module references from generated api.d.ts

Test plan

  • Verify all pages using simplified query hooks still load data correctly
  • Confirm explicit field projections return the expected data shape
  • Test dashboard redirect flows with zero and multiple organizations

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added loading state indicators across data fetching operations for improved UX feedback.
    • Expanded agent data to expose additional field details.
  • Bug Fixes

    • Fixed chat message grouping to correctly handle empty group labels.
    • Improved organization navigation with enhanced null-safety checks during redirect operations.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 13, 2026

📝 Walkthrough

Walkthrough

This pull request refactors multiple query hook files by removing query builder patterns (q.from(...).select(...)) in favor of direct collection references via useLiveQuery(() => collection). The changes also expand the return shapes of several hooks to include an isLoading flag alongside their data fields. Additionally, some hooks now explicitly transform and project data into expanded object shapes containing more fields. Minor safety improvements are applied to navigation logic in dashboard routes by using optional chaining with intermediate variable assignment.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (22 files):

⚔️ package-lock.json (content)
⚔️ services/platform/app/features/approvals/hooks/queries.ts (content)
⚔️ services/platform/app/features/automations/hooks/queries.ts (content)
⚔️ services/platform/app/features/automations/triggers/hooks/queries.ts (content)
⚔️ services/platform/app/features/chat/components/chat-search-dialog.tsx (content)
⚔️ services/platform/app/features/chat/hooks/__tests__/query-hooks.test.ts (content)
⚔️ services/platform/app/features/chat/hooks/queries.ts (content)
⚔️ services/platform/app/features/conversations/hooks/queries.ts (content)
⚔️ services/platform/app/features/custom-agents/hooks/queries.ts (content)
⚔️ services/platform/app/features/customers/hooks/queries.ts (content)
⚔️ services/platform/app/features/documents/hooks/queries.ts (content)
⚔️ services/platform/app/features/organization/hooks/queries.ts (content)
⚔️ services/platform/app/features/products/hooks/queries.ts (content)
⚔️ services/platform/app/features/settings/integrations/hooks/queries.ts (content)
⚔️ services/platform/app/features/settings/organization/hooks/queries.ts (content)
⚔️ services/platform/app/features/settings/teams/hooks/queries.ts (content)
⚔️ services/platform/app/features/vendors/hooks/queries.ts (content)
⚔️ services/platform/app/features/websites/hooks/queries.ts (content)
⚔️ services/platform/app/routes/dashboard/create-organization.tsx (content)
⚔️ services/platform/app/routes/dashboard/index.tsx (content)
⚔️ services/platform/convex/_generated/api.d.ts (content)
⚔️ services/platform/package.json (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ 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 accurately describes the main objective of the changeset: simplifying query hooks and introducing explicit field projections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 refactor/simplify-query-hooks
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch refactor/simplify-query-hooks
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

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

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: 4

Caution

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

⚠️ Outside diff range comments (1)
services/platform/app/features/settings/teams/hooks/queries.ts (1)

17-24: 🧹 Nitpick | 🔵 Trivial

Minor inconsistency in null handling across hooks.

useTeams returns data ?? null (Line 12), while useTeamMembers returns data directly (Line 21). This creates an inconsistent API where teams is always T[] | null but teamMembers is T[] | undefined.

Consider aligning both hooks to use the same pattern for consistency.

♻️ Suggested fix for consistency
 export function useTeamMembers(collection: Collection<TeamMember, string>) {
   const { data, isLoading } = useLiveQuery(() => collection);

   return {
-    teamMembers: data,
+    teamMembers: data ?? null,
     isLoading,
   };
 }
🤖 Fix all issues with AI agents
In `@services/platform/app/features/custom-agents/hooks/queries.ts`:
- Around line 94-99: The hook useAvailableIntegrations currently coerces
undefined to null (returning integrations: data ?? null) which is inconsistent
with sibling hooks useCustomAgentVersions, useCustomAgentWebhooks, and
useAvailableTools that return data directly; update useAvailableIntegrations to
return the raw data value (integrations: data) so its nullability matches the
other simplified hooks (leave the useLiveQuery call and variable names
unchanged).

In `@services/platform/app/features/customers/hooks/queries.ts`:
- Around line 54-66: The projection object used in the .select calls is
duplicated between useCustomers and useCustomerByEmail; extract the shared shape
into a single constant (e.g., CUSTOMER_PROJECTION) and reuse it in both .select
invocations to avoid drift when Customer changes. Create CUSTOMER_PROJECTION
containing the mapped fields (_id, _creationTime, organizationId, name, email,
externalId, status, source, locale, address, metadata) and replace the inline
object in useCustomers (the .select(({ c }) => ({ ... })) shown) and in
useCustomerByEmail (lines 26–38) to reference that constant so updates occur in
one place. Ensure the constant is typed to match the expected return shape and
imported/available to both hooks if moved out of the file.

In `@services/platform/app/routes/dashboard/create-organization.tsx`:
- Around line 26-31: The current code uses organizations[0]?.organizationId for
navigation which can be undefined if the first entry lacks organizationId and
later the component returns null, causing a blank page; change this to compute a
single canonical first valid ID by finding the first organization with a truthy
organizationId (e.g., const firstOrgId = organizations.find(o =>
o.organizationId)?.organizationId), then use that same firstOrgId for both the
navigate call and the render guard so navigation and rendering are consistent
(update usages around navigate({...}) and the subsequent return null check to
reference this computed firstOrgId).

In `@services/platform/app/routes/dashboard/index.tsx`:
- Around line 33-41: The effect assumes organizations[0]?.organizationId exists
and skips navigation when orgs are non-empty but lack organizationId, causing a
permanent loading state; update the logic in the component that computes
firstOrgId (and the navigation branch using navigate) to choose the first
organization object with a defined organizationId (e.g., use
organizations.find(o => o.organizationId) to derive a validId) and add an
explicit fallback branch that navigates to '/dashboard/create-organization' when
no validId is found, ensuring both the non-empty-without-id and empty cases
trigger navigation.

Comment thread services/platform/app/features/custom-agents/hooks/queries.ts
Comment thread services/platform/app/features/customers/hooks/queries.ts Outdated
Comment thread services/platform/app/routes/dashboard/create-organization.tsx
Comment thread services/platform/app/routes/dashboard/index.tsx
Simplify useLiveQuery calls by replacing verbose q.from/select patterns
with direct collection references where no filtering is needed. Use
explicit field projections instead of pass-through selects for type
safety. Add optional chaining for safer organization ID access in
dashboard routes.
Align test assertions with the new select behavior that projects
individual fields instead of passing through the row object.
@larryro larryro force-pushed the refactor/simplify-query-hooks branch from c2de1d0 to 7099ccb Compare February 13, 2026 05:14
@larryro larryro merged commit 22fd1ed into main Feb 13, 2026
15 checks passed
@larryro larryro deleted the refactor/simplify-query-hooks branch February 13, 2026 05:19
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