Files
twenty/packages
Paul Rastoin 3d00dd4066 feat(server): add 2.18 recompute-search-vectors upgrade command (#22355)
## Summary

closes https://github.com/twentyhq/core-team-issues/issues/2620

Adds the 2.18 `recompute-search-vectors` workspace upgrade command —
Part 2 of https://github.com/twentyhq/core-team-issues/issues/2620 (Part
1, the GIN-index rebuild fix, merged in #22349).

It uniformizes every workspace's `TS_VECTOR` (`searchVector`) columns
onto the new derive-from-`searchFieldMetadata` model and drops the
now-dead cached settings:

- **Recomputes** every searchVector column (re-derives its generated
expression from the `searchFieldMetadata` rows) and **recreates its GIN
index** — relying on the Part 1 rebuild fix.
- **Clears** the deprecated cached `TS_VECTOR` settings (`asExpression`
/ `generatedType`), which nothing reads anymore.

## How

New command `RecomputeSearchVectorsCommand`
(`@RegisteredWorkspaceCommand('2.18.0', 1799200001000)`), per
active/suspended workspace:

1. Load `flatFieldMetadataMaps`, enumerate every
`FieldMetadataType.TS_VECTOR` field. Skip (log) if none.
2. Support `--dry-run` (log the count, no writes).
3. Build one `update-field` action per TS_VECTOR field and run them in a
**single migration** via `workspaceMigrationRunnerService.run(...)`:

```ts
update: { universalSettings: null },   // clears the deprecated cached settings
rebuildSearchVector: true,             // re-derive column + recreate GIN index
```

`universalSettings: null` transpiles to `settings: null`, so one atomic
action both clears settings and triggers the rebuild; `runner.run`
invalidates the field-metadata cache afterward.

## Why these choices

- **Single migration under the standard app** covers standard, custom,
and installed-app search vectors at once — the runner operates per
workspace-schema table regardless of a field's owning application, and
the update-field handler doesn't use `flatApplication`.
- **Ordering is safe**: the upgrade sequence runs fast-instance →
slow-instance → workspace commands per version, so the 2.18
`tsVectorFieldMetadataId` backfill (which the expression derivation
depends on) is guaranteed to have run first.
- **Cost**: this is a deliberate full rebuild — it drops/re-adds every
searchVector STORED column (table rewrite per searchable object) and
recreates each GIN index, per workspace, under the workspace iterator.
Intentional ("uniformize for everyone"), as noted in the issue.

## Test plan
- [x] `npx nx typecheck twenty-server`
- [x] `npx nx lint:diff-with-main twenty-server`

Closes Part 2 of
https://github.com/twentyhq/core-team-issues/issues/2620


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22355?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-06-30 14:48:26 +02:00
..