Skip to content

Commit 3fb692f

Browse files
committed
fix(webapp): follow computed keys and call arguments in the list-filter rule
Two detector gaps hid live call sites. A property whose key cannot be read statically was skipped entirely, so a computed key inside a where clause hid the whole branch below it, even though a computed key there is a column name and its value is still predicate territory. And a filter fragment built by a helper and spread into where was dropped when the walk reached the call, so it depended on the helper being named a particular way. The walk now descends through unreadable keys and into call arguments, which exposed the two remaining unbounded sites: the run-graph join lookup, whose sibling target lookup was already bounded, and the member environment lookup.
1 parent eb4604d commit 3fb692f

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

apps/webapp/app/models/member.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export async function getProjectsMissingMemberDevelopmentEnvironments({
234234
organizationId,
235235
...memberDevelopmentEnvironmentWhere({
236236
orgMemberId: memberId,
237-
projectId: { in: projects.map((project) => project.id) },
237+
projectId: { in: boundedIn(projects.map((project) => project.id)) },
238238
}),
239239
},
240240
select: { projectId: true },

oxlint-plugins/prisma-in-filter.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ function propertyKeyName(node) {
117117
* Filters are routinely assembled conditionally, so the walk follows the shapes that carry
118118
* them: `cond ? { … } : {}`, `cond && { … }`, and `...(cond ? { … } : {})`. Stopping at a
119119
* plain ObjectExpression would leave those permanently invisible to the rule.
120+
*
121+
* It also follows call arguments, so a filter fragment built by a helper and spread into
122+
* `where` is still inspected, and it descends through properties whose key it cannot read
123+
* statically. A computed key inside a filter subtree is a column name, so the value below
124+
* it is still predicate territory; skipping it would hide the whole branch.
120125
*/
121126
function reportListFilters(node, context, depth, messageId = "listFilter", extra = {}) {
122127
if (!node || typeof node !== "object" || depth > 12) return;
@@ -139,6 +144,9 @@ function reportListFilters(node, context, depth, messageId = "listFilter", extra
139144
return;
140145
case "SpreadElement":
141146
return descend(node.argument);
147+
case "CallExpression":
148+
for (const argument of node.arguments) descend(argument);
149+
return;
142150
default:
143151
break;
144152
}
@@ -153,7 +161,13 @@ function reportListFilters(node, context, depth, messageId = "listFilter", extra
153161
if (property.type !== "Property") continue;
154162

155163
const name = propertyKeyName(property);
156-
if (!name || VALUE_POSITION.has(name)) continue;
164+
165+
if (!name) {
166+
descend(property.value);
167+
continue;
168+
}
169+
170+
if (VALUE_POSITION.has(name)) continue;
157171

158172
if (LIST_FILTERS.has(name)) {
159173
if (!isBounded(property.value)) {

0 commit comments

Comments
 (0)