Files
twenty/packages
Joseph Chiang 941c9e7586 fix: match relation field filters in optimistic & RLS record matchers (#21301)
Closes #21345.

## What

It should be caused by the GraphQL optimistic query.

`isRecordMatchingFilter` (front, Apollo optimistic cache) and
`isRecordMatchingRLSRowLevelPermissionPredicate` (server, RLS) now
handle a view filter that targets a **relation field object** (e.g. an
"is (not) empty" filter on a relation) by matching against the related
record id, instead of throwing.


<img width="3436" height="2250" alt="CleanShot 2026-06-08 at 06 44
01@2x"
src="https://github.com/user-attachments/assets/1dccbd1e-133c-4f4a-a0a9-7ccd02a9a0ae"
/>

<img width="1496" height="380" alt="CleanShot 2026-06-08 at 06 45 34@2x"
src="https://github.com/user-attachments/assets/e5c2071e-69df-4d99-bb7d-66d503a175b6"
/>


## Why

Both matchers only implemented the relation **join column** branch
(`fooId`) and threw `Not implemented yet, use UUID filter instead on the
corresponding "fooId" field` for the relation field itself (`foo`). In
practice the UI still stores relation filters keyed on the relation
object, so any view with such a filter made every create/update/delete
on that object throw: the optimistic effect re-evaluates all active view
filters against the changed record and hits the unimplemented branch.

Repro: add a self-relation field on People (e.g. "Referred By"), put it
in a view filter as "is not empty", then edit any Person. The optimistic
update throws.

## Behaviour change

| Scenario | Before | After |
|---|---|---|
| View filter on relation object (`referredBy is not empty`), then edit
a record | Throws `Not implemented yet...` | Record matched by related
id; update succeeds |
| Filter on relation join column (`referredById`) | Worked | Unchanged |

## Test plan

```bash
cd packages/twenty-front && npx jest isRecordMatchingFilter
cd packages/twenty-server && npx jest is-record-matching-rls-row-level-permission-predicate
```

- [x] Front: relation `is empty` / `is not empty` / `in` match by
related id; join-column path still passes (20/20)
- [x] Server: relation `is empty` / `is not empty` match by related id
(9/9)
- [x] `lint:diff-with-main` clean on both packages

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-06-11 07:29:10 +02:00
..