Skip to content

fix(codegen): merge condition into where filter instead of separate GraphQL argument#971

Closed
pyramation wants to merge 1 commit intomainfrom
feat/condition-to-filter-conversion
Closed

fix(codegen): merge condition into where filter instead of separate GraphQL argument#971
pyramation wants to merge 1 commit intomainfrom
feat/condition-to-filter-conversion

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

@pyramation pyramation commented Apr 10, 2026

Summary

The ORM query builder was emitting a separate $condition GraphQL variable referencing *Condition input types (e.g. DocumentCondition, DiligenceRequestCondition). These types don't exist in the schema because PgConditionArgumentPlugin is disabled in ConstructivePreset — all filtering goes through the where argument via graphile-connection-filter.

This PR converts the ORM's condition values into connection-filter equality format and merges them into the where variable instead:

condition: { title: "Financial", status: null }
→ where: { title: { equalTo: "Financial" }, status: { isNull: true } }

Both buildFindManyDocument and buildFindFirstDocument are updated. If both condition and where are provided, they are shallow-merged (condition fields spread on top of where).

Review & Testing Checklist for Human

  • Verify equalTo / isNull are the correct operators for graphile-connection-filter equality matching — these are hardcoded in conditionToFilter and must match the filter plugin's expected input shape
  • Check for field collisions: when both where and condition specify the same field, condition silently wins via { ...where, ...converted }. Confirm this is acceptable or if an and wrapper is needed
  • Run diligence-room integration tests (orm-search.test.ts, orm.test.ts) against this change to confirm the original errors are resolved end-to-end
  • Audit downstream callers that previously passed complex objects as condition values (e.g. embeddingNearby with vector/metric) — these would now be wrapped in { equalTo: ... } which may not be correct for non-scalar fields

Notes

  • The test file maintains its own copy of the query builder helpers (existing pattern). The conditionToFilter and mergeConditionIntoWhere functions were duplicated there to match.
  • The conditionTypeName parameter is still accepted by the function signatures but is now unused at runtime. It was left in place to avoid breaking the call sites in generated ORM code. A follow-up could clean this up.

Link to Devin session: https://app.devin.ai/sessions/136ba9e7789e4cf28c757e6740c21808
Requested by: @pyramation


Open with Devin

…raphQL argument

PostGraphile's PgConditionArgumentPlugin is disabled in ConstructivePreset,
so *Condition input types don't exist in the schema. The ORM codegen was
generating a separate $condition variable that referenced these non-existent
types, causing 'cannot be used as an input type' errors.

This converts condition values (simple equality matching) into the
connection-filter format used by the 'where' argument:
  condition: { title: 'Financial', status: null }
becomes:
  where: { title: { equalTo: 'Financial' }, status: { isNull: true } }

If both condition and where are provided, they are merged together.
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation closed this Apr 10, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

if (!where || Object.keys(where).length === 0) {
return converted;
}
return { ...where, ...converted };
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.

🔴 mergeConditionIntoWhere silently overwrites where filters when condition has overlapping field names

When both where and condition contain the same field name, the spread { ...where, ...converted } at line 880 causes the condition's converted filter to silently overwrite the existing where filter for that field. For example, calling findMany({ where: { status: { notEqualTo: 'deleted' } }, condition: { status: 'active' } }) produces { status: { equalTo: 'active' } } — the notEqualTo filter is silently dropped. This results in incorrect query results (potentially returning more rows than intended). The generated model code at graphql/codegen/src/core/codegen/orm/model-generator.ts:347-369 passes both where and condition from user args, so users can trigger this overlap in practice. The fix should either wrap both in an and combinator (e.g., { and: [where, converted] }) or detect overlapping keys and throw an error.

Prompt for agents
In mergeConditionIntoWhere (query-builder.ts:869-881), the naive spread { ...where, ...converted } silently drops where filters when condition has overlapping field names. The same issue exists in the test duplicate at query-builder.test.ts:141-153.

To fix this properly, when both where and condition have values, wrap them using graphile-connection-filter's `and` combinator instead of merging at the top level. This ensures both the where filter and the converted condition filter are applied:

  return { and: [where, converted] };

Alternatively, you could detect overlapping keys and throw an informative error, but using `and` is semantically correct and preserves both filters regardless of overlap. The same fix should be applied to the duplicate implementation in the test file.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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