Commit Graph
11965 Commits
Author SHA1 Message Date
24e64350ee i18n - translations (#20362)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-07 18:02:01 +02:00
40da6f605d Fix docs apps navigation (#20359)
## Scope & Context

Closes #20358.

The Apps docs were restructured into nested pages, but the generated
docs navigation source still pointed to the old flat Apps page slugs.
This made Developers > Apps navigation entries point to removed English
docs pages.

## Technical inputs

- Update `packages/twenty-docs/navigation/base-structure.json` to use
the current nested Apps docs structure.
- Regenerate `packages/twenty-docs/docs.json` and
`packages/twenty-docs/navigation/navigation.template.json` from the
updated structure.
- Update `generate-docs-json.ts` so localized navigation falls back to
the English slug when the localized `.mdx` file does not exist yet,
avoiding generated 404 links while translations catch up.

## Validation

- Parsed `docs.json`, `base-structure.json`, and
`navigation.template.json` as valid JSON.
- Checked all generated navigation page slugs against existing `.mdx`
files: `missing nav mdx 0`.
- Checked Apps navigation specifically: `missing apps nav mdx 0`.

`yarn docs:generate` could not be run in this local environment because
Yarn/Corepack is not installed here, so I regenerated the JSON files
with the same generator logic via Node.

Co-authored-by: dev111-actor <dev111-actor@users.noreply.github.com>
2026-05-07 18:01:57 +02:00
EtienneandGitHub 9fc5be1c4c Billing - Migrate from Stripe metering (#20298)
**Overall strategy**
**1. Introduce “Billing V2” behind a workspace flag**
Gate the new model with FeatureFlagKey.IS_BILLING_V2_ENABLED so existing
workspaces stay on the old behavior until they’re migrated or explicitly
on V2.

**2. Replace workflow metered SKUs with a resource-credit product**
Conceptually, billable “workflow execution” usage is not the primary
subscription line item anymore. Add a RESOURCE_CREDIT product (and keep
WORKFLOW_NODE_EXECUTION as deprecated for the transition). Usage and
limits are expressed through credit buckets (e.g. price metadata like
credit_amount), so one product can represent pooled credits instead of a
narrow workflow-only meter.

**3. Migrate subscriptions in two layers**
Schema/catalog: persist extra price metadata (instance upgrade) so the
server knows credit amounts and can match Stripe prices to the new
model.
Per workspace: the registered workspace command
upgrade:2-2:migrate-to-billing-v2 finds subscriptions that still have
WORKFLOW_NODE_EXECUTION, swaps those items to the right RESOURCE_CREDIT
prices (using existing Stripe schedule +
BillingSubscriptionUpdateService stack), then treats the workspace as V2
(flag). Workspaces without that legacy item or without a subscription
are skipped.

**4. Unify subscription lifecycle + usage on the server**

**5. Refresh the product surface in Settings**

Test : 

- [x] Subscribe v1 +  Update subscribe + Migrate
- [x]  Subscribe v2 + Update subscribe
2026-05-07 15:42:11 +00:00
Paul RastoinandGitHub ca58c7f15e Fix auto draft workflow (#20357)
# Introduction
Cannot use github graphql mutation with a `GITHUB_TOKEN` needs a
authenticated one
Dispatching to ci-priv to do so
2026-05-07 14:57:17 +00:00
Paul RastoinandGitHub a3224880e0 External contributor auto-draft and dispatch pr-review event type (#20329)
# Introduction

## Auto draft
On external contributor PR creation auto draft it and comment stating
that it needs to be marked as ready for review when it is

## Caveats / future improvement
Lets iterate first but we can imagine future pain points such as:
- Cubic only runs on ready for review PRs
- Expected green ci before turning ready to be review ? ( we could
invoke cubic ourselves )\
- Auto close external contributors draft PR after x duration

## Auto review
Once a PR started to be review or is being synchronized then auto
dispatch auto review
2026-05-07 13:28:43 +00:00
e2afcac076 i18n - docs translations (#20353)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-07 15:03:14 +02:00
2b4fa9d8cf fix: workspace member "me" filters now work in dashboard widgets (#20266)
## Summary

Fixes #20225

Dashboard graph widgets only passed `timeZone` in
`filterValueDependencies` when computing the GraphQL operation filter.
As a result, `isCurrentWorkspaceMemberSelected` ("me") filters were
silently ignored — the current workspace member ID was `undefined`.

Regular view filters already use `useFilterValueDependencies` which
provides both `timeZone` and `currentWorkspaceMemberId`. This PR
replaces the manual `{ timeZone: userTimezone }` object in
`useGraphWidgetQueryCommon` with `useFilterValueDependencies()`, giving
dashboard widgets full feature parity with view filters.

**Changed file:**
`packages/twenty-front/src/modules/page-layout/widgets/graph/hooks/useGraphWidgetQueryCommon.ts`

---------

Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 12:36:14 +00:00
2eae25dc34 Improved create-twenty-app documentation for AI coding agents (#20325)
Added a bit of enhanced context for better agentic coding, based on this
[Discord
conversation](https://discord.com/channels/1130383047699738754/1130383048173682821/1501538550301331477).

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-05-07 14:31:27 +02:00
Paul RastoinandGitHub 1179357bc7 Oxlint ignore twenty-version constant (#20350)
# Introduction
We could handle that by installing prettier on the package.json root and
running it over the twenty versions files inside the ci.
But to be honest it seems redundant, and would bloat the ci in the end.
Lets just not care about lint in these codegen files

Related https://github.com/twentyhq/twenty/pull/20345
2026-05-07 12:01:55 +00:00
f720186122 chore: bump version to 2.4.0 (#20345)
## Summary

- Moves current version to previous versions array
- Sets TWENTY_CURRENT_VERSION to the new version
- Updates TWENTY_NEXT_VERSIONS with the next minor version

## Checklist

- [x] Verify version constants are correct

---------

Co-authored-by: Github Action Deploy <github-action-deploy@twenty.com>
Co-authored-by: prastoin <paul@twenty.com>
2026-05-07 09:41:47 +00:00
9f930aa366 i18n - translations (#20347)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-07 11:19:50 +02:00
EtienneandGitHub e49673df79 Fix plan-required modal issue (#20346)
Commit ee6c0ef904 (Replace sign-in mocked metadata with hardcoded
BackgroundMock) removed the mocked metadata loading path in
MinimalMetadataLoadEffect. Before this change, users with an access
token but an inactive workspace (plan-required state) would get mocked
metadata loaded, which satisfied IsMinimalMetadataReadyEffect's
areObjectsLoaded check. After the change, shouldLoadRealMetadata =
hasAccessTokenPair && isActiveWorkspace is false for plan-required
users, so nothing is loaded, isMinimalMetadataReady stays false, and
MinimalMetadataGater renders the loading skeleton forever instead of the
actual auth modal content.

Fix: Add AppPath.PlanRequired and AppPath.PlanRequiredSuccess to
isOnExcludedPath in MinimalMetadataGater, mirroring how AppPath.Invite
is already excluded — both are pages where the user may have a token but
the workspace isn't fully active, so they don't need metadata to render.
2026-05-07 11:12:50 +02:00
martmullandGitHub 900f70fb9e Add description to oAuth_only app created (#20336)
## Before

<img width="1000" height="555" alt="image"
src="https://github.com/user-attachments/assets/bda317c7-93e7-448e-8e65-a9cc1be6df95"
/>

## After
<img width="1010" height="504" alt="image"
src="https://github.com/user-attachments/assets/5cbc5c6c-5cc3-40d8-9545-ba0f3d2675b4"
/>
<img width="980" height="574" alt="image"
src="https://github.com/user-attachments/assets/4386fe56-0614-4a4e-82a0-c9f46af69c85"
/>
2026-05-07 09:02:04 +00:00
Charles BochetandGitHub 027331c893 chore(front): move mocked-metadata helpers under src/testing (#20341)
## Summary

Follow-up to #20308. After that PR, production code no longer loads
mocked metadata when the user is unauthenticated. The remaining
mocked-metadata helpers (`useLoadMockedMetadata`,
`preloadMockedMetadata`) are now only consumed by Storybook decorators,
so move them next to the other testing-only utilities to make their
scope explicit and prevent accidental re-introduction of a runtime
dependency on mocks.

- `src/modules/metadata-store/hooks/useLoadMockedMetadata.ts`
  → `src/testing/hooks/useLoadMockedMetadata.ts`
- `src/modules/metadata-store/utils/preloadMockedMetadata.ts`
  → `src/testing/utils/preloadMockedMetadata.ts`

The three Storybook decorator imports
(`MockedMetadataLoadEffect`, `ObjectMetadataItemsDecorator`,
`WorkflowStepDecorator`) are updated to the new `~/testing/...` paths.

No runtime behavior change.

## Test plan

- [x] `npx oxlint --type-aware -c .oxlintrc.json` on touched files —
clean
- [x] `npx prettier --check` on touched files — clean
- [ ] CI: storybook, unit tests, e2e tests
2026-05-07 08:32:41 +00:00
af76e04f8d i18n - translations (#20340)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
v2.3.0
2026-05-07 10:10:15 +02:00
afb1f8b983 i18n - translations (#20338)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-07 10:06:49 +02:00
EtienneandGitHub 81f351c90c Ai provider - fix (#20318) 2026-05-07 10:02:54 +02:00
43b6f32080 i18n - website translations (#20337)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-07 10:01:46 +02:00
martmullandGitHub 948ed964bb Add isConfigured to application registration in App admin panel (#20326)
## After
Added "Configured" column in admin panel apps tab
<img width="1171" height="611" alt="image"
src="https://github.com/user-attachments/assets/e6850b39-5789-4ad2-b3df-192a28cb03e2"
/>

Add a banner to ask to configure the application 
<img width="1218" height="483" alt="image"
src="https://github.com/user-attachments/assets/1491363c-3479-41ca-97b7-c7dc9e07ff16"
/>
2026-05-07 09:59:01 +02:00
eddd2c979a Add Workspace Created and Payment Received ClickHouse events (#20277)
## Summary
- Adds two new workspace audit events for the AARRR funnel tracked in
ClickHouse
- **Workspace Created**: emitted in `signUpOnNewWorkspace` after the
transaction commits, capturing every new workspace creation
- **Payment Received**: emitted in `processInvoicePaid` on every Stripe
`invoice.paid` webhook, with `stripeInvoiceId`, `amountPaid`, and
`billingReason` properties. First payment per workspace can be derived
at query time via `min(timestamp)` grouped by `workspaceId`

## Test plan
- [x] Verify `Workspace Created` event appears in ClickHouse after
signing up on a new workspace
- [x] Verify `Payment Received` event appears in ClickHouse after a
Stripe `invoice.paid` webhook fires
- [x] Confirm no event is emitted if the billing customer cannot be
resolved from `stripeCustomerId`
- [x] Run existing `SignInUpService` unit tests pass with the new
`AuditService` mock


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 09:57:30 +02:00
Thomas TrompetteandGitHub be4b466234 Remove broken total count from workflow version (#20324)
## Problem

Opening a workflow run with a form step in the side panel, closing the
form and reopening it crashes the app: `<SidePanelWorkflowStepInfo>`
blows up on `workflow.versions.find` because `versions` is `null` in the
Apollo cache.

## Root cause

`useWorkflowVersion` was selecting:

```ts
workflow: { id, name, statuses, versions: { totalCount: true } }
```
Twenty's GraphQL field generator doesn't support connection-level
scalars — { totalCount: true } is interpreted as fields on the inner
WorkflowVersion node, gets filtered out, and the query collapses to:
versions { edges { node { __typename } } }
The server returns versions: null for that empty-node selection. 

Why now
The selection has always been wrong, but two recent changes made it
consistently surface:

Apollo Client v4 upgrade (#18584): stricter normalized writes, null
always wins.
#20242: WorkflowRunSSESubscribeEffect in the form filler keeps SSE
flowing, which re-fires useWorkflowVersion more often, making the bad
query consistently the last writer.
2026-05-07 09:57:10 +02:00
neo773andGitHub 1faf725498 Fix NestJS CLI pin chokidar to v3 (#20316)
fixes `EMFILE` by downgrading chokidar to v3
root cause is v4 removed kernel level FSEvents on macOS and instead uses
`node:fs.watch` which doesn't scales for a repo of our size

Seems to be working well, even survives multiple hot reloads after
editing files
2026-05-07 09:55:53 +02:00
Abdullah.andGitHub 552016a4d0 [Website] Add articles section with index and article pages, matching customers page design (#20315)
Bare-bone structure for the blog/articles on website.
2026-05-07 09:54:28 +02:00
Charles BochetandGitHub 10876138d2 refactor: stop reading joinColumnName from relation field settings (#20304)
## Summary

`joinColumnName` on relation field settings is always derivable from the
field name (and the target object name for morph relations). This PR
stops reading it from settings anywhere in production code; the stored
value is no longer used.

The settings field is **not** removed from data yet — a follow-up can
drop it once we are confident nothing depends on the stored value.

## Helpers

The helpers are split by layer because frontend and backend hold morph
relations differently: the frontend has a base name plus a
`morphRelations[]` array, the backend has one row per target with the
name already morph-resolved.

| Helper | Layer | When to use |
|---|---|---|
| `computeRelationGqlFieldJoinColumnName` | Shared / frontend
(`gqlField`) | Non-morph relation on the frontend. |
| `computeMorphRelationGqlFieldName` | Shared / frontend (`gqlField`) |
Need the per-target morph gqlField name (e.g. `targetCompany`). |
| `computeMorphRelationGqlFieldJoinColumnName` | Shared / frontend
(`gqlField`) | Per-target morph join column on the frontend. Prefer over
the non-morph helper for any morph field — it forces the per-target
inputs. |
| `computeMorphOrRelationFieldJoinColumnName` | Backend
(`FlatFieldMetadata.name`) | Any backend read or write — the flat name
is already morph-resolved, so one helper covers both cases. |
| `computeMorphRelationFlatFieldName` | Backend
(`FlatFieldMetadata.name`) | **Mutation paths only** (create / update /
object rename). Reads consume the stored `field.name` and never call
this. |

## Test plan

- [x] Typecheck and lint (front, server, shared)
- [x] Existing unit tests pass
- [ ] CI green
2026-05-07 09:53:00 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
4b56ad0607 chore(deps-dev): bump verdaccio from 6.3.1 to 6.5.2 (#20334)
Bumps [verdaccio](https://github.com/verdaccio/verdaccio) from 6.3.1 to
6.5.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/verdaccio/verdaccio/releases">verdaccio's
releases</a>.</em></p>
<blockquote>
<h2>v6.5.2</h2>
<h3><a
href="https://github.com/verdaccio/verdaccio/compare/v6.5.1...v6.5.2">6.5.2</a>
(2026-04-19)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>avoid sharing default security object across configs (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5812">#5812</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/9cca86ee8ac7b64f9011cdc6ac44b995ae025fc8">9cca86e</a>)</li>
<li>Missing package refresh after logging into WebUI (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5825">#5825</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/e6bbea44c56f904e850b883394ef4ffca6c93439">e6bbea4</a>),
closes <a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5814">#5814</a></li>
<li>remove basic header on login error 401 (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5821">#5821</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/1c1723dcbe2fcb1fd64d070d6d357ab7e24ece0a">1c1723d</a>)</li>
<li>update ui-theme dependency (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5822">#5822</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/c4f2cd99d57672792cda175b4674a1310e18fa38">c4f2cd9</a>)</li>
</ul>
<h2>v6.5.1</h2>
<h2>What's Changed</h2>
<ul>
<li>chore: enable ui e2e test by <a
href="https://github.com/juanpicado"><code>@​juanpicado</code></a> in <a
href="https://redirect.github.com/verdaccio/verdaccio/pull/5803">verdaccio/verdaccio#5803</a></li>
<li>fix: web validate password issue by <a
href="https://github.com/juanpicado"><code>@​juanpicado</code></a> in <a
href="https://redirect.github.com/verdaccio/verdaccio/pull/5811">verdaccio/verdaccio#5811</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/verdaccio/verdaccio/compare/v6.5.0...v6.5.1">https://github.com/verdaccio/verdaccio/compare/v6.5.0...v6.5.1</a></p>
<h2>v6.5.0</h2>
<h2><a
href="https://github.com/verdaccio/verdaccio/compare/v6.4.0...v6.5.0">6.5.0</a>
(2026-04-11)</h2>
<h3>Features</h3>
<ul>
<li>update ui to major (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5794">#5794</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/b957c6f0edd909d2c04ba4643d224ef0022c6416">b957c6f</a>)
<a href="https://github.com/juanpicado"><code>@​juanpicado</code></a>
<ul>
<li>Big UI refactoring <a
href="https://redirect.github.com/verdaccio/verdaccio/pull/5563">verdaccio/verdaccio#5563</a></li>
</ul>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>package-filter:</strong> fix O(n²) complexity in
cleanupDistFiles (<a
href="https://github.com/verdaccio/verdaccio/commit/b15f62279d86f16a916f4de849cc9376327849f1">b15f622</a>)
<a
href="https://redirect.github.com/verdaccio/verdaccio/pull/5797">verdaccio/verdaccio#5797</a>
by <a
href="https://github.com/plottodev"><code>@​plottodev</code></a></li>
<li>ui search returns no output <a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5798">#5798</a>
(<a
href="https://github.com/verdaccio/verdaccio/commit/3edd3ee8fab6e75c0ee4f3be5ae812dc8893459b">3edd3ee</a>)
<a
href="https://github.com/juanpicado"><code>@​juanpicado</code></a></li>
</ul>
<h2>v6.4.0</h2>
<h2>Features</h2>
<h3>Package Filter Plugins (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5786">#5786</a>,
<a
href="https://redirect.github.com/verdaccio/verdaccio/pull/5548">verdaccio/verdaccio#5548</a>)
by <a href="https://github.com/vsugrob"><code>@​vsugrob</code></a>, <a
href="https://github.com/pyhp2017"><code>@​pyhp2017</code></a> <a
href="https://github.com/juanpicado"><code>@​juanpicado</code></a></h3>
<blockquote>
<p>⚠️ Please help us to test this feature (it is pretty new and might be
not perfect) ref <a
href="https://github.com/orgs/verdaccio/discussions/5796">https://github.com/orgs/verdaccio/discussions/5796</a>
The <code>@verdaccio/package-filter</code> package is bundled by default
but must be enabled by the user.</p>
</blockquote>
<p><code>@verdaccio/package-filter</code> is a built-in plugin that
intercepts package metadata from uplinks and removes versions matching
configurable rules. With no rules configured, it acts as a no-op
passthrough.</p>
<h4>Block a compromised package version</h4>
<pre lang="yaml"><code>filters:
  '@verdaccio/package-filter':
    block:
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/verdaccio/verdaccio/blob/v6.5.2/CHANGELOG.md">verdaccio's
changelog</a>.</em></p>
<blockquote>
<h3><a
href="https://github.com/verdaccio/verdaccio/compare/v6.5.1...v6.5.2">6.5.2</a>
(2026-04-19)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>avoid sharing default security object across configs (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5812">#5812</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/9cca86ee8ac7b64f9011cdc6ac44b995ae025fc8">9cca86e</a>)</li>
<li>Missing package refresh after logging into WebUI (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5825">#5825</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/e6bbea44c56f904e850b883394ef4ffca6c93439">e6bbea4</a>),
closes <a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5814">#5814</a></li>
<li>remove basic header on login error 401 (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5821">#5821</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/1c1723dcbe2fcb1fd64d070d6d357ab7e24ece0a">1c1723d</a>)</li>
<li>update ui-theme dependency (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5822">#5822</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/c4f2cd99d57672792cda175b4674a1310e18fa38">c4f2cd9</a>)</li>
</ul>
<h3><a
href="https://github.com/verdaccio/verdaccio/compare/v6.5.0...v6.5.1">6.5.1</a>
(2026-04-16)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>web validate password issue (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5811">#5811</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/b66c872d2f1367fc204e96343747ff7a6d8ae601">b66c872</a>)</li>
</ul>
<h2><a
href="https://github.com/verdaccio/verdaccio/compare/v6.4.0...v6.5.0">6.5.0</a>
(2026-04-11)</h2>
<h3>Features</h3>
<ul>
<li>update ui to major (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5794">#5794</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/b957c6f0edd909d2c04ba4643d224ef0022c6416">b957c6f</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>package-filter:</strong> fix O(n²) complexity in
cleanupDistFiles (<a
href="https://github.com/verdaccio/verdaccio/commit/b15f62279d86f16a916f4de849cc9376327849f1">b15f622</a>)</li>
<li>ui search returns no output <a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5798">#5798</a>
(<a
href="https://github.com/verdaccio/verdaccio/commit/3edd3ee8fab6e75c0ee4f3be5ae812dc8893459b">3edd3ee</a>)</li>
</ul>
<h2><a
href="https://github.com/verdaccio/verdaccio/compare/v6.3.2...v6.4.0">6.4.0</a>
(2026-04-06)</h2>
<h3>Features</h3>
<ul>
<li>add package filter (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5786">#5786</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/458a9f2973ff018f2151386725ee36b4b012a69f">458a9f2</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> update core verdaccio dependencies (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5674">#5674</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/4d655079eac09cb32d0f3b072a829e7c24945117">4d65507</a>)</li>
<li><strong>deps:</strong> update core verdaccio dependencies (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5780">#5780</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/b58287b1416291b34f1330fe0fd4653ae3f35c99">b58287b</a>)</li>
<li><strong>deps:</strong> update dependency lodash to v4.18.1 (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5777">#5777</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/797ae530d33a565948166cfd1f45f27ddb33d4ba">797ae53</a>)</li>
</ul>
<h3><a
href="https://github.com/verdaccio/verdaccio/compare/v6.3.1...v6.3.2">6.3.2</a>
(2026-03-14)</h3>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> update core verdaccio dependencies (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5636">#5636</a>)
(<a
href="https://github.com/verdaccio/verdaccio/commit/3da63a4d0bda7dd3bf86378992b05c67b0f1eda5">3da63a4</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/6edeabe00d3b2607aaa287e420badbb938c603ef"><code>6edeabe</code></a>
chore(release): 6.5.2</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/e6bbea44c56f904e850b883394ef4ffca6c93439"><code>e6bbea4</code></a>
fix: Missing package refresh after logging into WebUI (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5825">#5825</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/c4f2cd99d57672792cda175b4674a1310e18fa38"><code>c4f2cd9</code></a>
fix: update ui-theme dependency (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5822">#5822</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/1c1723dcbe2fcb1fd64d070d6d357ab7e24ece0a"><code>1c1723d</code></a>
fix: remove basic header on login error 401 (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5821">#5821</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/9cca86ee8ac7b64f9011cdc6ac44b995ae025fc8"><code>9cca86e</code></a>
fix: avoid sharing default security object across configs (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5812">#5812</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/f01311279f59eb8b93386dbeef367d2ee323a49f"><code>f013112</code></a>
chore(release): 6.5.1</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/b66c872d2f1367fc204e96343747ff7a6d8ae601"><code>b66c872</code></a>
fix: web validate password issue (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5811">#5811</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/f25003c682346fd74cf56b3c9c2352d567faaa40"><code>f25003c</code></a>
chore: update cypress config</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/6d792e739d5db118596ebfe361e020e89d3642b4"><code>6d792e7</code></a>
chore: enable ui e2e test (<a
href="https://redirect.github.com/verdaccio/verdaccio/issues/5803">#5803</a>)</li>
<li><a
href="https://github.com/verdaccio/verdaccio/commit/4dd0083722620f8efaa3af0f916dd8f38f8acd17"><code>4dd0083</code></a>
chore(release): 6.5.0</li>
<li>Additional commits viewable in <a
href="https://github.com/verdaccio/verdaccio/compare/v6.3.1...v6.5.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=verdaccio&package-manager=npm_and_yarn&previous-version=6.3.1&new-version=6.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 09:52:39 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
de92dd7838 chore(deps): bump papaparse from 5.5.2 to 5.5.3 (#20335)
Bumps [papaparse](https://github.com/mholt/PapaParse) from 5.5.2 to
5.5.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/mholt/PapaParse/blob/master/CHANGELOG.md">papaparse's
changelog</a>.</em></p>
<blockquote>
<h2>5.5.3</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Avoid infinite loop with duplicate header counting (<a
href="https://redirect.github.com/mholt/PapaParse/issues/1095">#1095</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/mholt/PapaParse/commits">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=papaparse&package-manager=npm_and_yarn&previous-version=5.5.2&new-version=5.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 09:52:27 +02:00
Charles BochetandGitHub 9ac503e3af fix(front): defer default home redirect when object metadata is not loaded (#20330)
## Summary

Fixes the merge-queue E2E failures introduced after #20308. After login,
users were being silently redirected to `/settings/profile` instead of
their workspace home, which broke every dependent E2E test that re-uses
the post-login URL (`workflow-creation.spec.ts`,
`authentication/signup_invite_email.spec.ts`, etc.).

## Root cause

`useDefaultHomePagePath` falls back to `/settings/profile` when
`readableNonSystemObjectMetadataItems` is empty. That list is empty in
two cases:

1. The user genuinely has no readable objects → `/settings/profile` is
the intended fallback.
2. Object metadata simply hasn't been loaded yet (transient post-login
window).

Before #20308 the frontend always loaded mocked metadata for
authenticated users, so case (2) never happened. After #20308 mocked
metadata is gone, and during the post-verify window
(`handleLoadWorkspaceAfterAuthentication` finishes,
`setIsAppEffectRedirectEnabled(true)` re-enables redirects,
`PageChangeEffect` fires) the metadata store is still empty. The hook
then returns `/settings/profile`. Because that path is not in
`ONBOARDING_PATHS` / `ONGOING_USER_CREATION_PATHS`,
`usePageChangeEffectNavigateLocation` doesn't fire a corrective redirect
once metadata finally loads — the user is stranded.

`login.setup.ts` captures `process.env.LINK = page.url()` after verify,
so subsequent tests `goto(LINK)` end up in Settings looking for app
navigation that isn't there → click timeouts.

## Fix

Distinguish the two empty cases by reading
`metadataStoreState('objectMetadataItems').status`. If it isn't
`'up-to-date'` we defer to `AppPath.Index` instead of
`/settings/profile`. The memo recomputes when the status flips, and the
user is then routed to their actual home page.

A regression test is added in `useDefaultHomePagePath.test.ts` for the
not-loaded-yet case.

## Test plan

- [x] Unit: `npx jest
src/modules/navigation/hooks/__tests__/useDefaultHomePagePath.test.ts`
(5/5 pass, including new regression case)
- [ ] CI: Playwright E2E (`workflow-creation.spec.ts`,
`authentication/signup_invite_email.spec.ts`) pass on this branch
- [ ] Manual: log in to a fresh local instance and confirm landing page
is the workspace home, not `/settings/profile`
2026-05-07 09:51:55 +02:00
Charles BochetandGitHub 83c40bb8cc fix(server): bypass workspace cache in onboardingStatus resolver (#20322)
## Summary

In multi-instance deployments, `coreEntityCacheService` memoizes the
workspace entity per server for ~10s, bypassing Redis hash invalidation.
After `activateWorkspace`, if the next `currentUser` query is routed to
a stale replica, the server returns `onboardingStatus:
WORKSPACE_ACTIVATION` and `workspaceMember: null`, the client redirects
to `/create/profile`, and submitting the form throws "User is not logged
in". Reproduces on prod/staging only (local dev = single instance).

Fix: in `OnboardingService.getOnboardingStatus({ user, workspaceId })`,
read the workspace directly from `WorkspaceEntity` repository (bypassing
the per-instance core entity cache) so `onboardingStatus` reflects the
freshest `activationStatus` right after `activateWorkspace`, even when
the request hits a replica with a stale cached workspace.

## Test plan

- Prod/staging: sign up + create workspace, verify `/create/profile`
works and form submits.
- Local: regression on the full onboarding flow.
2026-05-06 17:41:46 +02:00
Abdullah.andGitHub b94b198a3b fix: server.fs.deny bypassed with queries (#20323)
Resolves [Dependabot Alert
886](https://github.com/twentyhq/twenty/security/dependabot/886).
2026-05-06 16:29:30 +02:00
martmullandGitHub 2158266fcc Fix migration (#20321)
as title
2026-05-06 15:05:13 +02:00
3f307bd192 i18n - translations (#20317)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-06 11:56:58 +02:00
Charles BochetandGitHub ee6c0ef904 Replace sign-in mocked metadata with hardcoded BackgroundMock (#20308)
## Summary

When the user is logged out, we render the auth modal on top of a sample
table to make the empty page feel alive. So far this was achieved by
**loading a full set of mocked object / field / view / navigation-menu
metadata into the runtime metadata store** and then mounting the real
`RecordTable` and `AppNavigationDrawer` behind the modal. This had a few
downsides:

- Significant bundle weight pulled in for unauthenticated users (mocked
GraphQL fixtures + the real `RecordTable` virtualization stack).
- Plenty of code paths that had to know about the "showAuthModal" case
(`useRecordIndexTableQuery`, `useTriggerInitialRecordTableDataLoad`,
`MainContextStoreProvider`, `IsMinimalMetadataReadyEffect`...).
- Any change to metadata-store internals or to the record-table runtime
risked breaking the logged-out background.

This PR replaces the entire flow with a small, self-contained
`BackgroundMock` component tree that **does not consume any metadata**
and **does not load any mocked metadata at runtime**.

### What changed

- New module under `sign-in-background-mock`:
- `BackgroundMockPage` + `BackgroundMockViewBar` + `BackgroundMockTable`
+ `BackgroundMockTableRow` render a hardcoded "Companies" table that
visually mirrors the real one.
- `BackgroundMockNavigationDrawer` renders a hardcoded sidebar with
People / Companies / Opportunities / Tasks / Notes (with their standard
colors).
- Hardcoded constants in `BackgroundMockCompanies.ts`,
`BackgroundMockColumns.ts`, `BackgroundMockNavigationItems.ts`.
- `MinimalMetadataLoadEffect` no longer calls `loadMockedMetadataAtomic`
for unauthenticated users — it just doesn't load anything.
- `IsMinimalMetadataReadyEffect` now reports ready immediately when
there is no access token pair, so the skeleton loader doesn't hang
waiting for metadata that will never come.
- `MainContextStoreProvider`, `useRecordIndexTableQuery`, and
`useTriggerInitialRecordTableDataLoad` drop their `showAuthModal`
branches — the real `RecordTable` is no longer mounted behind the modal.
- `DefaultLayout` and `NotFound` now lazily load `BackgroundMockPage` /
`BackgroundMockNavigationDrawer` instead of the deleted
`SignInBackgroundMockPage` / `SignInAppNavigationDrawerMock`.
- Removed: `SignInBackgroundMockPage`, `SignInBackgroundMockContainer`,
`SignInBackgroundMockContainerEffect`, `SignInAppNavigationDrawerMock`,
`SignInBackgroundMockColumnDefinitions`,
`SignInBackgroundMockCompanies`, `SignInBackgroundMockViewFields`.

`useLoadMockedMetadata` and `preloadMockedMetadata` are kept on purpose:
Storybook decorators (`ObjectMetadataItemsDecorator`,
`WorkflowStepDecorator`) still rely on the mocked metadata fixtures, but
**production** unauthenticated runtime no longer touches them.

### Visual parity

Side-by-side at 1440×900 on `/sign-in`:

**Before** (loads mocked metadata + real RecordTable):

![before](https://github.com/user-attachments/assets/before-placeholder)

**After** (purely hardcoded BackgroundMock):

![after](https://github.com/user-attachments/assets/after-placeholder)

## Test plan

- [ ] `npx nx typecheck twenty-front`  (passes locally)
- [ ] `npx nx lint:diff-with-main twenty-front`  (oxlint + prettier
clean)
- [ ] `npx jest useRecordIndexTableQuery` 
- [ ] Manually verify `/sign-in` renders the table + nav drawer behind
the modal
- [ ] Manually verify `/not-found` still renders the background
- [ ] Verify CI: storybook, unit tests, e2e tests
2026-05-06 11:49:24 +02:00
Paul RastoinandGitHub 26874c3603 Nest command unhandled error process exit 1 (#20312)
# Introduction
When running the `run-instance-commands` on a migration failure the
process wouldn't throw at all
Leading to conditional flow to keep going whereas it should have stopped
This update is very invasive and impacts all the nest commander
registered commands
We should keep in mind that it impacts the way we create and init
database and so on

But I think that's for the best, as cli that never exit 1 is
counterintuitive
2026-05-06 09:26:42 +00:00
Charles BochetandGitHub 0608bae9ae fix(front): resolve labelIdentifier per target for morph relation depth=1 (#20305)
## Summary

On the show page, morph relations were showing "Untitled" entries for
targets whose `labelIdentifier` is not `name` (for example
`Note.title`). The GraphQL response only contained `id` for those
records.

`generateDepthRecordGqlFieldsFromFields` was hardcoding the morph
depth=1 sub-selection to `{ id, name }` for every target instead of
resolving each target's `labelIdentifier` (and `imageIdentifier`) from
`objectMetadataItems`, the way the non-morph relation branch already
does. The morph branch was also ignoring
`shouldOnlyLoadRelationIdentifiers`.

<img width="1300" height="860" alt="image"
src="https://github.com/user-attachments/assets/ebdb5287-0b4c-4a96-95a2-33b19b31446e"
/>
2026-05-06 09:03:22 +00:00
88988e5a55 i18n - translations (#20313)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-06 10:42:40 +02:00
martmullandGitHub 617f571400 20215 convert application variable to a syncable entity (#20269)
##  Summary

- Converts applicationVariable from a bespoke sync path to a proper
SyncableEntity,
unifying it with the workspace migration pipeline used by all other
manifest-managed
  entities (agent, skill, frontComponent, webhook, etc.)
- Removes the upsertManyApplicationVariableEntities method and its
direct-DB-mutation
approach in favor of the standard validate → build → run action handler
pipeline
- Adds universalIdentifier, deletedAt columns and makes applicationId
NOT NULL via an
  instance command migration

##  Motivation

Before this change, applicationVariable was the only manifest-managed
entity that bypassed
ApplicationManifestMigrationService.syncMetadataFromManifest(). It used
a bespoke service
method called directly from syncApplication(), creating two mental
models, two validation
styles, and two cache invalidation patterns. Now there's one unified
pipeline for all
  manifest entities.

##  What changed

###  Entity refactor:
- ApplicationVariableEntity now extends SyncableEntity (gains
universalIdentifier,
  non-nullable applicationId with CASCADE, soft-delete via deletedAt)

###  New flat entity layer (flat-application-variable/):
- Type, maps type, editable properties constant, entity-to-flat
converter, cache service,
  module

###  New migration pipeline wiring:
- Manifest converter
(fromApplicationVariableManifestToUniversalFlatApplicationVariable)
  - Validator service (FlatApplicationVariableValidatorService)
- Builder service
(WorkspaceMigrationApplicationVariableActionsBuilderService)
  - Create/Update/Delete action handlers with secret encryption hooks
- Registered in orchestrator, builder module, runner module, and all
type registries

###  Removed bespoke path:
- Deleted upsertManyApplicationVariableEntities from
ApplicationVariableEntityService
  - Removed its call from ApplicationSyncService.syncApplication()
- Kept update() (operator-set value at runtime) and getDisplayValue()
(runtime display)

###  Database migration:
- Instance command to add columns, backfill universalIdentifier, enforce
NOT NULL
  constraints, and update indexes

##  Test plan

  - npx nx typecheck twenty-server passes (0 errors)
- Unit tests pass (application-variable.service.spec.ts,
build-env-var.spec.ts)
- Install an app with applicationVariables in its manifest → variables
appear with correct
  universalIdentifier
- Update app manifest (add/remove/modify a variable) → migration
pipeline handles diff
  correctly
- Operator-set value via update endpoint persists correctly with
encryption
  - Uninstall app → variables cascade-deleted
  - app dev --once on example app syncs without errors
2026-05-06 08:23:53 +00:00
2a97e77303 fix(server): handle Redis idle disconnects in session-store client (#20143)
## Summary

The session-store node-redis client doesn't attach an `'error'` event
listener, so when Redis closes an idle connection (server-side `timeout`
setting), node-redis emits an unhandled `'error'` event and the entire
Node process crashes with `SocketClosedUnexpectedlyError`.

## Reproduction

1. Deploy twenty-server against a Redis instance with `timeout 300` (5
min idle close).
2. Don't log in (or otherwise keep the session store completely idle).
3. ~5 minutes after `Nest application successfully started`, the process
crashes:

```
node:events:487
      throw er; // Unhandled 'error' event
      ^

SocketClosedUnexpectedlyError: Socket closed unexpectedly
    at Socket.<anonymous> (/app/node_modules/@redis/client/dist/lib/client/socket.js:194:118)
    ...
Emitted 'error' event on Commander instance at:
    at RedisSocket._RedisSocket_onSocketError (/app/node_modules/@redis/client/dist/lib/client/socket.js:218:10)
```

Kubernetes restarts the pod and the loop repeats every ~5 minutes (12
restarts in 95 min in our environment).

`twenty-worker` is unaffected — BullMQ's ioredis client has its own
keep-alive and the queue keeps it busy.

## Root cause


`packages/twenty-server/src/engine/core-modules/session-storage/session-storage.module-factory.ts`
constructs the node-redis client with no error listener:

```ts
const redisClient = createClient({ url: connectionString });

redisClient.connect().catch((err) => {
  throw new Error(`Redis connection failed: ${err}`);
});
```

In Node.js, an unhandled `'error'` event on an `EventEmitter` becomes an
uncaught exception. node-redis emits `'error'` on socket close. With no
listener, the process exits 1 — even though node-redis would otherwise
reconnect on its own.

## Fix

1. Attach a `client.on('error', ...)` listener so disconnect errors are
logged. node-redis' built-in `reconnectStrategy` then takes over.
2. Set `pingInterval: 60_000` so the connection is never idle long
enough to be reaped by any reasonable Redis `timeout`. Defense in depth.

## Verification

Reproduced locally with Redis `CONFIG SET timeout 30` (30s for fast
reproduction). Without the fix: process exits 30s after boot. With the
fix: client logs the disconnect, reconnects, and the process keeps
running.

## Notes / out of scope

- `cache-storage.module-factory.ts` uses `cache-manager-redis-yet`
(which wraps node-redis under the hood). It may exhibit the same
vulnerability under sufficiently idle conditions; recommend a follow-up
to confirm and similarly harden it.
- `redis-client.service.ts` uses ioredis, which has built-in keepalive
and reconnect — no immediate crash risk, but adding error logging there
would be a nice consistency win.

## Test plan

- [ ] Existing tests still pass
- [ ] Manual: deploy with low Redis `timeout` (e.g. `30`), confirm
process survives
- [ ] Manual: kill Redis briefly, confirm twenty-server reconnects
instead of exiting

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-05-05 22:09:13 +00:00
bbd9720ab3 [Dashboards] [Warning] Remove gauge chart support and delete existing widgets (#20172)
## Summary

Removes gauge chart from the chart-type picker and deletes existing
gauge widgets via a workspace migration. The gauge was rendering a
hardcoded `0.7 / "Progress"` stub regardless of configuration -- never
wired to real data.

The contract stays in place. We keep
`WidgetConfigurationType.GAUGE_CHART`, the DTO, the GraphQL union
member, and the gauge folder -- so stored gauge JSON still resolves
through the schema. The render path falls through to `default: return
null`, so any un-migrated gauge widget renders as an empty cell, not a
crash.

This PR just removes existing gauge widgets if there are any (via
`upgrade:2-3:delete-gauge-widgets`). The deliberate cleanup -- deleting
the type definitions, the gauge folder, the DTO -- comes in a follow-up
PR after the migration has run.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-05-05 21:36:45 +00:00
6ebeedba0a i18n - docs translations (#20303)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 20:54:25 +02:00
a3c026f1ce i18n - translations (#20302)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 20:39:23 +02:00
e0563377b5 Fix unclear metadata validation errors (#20234)
https://github.com/user-attachments/assets/8f8f1122-3de1-4a9b-8bb4-a3c8d31e47ae

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-05-05 18:18:05 +00:00
a03c2647cf Fix unreliable SSE event stream updates during workflow form transitions (#20242)
Before - workflow run not up to date, needs refresh to see created
company in some cases


https://github.com/user-attachments/assets/28517e97-2404-4f75-8bce-cc33e3cbea20

After 


https://github.com/user-attachments/assets/60f930cb-1265-4c50-8ec5-aa4f978b1873

## Summary
- Split `SSEQuerySubscribeEffect`'s single debounced
`updateQueryListeners` into separate `syncAdditions` (leading edge, 1s
debounce) and `syncRemovals` (trailing edge, 200ms debounce) callbacks.
This prevents query unregistrations during component mount/unmount
transitions from creating gaps where events are missed, while keeping
new registrations immediate.
- Each sync path now updates `activeQueryListenersState` granularly
(append-only for additions, filter-only for removals) instead of
overwriting the entire state, eliminating a race condition where
removals could mark unregistered queries as active.
- Mount `WorkflowRunSSESubscribeEffect` inside
`WorkflowEditActionFormFiller` so the workflow-run query subscription
stays active during form steps.
- Extract `buildSortedConnectionEdges` util that builds the resulting
edge list of a cached record connection after new records are created.
Position placeholders (`'first'` / `'last'`) bypass orderBy and are
pinned to the front/back; sortable positions (numeric or undefined) are
merged into existing edges and sorted by the connection's actual
`orderBy`. This replaces the broken `length * position` insertion logic
in `triggerCreateRecordsOptimisticEffect` that treated the sortable
`position` field as a 0-1 ratio, causing new records from SSE to land at
invisible indices in the cached list. Also fixes `totalCount` increment
for batched creates, derives `pageInfo` cursors from the final array,
and gracefully skips records whose `toReference` returns null.

## Test plan
- [x] Run a workflow with a form step — verify the workflow status
updates live after form submission (no stuck "running" state)
- [x] Run the same workflow multiple times — verify company creation
events appear live on the record index page for every run, not just the
first
- [x] Click the "+" button to create a record in first position — verify
it appears immediately at the top
- [x] Verify other SSE-backed live updates (record creation, deletion,
updates) still work correctly

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-05 18:14:25 +00:00
6854dc549b i18n - website translations (#20301)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 20:12:54 +02:00
Abdul RahmanandGitHub cbd2a017da Improve app gallery image sizing (no cropping) (#20287)
<img width="908" height="808" alt="Screenshot 2026-05-05 at 7 38 46 PM"
src="https://github.com/user-attachments/assets/a6f0a9b7-f676-46a3-8642-48c4bd06c7f4"
/>
2026-05-05 17:28:39 +00:00
Abdullah.andGitHub 8253fb6e6d feat: improve SEO foundations and canonicalise locale URLs while adding language-switcher in Footer as planned (#20294)
#### SEO

- Heading default flipped from h1 → h2; only Hero.Heading defaults to
h1. Eliminates accidental multi-h1 pages, which was confusing search
engines about the primary topic.
- Titles and descriptions in static-website-routes.ts rewritten to be
keyword-led and unique per page.
- Added buildFaqPageJsonLd (used on /, /pricing) and
buildReleaseListJsonLd (used on /releases).
- ReleaseEntry now renders id={release} so JSON-LD @id fragments resolve
to anchors.


#### Footer language switcher
- New LocaleSwitcher.tsx (plain React popover — useState + useRef +
outside-click). Trigger renders globe icon + native language name
(Français); popover lists all enabled locales with native + English
names side-by-side.
- Intl.DisplayNames-based name resolution in locale-display-names.ts.
- Plumbed into the footer's bottom row next to copyright.

Translations have not been pulled from Crowdin yet, so French pages
currently show English copy.
2026-05-05 17:28:08 +00:00
d5c1f4e10a i18n - docs translations (#20297)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 18:54:42 +02:00
Paul RastoinandGitHub 3b180e7cb5 Fix root monorepo package json focused installation (#20292)
# Introduction
Running `yarn workspace focus twenty`( only installing root package.json
dependencies ) would fail because the yarn constraint expect the yarn
types to be installed
2026-05-05 15:13:31 +00:00
Abdul RahmanandGitHub 3d60e6dbfc Fix stale address coordinates after clearing autofill (#20264)
Closes #20082
2026-05-05 14:43:51 +00:00
e89b12488c i18n - translations (#20290)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 16:44:11 +02:00
31674253a1 i18n - translations (#20289)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-05-05 16:33:11 +02:00