Commit Graph

11304 Commits

Author SHA1 Message Date
Charles Bochet
15eb3e7edc feat(sdk): use config file as single source of truth, remove env var fallbacks (#19409)
## Summary

- **Config as source of truth**: `~/.twenty/config.json` is now the
single source of truth for SDK authentication — env var fallbacks have
been removed from the config resolution chain.
- **Test instance support**: `twenty server start --test` spins up a
dedicated Docker instance on port 2021 with its own config
(`config.test.json`), so integration tests don't interfere with the dev
environment.
- **API key auth for marketplace**: Removed `UserAuthGuard` from
`MarketplaceResolver` so API key tokens (workspace-scoped) can call
`installMarketplaceApp`.
- **CI for example apps**: Added monorepo CI workflows for `hello-world`
and `postcard` example apps to catch regressions.
- **Simplified CI**: All `ci-create-app-e2e` and example app workflows
now use a shared `spawn-twenty-app-dev-test` action (Docker-based)
instead of building the server from source. Consolidated auth env vars
to `TWENTY_API_URL` + `TWENTY_API_KEY`.
- **Template publishing fix**: `create-twenty-app` template now
correctly preserves `.github/` and `.gitignore` through npm publish
(stored without leading dot, renamed after copy).

## Test plan

- [x] CI SDK (lint, typecheck, unit, integration, e2e) — all green
- [x] CI Example App Hello World — green
- [x] CI Example App Postcard — green
- [x] CI Create App E2E minimal — green
- [x] CI Front, CI Server, CI Shared — green
2026-04-08 06:49:10 +02:00
github-actions[bot]
af3423dc6f i18n - translations (#19421)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-08 03:42:20 +02:00
Abdul Rahman
a0484f686a Add color to object icon picker in data model (#19368)
Closes [#2291](https://github.com/twentyhq/core-team-issues/issues/2291)
2026-04-08 01:27:08 +00:00
martmull
5c8b6e395b App feedbacks front (#19416)
- Removes agents from app settings
https://discord.com/channels/1130383047699738754/1488500960656490618
- fix public assets not properly pack in deploy and build commands
-
2026-04-07 19:49:02 +00:00
Félix Malfait
9bdef449e6 Fix messageThread view and labelIdentifier on legacy workspaces (#19414)
## Summary
Adds `upgrade:1-21:fix-message-thread-view-and-label-identifier` to
retroactively apply two messageThread changes from #19351 that never
propagated to existing workspaces (because
`synchronizeTwentyStandardApplicationOrThrow` only runs at workspace
creation):

1. **`allMessageThreads` view fields**: delete-and-recreate all view
fields for the standard view from the current twenty-standard
definition, which adds the new `subject` and `updatedAt` columns. Same
pattern as the FIELDS_WIDGET sync in
`1-21-workspace-command-1775500005000-backfill-page-layouts-and-fields-widget-view-fields`.
2. **`messageThread.labelIdentifierFieldMetadataId`**: repointed to the
`subject` field via `validateBuildAndRunWorkspaceMigration`. The
migration runner already resolves
`labelIdentifierFieldMetadataUniversalIdentifier` → id in
`update-object-action-handler`, so this goes through the standard flow
and properly invalidates caches.

Both fixes share a single `validateBuildAndRunWorkspaceMigration` call
(one `viewField` op, one `objectMetadata` update op). Idempotent — skips
if nothing to do.

Depends on `upgrade:1-21:backfill-message-thread-subject` having run
first (the label identifier fix needs the `subject` field to exist; it
logs a warning and skips that part otherwise).

## Test plan
- [ ] Legacy workspace: run \`backfill-message-thread-subject\`, then
this command, then verify:
- the \`allMessageThreads\` view shows the new \`subject\` and
\`updatedAt\` columns
  - messageThread records display their \`subject\` as the record label
- [ ] Re-run the command: no-op, logs \`Nothing to fix\`
- [ ] \`--dry-run\` logs planned changes without applying them

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 21:57:35 +02:00
Baptiste Devessier
e2bd3e8ef4 Unselect widget when exiting layout customization mode (#19411) 2026-04-07 17:26:07 +00:00
Paul Rastoin
c0eacedfec Workspace command decorators (#19397)
# Introduction
Migrating the workspace commands to the decorator version + timestamp
listing as for the instance commands

We've now been able to remove the upgrade command abstraction where we
needed to import all modules and order them
Now they're dynamically retrieved at upgrade runtime, sorted by
timestamp

## Instance and workspace commands name
The name is computed from the command metadata `version` `className` and
`timestamp` we have a duplicate validation at module init from the
unified registry
2026-04-07 16:33:48 +00:00
github-actions[bot]
24a5273a79 i18n - docs translations (#19410)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 18:36:49 +02:00
Raphaël Bosi
607e708670 [COMMAND MENU ITEMS] Add navigate to settings pages commands (#19408)
Add commands to navigate to every settings page.
2026-04-07 16:06:40 +00:00
neo773
61abfd103d fix TextVariableEditor layout and add support for multi line paste (#18721)
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-07 15:58:42 +00:00
neo773
54be3b7e87 docs: remove reference to sync metadata (#19400) 2026-04-07 15:55:23 +00:00
Paul Rastoin
137e068ced Fix yarn-install-lambda and lambda-build target (#19407)
# Size issue
```
Yarn install Lambda failed: {"errorType":"Error","errorMessage":"yarn install failed: ➤ Y/tmp/3bac8baafe6354db414389434726b02c/nodejs/node_modules/tar ENOSPC: no space left on device, write","➤ YN0000: └ Completed in 3s 57ms","➤ YN0000: · Failed with errors in 11s 684ms",""," at runYarnInstall (file:///var/task/index.mjs:48:11)"," at process.processTicksAndRejections (node:internal/process/task_queues:105:5)"," at async Runtime.handler (file:///var/task/index.mjs:119:5)"]}
```

# target esnext
setting the same target for each logic function build funnels
- sdk
- local driver
- lambda driver
2026-04-07 15:53:31 +00:00
Thomas des Francs
91f8f7329a improve pricing card header [website] (#19385)
## Summary
- Reduce the plan title size from `md` to `xs`
- Switch the pricing card header layout from grid to flex for tighter
title/price control
- Tighten the title line-height and add a `black/60` color override for
the `/month...` suffix
- Add a 4px gap between the price amount and suffix
- Reduce the illustration height to 80px and shift it slightly right on
desktop

## Testing
- Not run (not requested)

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-07 15:02:48 +00:00
Raphaël Bosi
d341d0d624 Refactor navigation commands to use NAVIGATION engine key with payload (#19303)
- Adds a payload JSON column to `CommandMenuItem` and introduces a
unified `NAVIGATION` engine component key that replaces all individual
GO_TO_* keys
- Navigation commands now use the payload to determine their target
(either an objectMetadataItemId or a path), making navigation commands
dynamic and eliminating the need for a hardcoded engine key per object
- Includes a 1.21 upgrade command (refactor-navigation-commands) that
migrates existing GO_TO_* items to NAVIGATION items with the appropriate
payload, and applies a CHECK constraint enforcing payload coherence



https://github.com/user-attachments/assets/4d305ba2-ae0b-4556-bb0e-e9d899777350


TODO: In a second PR, create the sync between object metadata items and
the navigation command menu items
- Object metadata item created or enabled -> Create navigation command
- Object metadata item deleted or disabled -> Delete associated
navigation command

In another PR:
- Allow `label`, `shortLabel` and `icon` to resolve the
`navigateToObjectMetadataItem` dynamically in their interpolation
instead of being hardcoded in the command menu item
- Make the icon dynamic in the command menu items as the label so that
we can resolve ${navigateToObjectMetadataItem.icon} at runTime -> This
way we won't need to keep update the command menu item icon when we
update the objectMetadataItem icon
2026-04-07 15:00:04 +00:00
github-actions[bot]
5e9792009f i18n - docs translations (#19405)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 16:51:49 +02:00
Abdullah.
38802bd0b8 Style the remaining website visuals. (#19401)
This PR styles the remaining website visuals. First implementation.
2026-04-07 14:33:54 +00:00
github-actions[bot]
e692e97428 i18n - translations (#19404)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 16:37:15 +02:00
Baptiste Devessier
1f3965e5f8 Add Manage and Placement sections in widget side panel page for record page layouts (#19310)
https://github.com/user-attachments/assets/f6120c2e-95e7-4b9b-abb5-69a10c3f2f3b
2026-04-07 14:21:35 +00:00
Thomas Trompette
e048d03872 Improve workflow crons efficiency (#19381)
**Optimize workflow cron jobs: partition workspaces and use raw
queries**

- Split all 3 workflow cron jobs (WorkflowRunEnqueueCronJob,
WorkflowHandleStaledRunsCronJob, WorkflowCleanWorkflowRunsCronJob) to
process only 1/10th of workspaces per invocation using minute-based
partitioning, reducing per-run load
- Replace ORM repository + workspace context loading with raw SQL
queries in WorkflowRunEnqueueCronJob and
WorkflowHandleStaledRunsCronJob, avoiding costly cache/metadata
hydration for a simple existence check
2026-04-07 14:09:11 +00:00
github-actions[bot]
653180d10f i18n - translations (#19403)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 16:10:37 +02:00
martmull
8702300b07 App feedbacks fix option id required in apps (#19386)
fixes
https://discord.com/channels/1130383047699738754/1488226371032453292
2026-04-07 13:53:16 +00:00
Weiko
6e23ca35e6 Pagelayout backfill command standard app (#19380)
## Context
Due to the chosen strategy for "Reset to default" feature for page
layouts. Those overridable entities need to be associated to the
Standard app to work properly (there is no "Default" state for custom
entities). Until we find a better implementation, I'm changing the
backfill command to reflect that
2026-04-07 12:49:35 +00:00
Félix Malfait
96a242eb7d fix(messaging): create messageThread.subject field metadata + column in 1-21 backfill (#19394)
## Summary
- The 1-21 \`upgrade:1-21:backfill-message-thread-subject\` command
assumed the legacy \`sync-metadata\` flow would create the new
\`messageThread.subject\` field metadata and column on existing
workspaces. That sync was removed, so the column was never added and the
backfill silently skipped.
- The command now ensures the field exists by computing the standard
\`messageThread.subject\` flat field from the twenty-standard
application and running it through
\`WorkspaceMigrationValidateBuildAndRunService\` (same pattern used by
the page-layout / command-menu-item backfills). This creates both the
field metadata row and the workspace schema column.
- After ensuring the field, the existing \`UPDATE messageThread SET
subject = ...\` runs as before.

## Test plan
- [ ] On a workspace with no \`subject\` column on \`messageThread\`,
run \`yarn command:prod upgrade:1-21:backfill-message-thread-subject\`
and confirm:
  - the field metadata row is created in \`core.\"fieldMetadata\"\`
- the \`subject\` column is created on \`workspace_<id>.messageThread\`
  - existing message threads are backfilled from the most recent message
- [ ] Re-run on the same workspace and confirm it is a no-op (field
already exists, no rows to update)
- [ ] Run on a workspace that already has the column but \`NULL\`
subjects and confirm only the backfill runs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 14:42:20 +02:00
github-actions[bot]
d97a1cfc27 i18n - docs translations (#19399)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 14:39:30 +02:00
github-actions[bot]
c844109ffc i18n - translations (#19398)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 14:35:24 +02:00
neo773
dd2a09576b Imap-smtp-caldav form fixes (#19392)
/closes #19273
2026-04-07 12:18:11 +00:00
martmull
fe07de63b0 Enterprise plan required for private app sharing (#19393)
## before

<img width="1512" height="696" alt="image"
src="https://github.com/user-attachments/assets/d57f398e-6ac3-4ce0-a54b-a23ae41b1890"
/>


## after

<img width="923" height="448" alt="image"
src="https://github.com/user-attachments/assets/f4fea42e-1019-4287-9302-42da143ee878"
/>
2026-04-07 12:17:59 +00:00
Paul Rastoin
1c9fc94c1f Workspace commands writes inupgradeMigration (#19379)
# Introduction
As for the instance commands we want to keep a track of what has been
run for the workspace commands
Note that the history will be updated only when the workspace command
has been run through the upgrade directly and not when run atomically

## What's next
Later we will use this history in order to determine the current
workspace's version and instance's version getting rid of the version in
database, that will be the last stone
2026-04-07 12:15:06 +00:00
github-actions[bot]
d10ef156c1 i18n - translations (#19395)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 14:17:20 +02:00
nitin
d3ec64072b [AI] Improve AI System Prompt page layout and token display (#19391)
closes
https://discord.com/channels/1130383047699738754/1480982048050249900

<img width="1438" height="1315" alt="CleanShot 2026-04-07 at 17 02 09"
src="https://github.com/user-attachments/assets/43c5a16f-6dd0-49da-8138-a11a7476e612"
/>
2026-04-07 11:52:48 +00:00
Etienne
1b14e7e1f1 Fix - Update package.json (#19390)
https://github.com/twentyhq/twenty/pull/19383#discussion_r3044330450
2026-04-07 11:44:23 +00:00
neo773
6ad9566043 Add messaging upgrade command 1 21 (#19389)
```
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [WorkspaceIteratorService] Running on workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 1/2
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 5 connected accounts for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 6 message channels for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 6 calendar channels for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 5 message folders for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [WorkspaceIteratorService] Running on workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db 2/2
[Nest] 50057  - 04/07/2026, 4:14:10 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 5 connected accounts for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 50057  - 04/07/2026, 4:14:11 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 4 message channels for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 50057  - 04/07/2026, 4:14:11 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 4 calendar channels for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 50057  - 04/07/2026, 4:14:11 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Migrated 10 message folders for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 50057  - 04/07/2026, 4:14:11 PM     LOG [MigrateMessagingInfrastructureToMetadataCommand] Command completed!
```
2026-04-07 11:21:27 +00:00
Félix Malfait
f39fccc3c4 fix(messaging): split thread create/update statements and stop clobbering accumulator (#19388)
## Summary

Fixes two bugs in
`MessagingMessageService.saveMessagesWithinTransaction`.

### Bug 1 — `ON CONFLICT DO UPDATE command cannot affect row a second
time`

Reported in production logs from `MessagingMessagesImportService`.
Postgres rejects a single `INSERT … ON CONFLICT DO UPDATE` when the same
conflict target appears twice in the values list, and that's exactly
what was happening to `messageThread`.

Where it came from: #19351 added the message-thread subject refresh
feature and, in doing so, switched the existing thread `insert` to a
bulk `upsert(['id'])` over a list built by concatenating two sources:

```ts
const threadsToUpsert = [
  ...messageThreadsToCreate,        // brand-new thread rows
  ...threadSubjectUpdates entries,  // subject refreshes for existing threads
];
await messageThreadRepository.upsert(threadsToUpsert, ['id'], txManager);
```

Each list is internally unique, but they are **not disjoint**.
`enrichMessageAccumulatorWithMessageThreadToCreate`, when it sees two
messages in the same batch sharing a brand-new thread external id,
copies the first sibling's freshly-minted thread id into the second
sibling's `existingThreadInDB`. The subject-update gate later in the
loop then trusts that field and queues a subject refresh for that id —
which is also already in `messageThreadsToCreate`. Same id, same
statement, two rows → Postgres aborts the transaction and the import
retries forever on the same batch.

**Fix:** stop merging the two lists. Issue creates and subject updates
as two separate statements within the same transaction:

```ts
if (messageThreadsToCreate.length > 0) {
  await messageThreadRepository.insert(messageThreadsToCreate, txManager);
}
if (threadSubjectUpdates.size > 0) {
  await messageThreadRepository.upsert(
    Array.from(threadSubjectUpdates.entries()).map(([id, { subject }]) => ({ id, subject })),
    ['id'],
    txManager,
  );
}
```

This is closer to the pre-#19351 shape (`insert` for new rows) and
side-steps the duplicate-row constraint entirely: each statement is
internally unique (creates use freshly minted UUIDs; updates are keyed
by a `Map<id, …>`), and within the same transaction Postgres happily
applies a subject update to a row inserted by a previous statement.

### Bug 2 —
`enrichMessageAccumulatorWithExistingMessageChannelMessageAssociations`
clobbers the accumulator

Independent latent bug spotted while tracing the flow. The helper did:

```ts
if (existingMessageChannelMessageAssociation) {
  messageAccumulatorMap.set(message.externalId, {
    existingMessageInDB: existingMessage,
    existingMessageChannelMessageAssociationInDB: existingMessageChannelMessageAssociation,
  });
}
```

i.e. it **replaces** the accumulator object, dropping the
`existingThreadInDB` set just before by
`enrichMessageAccumulatorWithExistingMessageThreadIds`.

The branch only fires when re-encountering a message that's already been
fully synced on this channel (matched on `headerMessageId` AND already
has an association row) — i.e. routinely on Gmail/IMAP incremental syncs
whenever the connector re-delivers an existing message (label change,
read/unread, archive, full-resync after error, …).

When it fires, the next enrichment step sees `existingThreadInDB` as
`undefined`, falls into the "create a new thread" branch, mints a fresh
`threadToCreate`, but the main loop never queues a `messageToCreate` or
association for it (because both `existingMessageInDB` and the existing
association are still set). Net effect: **one orphan `messageThread` row
inserted per re-encountered message, with nothing referencing it.**

The existing message in the DB keeps pointing at its real thread, so
this is invisible to users — no thread fragmentation, no UI symptoms, no
error logs. Just slow accumulation of orphan thread rows that no query
joins onto. Probably worth running

```sql
SELECT COUNT(*)
FROM "messageThread" mt
WHERE NOT EXISTS (
  SELECT 1 FROM message m WHERE m."messageThreadId" = mt.id
);
```

on a busy production workspace once this lands to size whether a cleanup
migration is warranted.

**Fix:** mutate the existing accumulator in place instead of replacing
it.

## Test plan

- [x] `oxlint --type-aware` clean on touched file
- [x] `prettier` clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-07 13:23:31 +02:00
Etienne
ac1ec91f25 Direct execution - Remove conditional schema (#19383) 2026-04-07 10:22:56 +00:00
Abdullah.
d324bbfc25 Styled illustrations for Hero, ThreeCards, Helped sections. (#19387)
This PR adds styles and animations to illustrations for Hero, ThreeCards
and Helped sections.
2026-04-07 10:17:32 +00:00
eason
7c2a9abed4 fix: prevent NaN in health indicator calculations (#19378)
## Summary

Fixes #19377

- **Redis health**: The hit rate calculation divides by zero when both
`keyspace_hits` and `keyspace_misses` are `"0"` (common on fresh
instances). The string `"0"` is truthy so the guard
`statsData.keyspace_hits ? ...` doesn't catch this case, resulting in
`0/0 = NaN`. Fixed by computing the total first and checking it's a
valid non-zero number.
- **Database health**: The cache hit ratio query returns `null` when
`pg_statio_user_tables` is empty (no user tables). `parseFloat(null)` →
`NaN`. Fixed by adding a null check.

## Test plan

- [ ] Verify health indicators display correctly on a fresh instance
with no Redis keyspace activity
- [ ] Verify health indicators display correctly on a database with no
user tables
- [ ] Existing tests in `redis.health.spec.ts` still pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: easonysliu <easonysliu@tencent.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-07 10:01:49 +00:00
github-actions[bot]
c0c0cbb896 i18n - translations (#19382)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-07 11:50:21 +02:00
Weiko
a2188cb0eb Reset Fields widget implementation (#19283)
## Context
This PR implements the first steps for overridable entities resets.

<img width="1277" height="568" alt="Screenshot 2026-04-02 at 18 58 04"
src="https://github.com/user-attachments/assets/4c7f93b1-c453-4905-a919-cd6af11e0e16"
/>
2026-04-07 09:34:44 +00:00
Paul Rastoin
23874848a4 Instance commands and upgrade_migrations table (#19356)
# Introduction
Now only using typeorm to generate migrations up and down statement
We handle and maintain our own migration table history

## What's new
Now all the instance commands will live within the same module and
folder than the upgrade commands
Sequentiality comes from the timestamp located in the filename
Same sequentiality also applies to the workspace commands in the future,
for the moment still expected a as code explicit declaration

( below screen is an example see below section )
<img width="1382" height="634" alt="image"
src="https://github.com/user-attachments/assets/5610a246-4eae-485e-99f4-98fb89ad5ac8"
/>

## Existing 1.21 migrations
We won't start following this pattern in 1.21 yet at least not with the
migration that has already been released as typeorm migrations in cloud
production as they would rerun


## Small duplication
Duplicating the legacy typeorm and instance commands run in the
`run-instance-commands` to avoid any merge of interest for the moment

## Concurrency
Not handling any run in parrallel of the upgrade for the moment
2026-04-07 08:55:17 +00:00
neo773
b23d2b4e73 messaging post migration cleanup (#19365)
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-07 10:56:49 +02:00
Paul Rastoin
601dc02ed7 Fix s3 driver empty objects (#19361)
`undefined === 0` breaks the early return
2026-04-07 08:20:56 +00:00
Abdullah.
2d552fc9fd Remove hover and scroll transitions from website. (#19369)
This PR removes hover and scroll transitions from the website. 

Per the conversation with Thomas, we should introduce them one by one
for each section.
2026-04-07 07:58:40 +00:00
Paul Rastoin
f33ad53e72 chore: remove registeredCoreMigration (#19376)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
v1.20.7
2026-04-07 10:02:07 +02:00
Félix Malfait
7053e1bbc5 fix: bypass permission checks in 1.21 backfill-message-thread-subject command (#19375)
## Summary
- `upgrade:1-21:backfill-message-thread-subject` was failing on every
workspace with `Method not allowed because permissions are not
implemented at datasource level`.
- The global workspace datasource gates raw `query()` calls behind
`shouldBypassPermissionChecks`. Both the column-existence probe and the
UPDATE in this command now pass that flag, matching the pattern used by
the other 1.20/1.21 upgrade commands.

## Test plan
- [ ] Re-run `yarn command:prod
upgrade:1-21:backfill-message-thread-subject` and confirm all workspaces
complete without the permissions error
- [ ] Spot-check a workspace to confirm `messageThread.subject` is
backfilled from the most recent message

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:59:30 +02:00
Félix Malfait
955aa9191f fix: unify settings layout prep when entering settings from outside (#19373)
## Summary

Clicking **Compose** in the emails tab without a connected account
redirects to the New Account settings page, but the settings nav drawer
was left in its previous (collapsed / "main") state — producing a
visibly half-broken transition.

### Root cause

The "enter settings" preparation (memorize previous URL + drawer state,
expand the desktop drawer, switch the mobile drawer to `'settings'`) was
duplicated **inline in three different places**:
- `NavigationDrawerOtherSection.handleSettingsClick`
- `MultiWorkspaceDropdownDefaultComponents` Settings link
- Implicitly expected (but missing) from every `useNavigateSettings`
caller

Every other entry point — `ComposeEmailButton`, `ComposeEmailCommand`,
`AIChatCreditsExhaustedMessage`, several workflow/role components — just
called `navigateSettings(...)` and skipped the prep entirely,
reproducing the bug.

### Fix

- Move the full prep into `useOpenSettingsMenu`, with a
`useIsSettingsPage()` short-circuit so internal navigation doesn't
clobber the memorized return target.
- `useNavigateSettings` delegates to `openSettingsMenu()` before
navigating — fixing every caller in one place.
- Collapse the duplicated inline logic in `NavigationDrawerOtherSection`
and `MultiWorkspaceDropdownDefaultComponents` to a single call.

Net **−9 lines**, single source of truth, no behavior change for the
existing happy paths.

## Test plan

- [x] \`nx typecheck twenty-front\` passes
- [x] \`oxlint\` + \`prettier\` clean on all 4 changed files
- [x] Existing \`useNavigateSettings\` tests pass (4/4)
- [ ] Manual: Compose button on a Person/Company/Opportunity emails tab
with no connected account → settings drawer renders fully expanded,
"Exit Settings" returns to the record
- [ ] Manual: "Settings" entry in the main nav drawer still works
(return path memorized)
- [ ] Manual: "Settings" entry in the multi-workspace dropdown still
works, and right-click → open in new tab still works (kept
\`UndecoratedLink\`)
- [ ] Manual: Navigating between settings pages does not overwrite the
memorized return URL

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:50:31 +02:00
oniani1
3f87d27d5d fix: use AND instead of OR in neq filter for null-equivalent values (#19071)
Fixes #19070

The `neq` operator in `compute-where-condition-parts.ts` uses `OR` where
it should use `AND` when handling null-equivalent values.

Currently generates:
```sql
field != '' OR field IS NOT NULL
```

For a row where `field = ''`:
- `'' != ''` = false
- `'' IS NOT NULL` = true
- `false OR true` = true -- row incorrectly passes the filter

The `eq` operator correctly uses `OR field IS NULL` because it's
additive (match value or its null equivalent). By De Morgan's law, the
negation `neq` needs `AND field IS NOT NULL` -- exclude if the value
doesn't match AND is not a null equivalent.

With the fix:
```sql
field != '' AND field IS NOT NULL
```
- `'' != ''` = false, `'' IS NOT NULL` = true, `false AND true` = false
-- correctly excluded
- `NULL != ''` = NULL, `NULL IS NOT NULL` = false, `NULL AND false` =
false -- correctly excluded
- `'Alice' != ''` = true, `'Alice' IS NOT NULL` = true, `true AND true`
= true -- correctly included

Affects `neq` filters on TEXT fields and all composite sub-fields
(firstName, lastName, primaryEmail, primaryPhoneNumber, address
sub-fields, etc.) when filtering against null-equivalent values.

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2026-04-07 07:36:41 +00:00
Abdullah.
68cd2f6d61 fix: node-tar symlink path traversal via drive-relative linkpath (#19360)
Resolves [Dependabot Alert
619](https://github.com/twentyhq/twenty/security/dependabot/619) and
[Dependabot Alert
629](https://github.com/twentyhq/twenty/security/dependabot/629).
2026-04-07 07:15:55 +00:00
Abdullah.
8c9228cb2b fix: SVGO DoS through entity expansion in DOCTYPE (#19359)
Resolves [Dependabot Alert
604](https://github.com/twentyhq/twenty/security/dependabot/604) and
[Dependabot Alert
605](https://github.com/twentyhq/twenty/security/dependabot/605).
2026-04-07 07:15:35 +00:00
Abdullah.
35b76539cc fix: minimatch related dependabot alerts. (#19357)
Resolves [Dependabot Alert
491](https://github.com/twentyhq/twenty/security/dependabot/491).

Expecting it to resolve a few other minimatch generated alerts too, but
merging shall confirm which ones since minimatch has a lot of different
versions being imported by different packages as a transitive
dependency.
2026-04-07 07:15:08 +00:00
Thomas des Francs
ea4ef99565 Salesforce section (#19366)
## Summary
- add the retro `VT323` font to the marketing site and apply it across
the Salesforce pricing card and popups
- expand the Salesforce pricing simulator with per-row metadata, unique
popup messages, dynamic price calculation, enterprise shared-cost
handling, and fixed-cost totals
- align the Salesforce card UI with the wireframes: sticky pricing
header, updated checkbox states, popup styling/behavior, add-on link,
and footer cleanup
- remove obsolete shared popup constants and quote form logic tied to
the Salesforce card
- refresh nearby pricing page UI details, including sticky menu behavior
and related pricing section polish

## Testing
- `yarn workspace twenty-website-new build`
2026-04-07 07:14:31 +00:00