fb41b116a4a2e1cde4d01130900e6568bbc5c4ed
9493 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fb41b116a4 |
Add Quick Lead workflow integration tests (#16862)
## Description This PR adds integration tests for the Quick Lead workflow, including a complete end-to-end test with full workflow execution. ### Key Changes 1. **Enabled SyncDriver for integration tests** - Jobs are now processed synchronously in tests - Modified `create-app.ts` to use `SyncDriver` instead of `BullMQ` - Added `MessageQueueExplorer` to discover and register workflow job handlers - This enables complete workflow execution in integration tests 2. **Added integration tests for Quick Lead workflow**: - Verify workflow exists and is active - Verify workflow version has correct structure (MANUAL trigger, FORM step, CREATE_RECORD steps) - Test workflow triggering creates workflow run with correct initial state - Test stop workflow run on a running workflow - **Full end-to-end test**: trigger → submit form → verify Company and Person records created ### Test Coverage The complete end-to-end test verifies: - Workflow triggers and is in RUNNING status (waiting on FORM step) - Form submission with test data succeeds - Workflow completes successfully with all steps in SUCCESS status - Company record is created with correct name and domain - Person record is created with correct name and email - Records are properly cleaned up after test ### How to Run Tests ```bash npx nx run twenty-server:test:integration -- --testPathPattern="quick-lead-workflow" ``` Or with database reset: ```bash npx nx run twenty-server:test:integration:with-db-reset -- --testPathPattern="quick-lead-workflow" ``` |
||
|
|
a2872b02ed |
Deleted at improvement (#16732)
Disable Deactivate option for all standard fields #16706 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Prevents deactivation UI for standard system fields on the field edit page. > > - Introduces `canFieldBeDeactivated` to flag standard fields (`createdAt`, `createdBy`, `deletedAt`, `updatedAt`) > - Hides the "Danger zone" (deactivate/activate/delete controls) when `!isLabelIdentifier && !readonly && !canFieldBeDeactivated` > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b309815700555c8e0f28324936e4ddd313a24fb6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> |
||
|
|
61addf8b62 |
fix(email threads): linkify Email body so that URL links are properly formatted (#16415)
Closes #16396 Added [linkify-react](https://www.npmjs.com/package/linkify-react) and [linkifyjs](https://www.npmjs.com/package/linkifyjs?activeTab=versions) to dependancies. Both are widely used libraries with millions of weekly downloads. Both of them have 0 dependancies on other packages, so should be safe to use. ### Before URLs were shown as plain text <img width="395" height="699" alt="Screenshot 2025-12-09 at 12 25 03 PM" src="https://github.com/user-attachments/assets/772e6d03-8c48-45a1-985c-f775bbd3465c" /> ### After URLs are shown as link and are clickable now. <img width="367" height="641" alt="Screenshot 2025-12-09 at 2 50 29 PM" src="https://github.com/user-attachments/assets/d15bf23a-7cae-4cd4-b9da-e99706c7db38" /> <img width="376" height="656" alt="Screenshot 2025-12-09 at 2 50 46 PM" src="https://github.com/user-attachments/assets/ba112a65-7550-47e3-b42f-83b94c08bfa6" /> --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> |
||
|
|
64d75d0b79 |
Fix E2E tests + Skip chromatic (#16838)
- Always skip chromatic job (we dont check the outcome) - Fix workflow creation test - Run E2E tests before merge (to enable through repo rulesets) |
||
|
|
1128331cc1 |
Fix field item type tag (#16860)
# Introduction This has been fixed on main already 1 hour ago, this PR now only passes the field application id instead of the object applicationId that could be different for example when creating a custom field on a standard object For the moment not introducing any logic around application integrity directly and still relying on the isCustom and standardId definition This will have to be refactored once we deprecate the standardId |
||
|
|
aac70c679f |
Field widget fix dropdowns (#16855)
## Before https://github.com/user-attachments/assets/a78f6561-a519-455e-a838-c4e138fb336f ## After https://github.com/user-attachments/assets/ec704406-b16b-491a-8a88-8aa6fe25254b Closes https://github.com/twentyhq/core-team-issues/issues/2023 |
||
|
|
ab95437065 |
Create query runner context from request context instead of schema builder internal context (#16858)
## Context
This PR refactors how authentication context is handled in the GraphQL
resolver layer. Previously, the auth context was baked into the schema
builder context at schema creation time. Now, the auth context is
extracted from the request at query execution time, enabling better
schema caching.
## Implementation
- Removed user-specific data from schema cache key: The schema cache key
no longer includes userId and apiKeyId, allowing the same schema to be
shared across all users in a workspace
- Cache key simplified from
${workspaceId}-${userId}-${apiKeyId}-${url}-${cacheVersion} to
${workspaceId}-${url}-${cacheVersion}
- Removed authContext from WorkspaceSchemaBuilderContext: The schema
builder context is now purely about object/field metadata, not about who
is accessing it
- Created createQueryRunnerContext utility: A new helper that combines
the schema builder context with the auth context from the actual request
- Updated all resolver factories: All 15 resolver factories now use
createQueryRunnerContext to build the full context needed by query
runners at execution time
## Benefits
- Improved cache efficiency: GraphQL schemas are now cached per
workspace rather than per user, significantly reducing memory usage and
schema regeneration
- Cleaner separation of concerns: Schema building (metadata-driven) is
now separate from query execution (auth-driven)
- Fresh auth context: Auth context is always retrieved from the current
request, ensuring it reflects the latest state
- Reduced complexity: Simplified the schema creation path by removing
unnecessary auth checks
## Next steps
- Introduce a hash in redis and expose it in the req object so the yoga
patch can access the hash and use it during its own cache key
computation. This way we will be able to invalidate the local cache in
yoga graphql schema generation without restarting pods.
|
||
|
|
e3ffdb0c2b |
[BREAKING_CHANGE_NESTED_WORKSPACE]Refactor FlatEntity typing in aim of introducing UniversalFlatEntity (#16701)
# Introduction
Added a `WorkspaceRelated` and `AllNonWorkspaceRelatedEntity` to
simplify the `FlatEntityFrom` that now do not expect a string literal to
omit and itself builds the related many to one entities foreign key
aggregators
We now have the type grain over relation to syncable or just workspace
related entities
Added a migrations that sets the fk on missing entities
## Next
In upcoming PR we will be able to introduce such below type
```ts
import { type CastRecordTypeOrmDatePropertiesToString } from 'src/engine/metadata-modules/flat-entity/types/cast-record-typeorm-date-properties-to-string.type';
import { type ExtractEntityManyToOneEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-many-to-one-entity-relation-properties.type';
import { type ExtractEntityOneToManyEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-one-to-many-entity-relation-properties.type';
import { type ExtractEntityRelatedEntityProperties } from 'src/engine/metadata-modules/flat-entity/types/extract-entity-related-entity-properties.type';
import { type RemoveSuffix } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/remove-suffix.type';
import { type SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/types/syncable-entity.interface';
export type UniversalFlatEntityFrom<TEntity extends SyncableEntity> = Omit<
TEntity,
| `${ExtractEntityManyToOneEntityRelationProperties<TEntity> & string}Id`
| ExtractEntityRelatedEntityProperties<TEntity>
| 'application'
| 'workspaceId'
| 'applicationId'
| keyof CastRecordTypeOrmDatePropertiesToString<TEntity>
> &
CastRecordTypeOrmDatePropertiesToString<TEntity> & {
[P in ExtractEntityManyToOneEntityRelationProperties<TEntity> &
string as `${RemoveSuffix<P, 's'>}UniversalIdentifier`]: string;
} & {
[P in ExtractEntityOneToManyEntityRelationProperties<
TEntity,
SyncableEntity
> &
string as `${RemoveSuffix<P, 's'>}UniversalIdentifiers`]: string[];
};
```
|
||
|
|
720348c583 |
Add upgrade commands to backfill updatedBy field and view fields (#16845)
--- prastoin edit ## Introduction As we're deprecating the sync metadata we cannot rely on it anymore in order to create the new standard updatedBy field In this PR we introduce a command that will backfill the dynamic field on both workspace standard and custom objects, for standard object it will create a standard fields ( twenty-standard app scoped ) and for custom one it will create a custom field ( worksapce-custom-app scoped ) ## Testing method Checkout `1.14.0` `yarn` and `npx nx database:reset twenty-server` checkout PR and `yarn` `npx nx build twenty-server` and `yarn database:migrate:prod` finally running the command #### Before <img width="2244" height="1464" alt="image" src="https://github.com/user-attachments/assets/2fb866cd-13b8-4152-99b8-1fcc813b1d46" /> #### After <img width="2244" height="1464" alt="image" src="https://github.com/user-attachments/assets/b836ac06-c7b8-4add-bee1-bc1963418f29" /> #### Logs ```ts [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Found 12 objects that need updatedBy field [EntityBuilder fieldMetadata] matrix computation: 3.994ms [EntityBuilder fieldMetadata] creation validation: 1.822ms [EntityBuilder fieldMetadata] deletion validation: 0.016ms [EntityBuilder fieldMetadata] update validation: 0.009ms [EntityBuilder fieldMetadata] entity processing: 6.098ms [EntityBuilder fieldMetadata] validateAndBuild: 10.217ms [EntityBuilder index] matrix computation: 0.857ms [EntityBuilder index] creation validation: 0.003ms [EntityBuilder index] deletion validation: 0.017ms [EntityBuilder index] update validation: 0.008ms [EntityBuilder index] entity processing: 4.721ms [EntityBuilder index] validateAndBuild: 5.632ms [Runner] Initial cache retrieval: 0.07ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 7.69ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 10.531ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 5.354ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 6.134ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.507ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.745ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.113ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.585ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.223ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.221ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 5.375ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 5.943ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.363ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.997ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.03ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.982ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.88ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.977ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 9.638ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 11.297ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.581ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.248ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.847ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.732ms [Runner] Transaction execution: 82.555ms [Runner] Cache invalidation flatFieldMetadataMaps,flatIndexMaps,flatObjectMetadataMaps: 89.247ms [Runner] Total execution: 171.963ms [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Successfully backfilled updatedBy field for 12 objects in workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Running command on workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db 2/2 [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Starting backfill of updatedBy field for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Found 10 objects that need updatedBy field [EntityBuilder fieldMetadata] matrix computation: 3.224ms [EntityBuilder fieldMetadata] creation validation: 0.969ms [EntityBuilder fieldMetadata] deletion validation: 0.014ms [EntityBuilder fieldMetadata] update validation: 0.002ms [EntityBuilder fieldMetadata] entity processing: 5.149ms [EntityBuilder fieldMetadata] validateAndBuild: 8.472ms [EntityBuilder index] matrix computation: 0.785ms [EntityBuilder index] creation validation: 0.002ms [EntityBuilder index] deletion validation: 0.014ms [EntityBuilder index] update validation: 0.002ms [EntityBuilder index] entity processing: 3.818ms [EntityBuilder index] validateAndBuild: 4.637ms [Runner] Initial cache retrieval: 0.05ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.964ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.902ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.502ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.039ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.673ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.403ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.143ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.123ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.033ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.954ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.826ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.903ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.495ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.106ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 14.014ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 14.373ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.669ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.48ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.62ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.048ms [Runner] Transaction execution: 73.222ms [Runner] Cache invalidation flatFieldMetadataMaps,flatIndexMaps,flatObjectMetadataMaps: 37.703ms [Runner] Total execution: 111.071ms ``` --- --------- Co-authored-by: prastoin <paul@twenty.com> |
||
|
|
a0491e4755 |
fix: images are not included in PDF exports (#16076)
## Description - This PR address issue https://github.com/twentyhq/twenty/issues/15998 - The issue was that images are stored as signed urls and the backend signed these with JWT - BlockNote `resolveFileUrl` uses a public CORS proxy that couldn’t access authenticated/signed URLs ## Visual Appearance https://github.com/user-attachments/assets/12936451-d91d-4371-bcf7-8a2c2bb68e9c |
||
|
|
a2827494a1 |
Support actor filtering in workflows (#16783)
Fixes https://github.com/twentyhq/twenty/issues/15782 Find records <img width="422" height="423" alt="Capture d’écran 2025-12-23 à 16 23 49" src="https://github.com/user-attachments/assets/5856de06-d608-46f6-97a6-8f382f355a44" /> Filters <img width="422" height="271" alt="Capture d’écran 2025-12-23 à 16 23 32" src="https://github.com/user-attachments/assets/fcc10b6e-f1ec-497a-8593-d599164d4e4b" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds full support for filtering on `ACTOR` composite fields across UI and server. > > - Front-end: handles `ACTOR` in advanced filters and workflow filters; `source` uses multi-select options from `FieldActorSource`, `workspaceMemberId` uses `FormSingleRecordPicker`, others default to text > - Updates operand mapping for `ACTOR` (`source`→`SELECT`, `workspaceMemberId`→`RELATION`, else `TEXT`) > - Server: adds `ACTOR` evaluation with subfield-specific logic (delegates to select/relation/text evaluators) > - Simplifies `AdvancedFilterFieldSelectMenu` by removing workflow-specific field filtering > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7a8164cd2d4cad321ff1009bc7d1c4295a6672ca. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
d39f105a03 |
i18n - translations (#16849)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
19c9f957b1 |
Improve userFriendlyMessage devX (#16815)
Two challenges with error messages - always provide a useful/meaningful error message for the end user instead of the generic one. eg: show "Wrong password" and not "An error occured" - avoid technical details unless error regards a technical feature. eg: show "An error occured" and not "Invalid post-hook payload."; but do show "Invalid issuer URL." as it occurs while configuring SSO What this PR does - Make userFriendlyMessage mandatory for widely used GraphqlQueryRunnerException and CommonQueryRunnerException, so that developers are forced to ask themselves what the error message should be, and as it contains very wide error codes (eg: "Bad request") which should not be mapped to just one default message - Keep userFriendlyMessage optional for service-specific exceptions (eg: workflowStepExecutorException), but convert the error code to userFriendlyMessage mapper to a switch case function with a typecheck ensuring that all codes are mapped to a message. These default messages are still overridable where they are thrown. |
||
|
|
7522ff6675 |
i18n - translations (#16848)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
418377b867 |
i18n - translations (#16847)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
4f1f0eb177 |
Redesign Object/Field tables (#16844)
Redesign the data model pages for more clarity / better distinction between fields and relations |
||
|
|
8d130908c2 |
Allow user to update profile picture (#16812)
Fixes [#16805](https://github.com/twentyhq/twenty/issues/16805) User was not able to update his own profile picture it showed permisson error while doing so. Updated permission so that user is able to edit profile picture <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Ensures profile picture uploads succeed only with appropriate permissions and clearer errors. > > - Tightens `UploadProfilePicturePermissionGuard` to handle missing `workspace`, allow during workspace creation, and permit uploads when user has `WORKSPACE_MEMBERS` or `PROFILE_INFORMATION` settings; otherwise throws a `PermissionsException` with a user-friendly message > - In `user-workspace.resolver.ts`, validates the upload result and throws an error if no files were returned > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3766bac15e340bdd467de3a9d923dbd697aab3db. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
3096769616 |
build(deps): bump @monaco-editor/react from 4.6.0 to 4.7.0 (#16829)
Bumps [@monaco-editor/react](https://github.com/suren-atoyan/monaco-react) from 4.6.0 to 4.7.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/releases"><code>@monaco-editor/react</code>'s releases</a>.</em></p> <blockquote> <h2>v4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (<code>v1.5.0</code>) version (this uses <code>monaco-editor</code> <code>v0.52.2</code>)</li> <li>package: inherit all changes from <code>v4.7.0-rc.0</code></li> </ul> <h2>v4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom <code>v19</code> as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/suren-atoyan/monaco-react/blob/master/CHANGELOG.md"><code>@monaco-editor/react</code>'s changelog</a>.</em></p> <blockquote> <h2>4.7.0</h2> <ul> <li>package: update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version (this uses monaco-editor v0.52.2)</li> <li>package: inherit all changes from v4.7.0-rc.0</li> </ul> <h2>4.7.0-rc.0</h2> <ul> <li>package: add support for react/react-dom v19 as a peer dependency</li> <li>playground: update playground's React version to 19</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/eb120e66378471315620fe5339b73ba003f199ad"><code>eb120e6</code></a> update package to 4.7.0 version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/cdd070c9f080caf4a9a7b13c2c34fa4e10edc9bf"><code>cdd070c</code></a> update snapshots</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/55a063e45d2f2672884b77059ac97850758764ae"><code>55a063e</code></a> update <code>@monaco-editor/loader</code> to the latest (v1.5.0) version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/52e8c75616e09730b7b1a0b5822385212a082ce8"><code>52e8c75</code></a> update package to 4.7.0-rc.o version</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/e72be4edc1b4492eae9f7d85671ee61a43a6aee8"><code>e72be4e</code></a> add react 19 to peerDependencies</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/642be903a9dd21d6fe639ab5c92c234dad77c813"><code>642be90</code></a> update playground's react version to 19</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ceee344fbe26285dabb0fe90985fe18ec867211c"><code>ceee344</code></a> Add Monaco-React AI Bot in Readme (<a href="https://redirect.github.com/suren-atoyan/monaco-react/issues/655">#655</a>)</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/f7cac39fbad0f062dc66458831aaf57a7126dd40"><code>f7cac39</code></a> add electron blog post link</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/ea601cf9f6fe9f2cc0c6271d6a9cde9a332b6dc0"><code>ea601cf</code></a> add tea constitution file</li> <li><a href="https://github.com/suren-atoyan/monaco-react/commit/3327f3c368cb6d56c02f2df8a9d45177ce6f52e9"><code>3327f3c</code></a> add GitHub sponsor button</li> <li>See full diff in <a href="https://github.com/suren-atoyan/monaco-react/compare/v4.6.0...v4.7.0">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com> |
||
|
|
3a673f99ba |
Disable updated By 2 (#16840)
Prepare for release, will re-enable them |
||
|
|
e5e5ae8e1d |
fix: guard against invalid date and undefined links field value (#16039)
closes https://github.com/twentyhq/twenty/issues/15854 - Add `isValid()` check in `formatDateISOStringToDateTime` before calling `formatInTimeZone` - Add `isDefined()` guard in `getFieldLinkDefinedLinks` (mirrors `phonesUtils` pattern) before: https://github.com/user-attachments/assets/1eb89fa4-70b6-4794-8860-0a42522598b5 https://github.com/user-attachments/assets/781c7d37-c435-4832-98d4-8e6925b51e10 after: https://github.com/user-attachments/assets/b1c22d25-4e8e-45c3-af98-be1684a5962e https://github.com/user-attachments/assets/ce084a9d-03b8-4f88-8522-a32cb1b7cf2f --------- Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> |
||
|
|
b56dcd8c22 |
Temporarily disable updatedBy (#16839)
To avoid breaking workflows during release |
||
|
|
ba7a060195 |
i18n - translations (#16836)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
4135a6473a |
[BREAKING_CHANGE_DASHBOARDS][DASHBOARD_CACHE_FLUSH_REQUIRED] Refactor page layout widget configuration type (#16671)
# Introduction In this pull-request we're refactoring the page layout widget configuration entity to be containing its discriminated key simplifying underlying code and maintainability - Made the configuration and title non nullable - Introduced a generic predicate for the `widgetConfigurationType` - Upgraded command to remove `graphType` and insert new `configurationType` to existing entries - Migrated frontend to new type system --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com> Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com> |
||
|
|
2b9728230a |
Correctly separate widgets in side-column mode. (#16804)
Had to close the other PR since I messed up re-basing somehow: https://github.com/twentyhq/twenty/pull/16668/files. Moved changes to this new PR in order to resolve comments from the previous PR and also match the field-design to that on Figma. --------- Co-authored-by: Baptiste Devessier <baptiste@devessier.fr> |
||
|
|
bee58fd03d |
feat: use side-column variant for all widgets on mobile and side panel (#16822)
Closes [1957](https://github.com/twentyhq/core-team-issues/issues/1957). `getWidgetCardVariant` now returns `side-panel` for mobile and right drawer instead of returning `record-page`. Added stories to WidgetRenderer.stories.tsx because WidgetRenderer is where getWidgetCardVariant is called and the variant is applied. These stories test the actual behavior (mobile/side panel triggering side-column variant) rather than just visual appearance, following the existing pattern of individual behavior-testing stories in this file. |
||
|
|
bb18f78f1b |
[Fix] Fix NaN position in notes resulting in not being able to create notes (#16818)
Following [discord thread](https://discord.com/channels/1130383047699738754/1453910755387899996/1453910755387899996), reproductible on twenty-eng https://github.com/user-attachments/assets/ae7f363d-87e1-44fa-8fe2-ee78412d62a7 Records positions are computed at record creation, depending on the position arg from the request, being equal to `last`, `first`, or not present. When being equal to last, as it is done when creating a note from the product, the position is calculated using `.maximum()` function which uses postgres' MAX function. If there is a `NaN` value among the list, the MAX will return `NaN` too. So if for some reason there is a NaN somewhere in the position column, all subsequent records being created with last position argument will be created with NaN value. Until [this PR](https://github.com/twentyhq/twenty/pull/16630), where we introduced a validation on position at record creation which throws when NaN is trying to be introduced as a position, this was going silent. (fyi @etiennejouan , not on you at all but for info) Looking into twenty-eng workspace, I found note records with NaN position dating back to august 2025, making it hard to understand and debug why they were introduced with NaN position. So I did not find the real root cause, but I suggest to - update record-position.service to fix the issue for subsequent records that go through this service (which is what is currently broken) - run a command to fix the existing records with NaN position for Notes, as it is where the issue happened for both the user reporting the issue on discord, and us on twenty-eng. So hopefully the problem was limited to Notes |
||
|
|
ee0e2ed854 |
i18n - translations (#16832)
Created by Github action --------- Co-authored-by: Félix Malfait <felix@twenty.com> Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
343b74666f |
i18n - translations (#16831)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
01e0502fcf |
feat: add updatedBy field to track last record modifier (#16807)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Implements last-modifier tracking and unified actor injection. > > - New `ActorFromAuthContextService` replaces createdBy-only logic; pre-query hooks now inject both `createdBy` and `updatedBy` on create and `updatedBy` on update > - Add `updatedBy` standard field to core/custom objects (e.g., `person`, `company`, `task`, `note`, `attachment`, `dashboard`, `workflow`, `workflowRun`) with IDs, metadata builders, and ORM entity fields > - Record CRUD: `create` now sets both `createdBy` and `updatedBy`; `update` sets `updatedBy`; workflow actions use a shared workflow actor builder; REST base handler uses the new actor service > - Seeder data and snapshots updated to include `updatedBy`; GraphQL result formatting adds defaults/handling for empty composite fields (incl. actor) > - Frontend `useUpdateOneRecord` upserts returned record into the local store after mutation > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1f283778e9cb28a35bf84632a1a2997250bb3131. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
0da5cf29de |
Bump eslint from 9.32.0 to 9.39.2 (#16736)
Bumps [eslint](https://github.com/eslint/eslint) from 9.32.0 to 9.39.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/eslint/eslint/releases">eslint's releases</a>.</em></p> <blockquote> <h2>v9.39.2</h2> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/57058331946568164449c5caabe2cf206e4fb5d9"><code>5705833</code></a> fix: warn when <code>eslint-env</code> configuration comments are found (<a href="https://redirect.github.com/eslint/eslint/issues/20381">#20381</a>) (sethamus)</li> </ul> <h2>Build Related</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/506f1549a64aa65bdddc75c71cb62f0ab94b5a23"><code>506f154</code></a> build: add .scss files entry to knip (<a href="https://redirect.github.com/eslint/eslint/issues/20391">#20391</a>) (Milos Djermanovic)</li> </ul> <h2>Chores</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/7ca0af7f9f89dd4a01736dae01931c45d528171b"><code>7ca0af7</code></a> chore: upgrade to <code>@eslint/js@9.39.2</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20394">#20394</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/c43ce24ff0ce073ec4ad691cd5a50171dfe6cf1e"><code>c43ce24</code></a> chore: package.json update for <code>@eslint/js</code> release (Jenkins)</li> <li><a href="https://github.com/eslint/eslint/commit/4c9858e47bb9146cf20f546a562bc58a9ee3dae1"><code>4c9858e</code></a> ci: add <code>v9.x-dev</code> branch (<a href="https://redirect.github.com/eslint/eslint/issues/20382">#20382</a>) (Milos Djermanovic)</li> </ul> <h2>v9.39.1</h2> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/650753ee3976784343ceb40170619dab1aa9fe0d"><code>650753e</code></a> fix: Only pass node to JS lang visitor methods (<a href="https://redirect.github.com/eslint/eslint/issues/20283">#20283</a>) (Nicholas C. Zakas)</li> </ul> <h2>Documentation</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/51b51f4f1ce82ef63264c4e45d9ef579bcd73f8e"><code>51b51f4</code></a> docs: add a section on when to use extends vs cascading (<a href="https://redirect.github.com/eslint/eslint/issues/20268">#20268</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/b44d42699dcd1729b7ecb50ca70e4c1c17f551f1"><code>b44d426</code></a> docs: Update README (GitHub Actions Bot)</li> </ul> <h2>Chores</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/92db329211c8da5ce8340a4d4c05ce9c12845381"><code>92db329</code></a> chore: update <code>@eslint/js</code> version to 9.39.1 (<a href="https://redirect.github.com/eslint/eslint/issues/20284">#20284</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/c7ebefc9eaf99b76b30b0d3cf9960807a47367c4"><code>c7ebefc</code></a> chore: package.json update for <code>@eslint/js</code> release (Jenkins)</li> <li><a href="https://github.com/eslint/eslint/commit/61778f6ca33c0f63962a91d6a75a4fa5db9f47d2"><code>61778f6</code></a> chore: update eslint-config-eslint dependency <code>@eslint/js</code> to ^9.39.0 (<a href="https://redirect.github.com/eslint/eslint/issues/20275">#20275</a>) (renovate[bot])</li> <li><a href="https://github.com/eslint/eslint/commit/d9ca2fcd9ad63331bfd329a69534e1ff04f231e8"><code>d9ca2fc</code></a> ci: Add rangeStrategy to eslint group in renovate config (<a href="https://redirect.github.com/eslint/eslint/issues/20266">#20266</a>) (唯然)</li> <li><a href="https://github.com/eslint/eslint/commit/009e5076ff5a4bd845f55e17676e3bb88f47c280"><code>009e507</code></a> test: fix version tests for ESLint v10 (<a href="https://redirect.github.com/eslint/eslint/issues/20274">#20274</a>) (Milos Djermanovic)</li> </ul> <h2>v9.39.0</h2> <h2>Features</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/cc57d87a3f119e9d39c55e044e526ae067fa31ce"><code>cc57d87</code></a> feat: update error loc to key in <code>no-dupe-class-members</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20259">#20259</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/126552fcf35da3ddcefa527db06dabc54c04041c"><code>126552f</code></a> feat: update error location in <code>for-direction</code> and <code>no-dupe-args</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20258">#20258</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/167d0970d3802a66910e9820f31dcd717fab0b2a"><code>167d097</code></a> feat: update <code>complexity</code> rule to highlight only static block header (<a href="https://redirect.github.com/eslint/eslint/issues/20245">#20245</a>) (jaymarvelz)</li> </ul> <h2>Bug Fixes</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/15f5c7c168d0698683943f51dd617f14a5e6815c"><code>15f5c7c</code></a> fix: forward traversal <code>step.args</code> to visitors (<a href="https://redirect.github.com/eslint/eslint/issues/20253">#20253</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/5a1a534e877f7c4c992885867f923df307c3929d"><code>5a1a534</code></a> fix: allow JSDoc comments in object-shorthand rule (<a href="https://redirect.github.com/eslint/eslint/issues/20167">#20167</a>) (Nitin Kumar)</li> <li><a href="https://github.com/eslint/eslint/commit/e86b813eb660f1a5adc8e143a70d9b683cd12362"><code>e86b813</code></a> fix: Use more types from <code>@eslint/core</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20257">#20257</a>) (Nicholas C. Zakas)</li> <li><a href="https://github.com/eslint/eslint/commit/927272d1f0d5683b029b729d368a96527f283323"><code>927272d</code></a> fix: correct <code>Scope</code> typings (<a href="https://redirect.github.com/eslint/eslint/issues/20198">#20198</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/37f76d9c539bb6fc816fedb7be4486b71a58620a"><code>37f76d9</code></a> fix: use <code>AST.Program</code> type for Program node (<a href="https://redirect.github.com/eslint/eslint/issues/20244">#20244</a>) (Francesco Trotta)</li> <li><a href="https://github.com/eslint/eslint/commit/ae07f0b3334ebd22ae2e7b09bca5973b96aa9768"><code>ae07f0b</code></a> fix: unify timing report for concurrent linting (<a href="https://redirect.github.com/eslint/eslint/issues/20188">#20188</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/b165d471be6062f4475b972155b02654a974a0e9"><code>b165d47</code></a> fix: correct <code>Rule</code> typings (<a href="https://redirect.github.com/eslint/eslint/issues/20199">#20199</a>) (jaymarvelz)</li> <li><a href="https://github.com/eslint/eslint/commit/fb97cda70d87286a7dbd2457f578ef578d6905e8"><code>fb97cda</code></a> fix: improve error message for missing fix function in suggestions (<a href="https://redirect.github.com/eslint/eslint/issues/20218">#20218</a>) (jaymarvelz)</li> </ul> <h2>Documentation</h2> <ul> <li><a href="https://github.com/eslint/eslint/commit/d3e81e30ee6be5a21151b7a17ef10a714b6059c0"><code>d3e81e3</code></a> docs: Always recommend to include a files property (<a href="https://redirect.github.com/eslint/eslint/issues/20158">#20158</a>) (Percy Ma)</li> <li><a href="https://github.com/eslint/eslint/commit/0f0385f1404dcadaba4812120b1ad02334dbd66a"><code>0f0385f</code></a> docs: use consistent naming recommendation (<a href="https://redirect.github.com/eslint/eslint/issues/20250">#20250</a>) (Alex M. Spieslechner)</li> <li><a href="https://github.com/eslint/eslint/commit/a3b145609ac649fac837c8c0515cbb2a9321ca40"><code>a3b1456</code></a> docs: Update README (GitHub Actions Bot)</li> <li><a href="https://github.com/eslint/eslint/commit/cf5f2dd58dd98084a21da04fe7b9054b9478d552"><code>cf5f2dd</code></a> docs: fix correct tag of <code>no-useless-constructor</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20255">#20255</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/10b995c8e5473de8d66d3cd99d816e046f35e3ec"><code>10b995c</code></a> docs: add TS options and examples for <code>nofunc</code> in <code>no-use-before-define</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20249">#20249</a>) (Tanuj Kanti)</li> <li><a href="https://github.com/eslint/eslint/commit/2584187e4a305ea7a98e1a5bd4dca2a60ad132f8"><code>2584187</code></a> docs: remove repetitive word in comment (<a href="https://redirect.github.com/eslint/eslint/issues/20242">#20242</a>) (reddaisyy)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/eslint/eslint/commit/9278324aa0023d223874825b0d4b6ac75783096a"><code>9278324</code></a> 9.39.2</li> <li><a href="https://github.com/eslint/eslint/commit/542266ad3c58b47066d4b8ae61d419b423acee8f"><code>542266a</code></a> Build: changelog update for 9.39.2</li> <li><a href="https://github.com/eslint/eslint/commit/7ca0af7f9f89dd4a01736dae01931c45d528171b"><code>7ca0af7</code></a> chore: upgrade to <code>@eslint/js@9.39.2</code> (<a href="https://redirect.github.com/eslint/eslint/issues/20394">#20394</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/c43ce24ff0ce073ec4ad691cd5a50171dfe6cf1e"><code>c43ce24</code></a> chore: package.json update for <code>@eslint/js</code> release</li> <li><a href="https://github.com/eslint/eslint/commit/57058331946568164449c5caabe2cf206e4fb5d9"><code>5705833</code></a> fix: warn when <code>eslint-env</code> configuration comments are found (<a href="https://redirect.github.com/eslint/eslint/issues/20381">#20381</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/506f1549a64aa65bdddc75c71cb62f0ab94b5a23"><code>506f154</code></a> build: add .scss files entry to knip (<a href="https://redirect.github.com/eslint/eslint/issues/20391">#20391</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/4c9858e47bb9146cf20f546a562bc58a9ee3dae1"><code>4c9858e</code></a> ci: add <code>v9.x-dev</code> branch (<a href="https://redirect.github.com/eslint/eslint/issues/20382">#20382</a>)</li> <li><a href="https://github.com/eslint/eslint/commit/e2772811a8595d161870835ff04822b25a2cdf45"><code>e277281</code></a> 9.39.1</li> <li><a href="https://github.com/eslint/eslint/commit/4cdf397b30b2b749865ea0fcf4d30eb8ba458896"><code>4cdf397</code></a> Build: changelog update for 9.39.1</li> <li><a href="https://github.com/eslint/eslint/commit/92db329211c8da5ce8340a4d4c05ce9c12845381"><code>92db329</code></a> chore: update <code>@eslint/js</code> version to 9.39.1 (<a href="https://redirect.github.com/eslint/eslint/issues/20284">#20284</a>)</li> <li>Additional commits viewable in <a href="https://github.com/eslint/eslint/compare/v9.32.0...v9.39.2">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com> |
||
|
|
3278950415 |
build(deps-dev): bump msw-storybook-addon from 2.0.5 to 2.0.6 (#16830)
Bumps [msw-storybook-addon](https://github.com/mswjs/msw-storybook-addon/tree/HEAD/packages/msw-addon) from 2.0.5 to 2.0.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/mswjs/msw-storybook-addon/releases">msw-storybook-addon's releases</a>.</em></p> <blockquote> <h2>v2.0.6</h2> <h4>🐛 Bug Fix</h4> <ul> <li>fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> <a href="https://redirect.github.com/mswjs/msw-storybook-addon/pull/178">#178</a> (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <h4>Authors: 1</h4> <ul> <li>Connor Shea (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/mswjs/msw-storybook-addon/blob/main/packages/msw-addon/CHANGELOG.md">msw-storybook-addon's changelog</a>.</em></p> <blockquote> <h1>v2.0.6 (Fri Oct 10 2025)</h1> <h4>🐛 Bug Fix</h4> <ul> <li>fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> <a href="https://redirect.github.com/mswjs/msw-storybook-addon/pull/178">#178</a> (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <h4>Authors: 1</h4> <ul> <li>Connor Shea (<a href="https://github.com/connorshea"><code>@connorshea</code></a>)</li> </ul> <hr /> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/mswjs/msw-storybook-addon/commit/ae7ce4de01bf9665a03816f3ca4908feb5f90653"><code>ae7ce4d</code></a> Update CHANGELOG.md [skip ci]</li> <li><a href="https://github.com/mswjs/msw-storybook-addon/commit/0b9594003ce8226767d51b444bad505db401c387"><code>0b95940</code></a> fix: add a <code>@deprecated</code> tag to the <code>mswDecorator</code> (<a href="https://github.com/mswjs/msw-storybook-addon/tree/HEAD/packages/msw-addon/issues/178">#178</a>)</li> <li>See full diff in <a href="https://github.com/mswjs/msw-storybook-addon/commits/v2.0.6/packages/msw-addon">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> |
||
|
|
3005f7ba41 |
build(deps): bump @opentelemetry/auto-instrumentations-node from 0.60.0 to 0.60.1 (#16828)
Bumps [@opentelemetry/auto-instrumentations-node](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/auto-instrumentations-node) from 0.60.0 to 0.60.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/releases"><code>@opentelemetry/auto-instrumentations-node</code>'s releases</a>.</em></p> <blockquote> <h2>instrumentation-aws-lambda: v0.60.1</h2> <h2><a href="https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-aws-lambda-v0.60.0...instrumentation-aws-lambda-v0.60.1">0.60.1</a> (2025-11-24)</h2> <h3>Dependencies</h3> <ul> <li>The following workspace dependencies were updated <ul> <li>devDependencies <ul> <li><code>@opentelemetry/propagator-aws-xray</code> bumped from ^2.1.3 to ^2.1.4</li> <li><code>@opentelemetry/propagator-aws-xray-lambda</code> bumped from ^0.55.3 to ^0.55.4</li> </ul> </li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/packages/auto-instrumentations-node/CHANGELOG.md"><code>@opentelemetry/auto-instrumentations-node</code>'s changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/open-telemetry/opentelemetry-js-contrib/compare/auto-instrumentations-node-v0.60.0...auto-instrumentations-node-v0.60.1">0.60.1</a> (2025-06-05)</h2> <h3>Dependencies</h3> <ul> <li>The following workspace dependencies were updated <ul> <li>dependencies <ul> <li><code>@opentelemetry/instrumentation-hapi</code> bumped from ^0.48.0 to ^0.49.0</li> <li><code>@opentelemetry/instrumentation-koa</code> bumped from ^0.50.0 to ^0.50.1</li> <li><code>@opentelemetry/instrumentation-mongodb</code> bumped from ^0.55.0 to ^0.55.1</li> <li><code>@opentelemetry/instrumentation-net</code> bumped from ^0.46.0 to ^0.46.1</li> <li><code>@opentelemetry/instrumentation-redis</code> bumped from ^0.49.0 to ^0.49.1</li> <li><code>@opentelemetry/instrumentation-restify</code> bumped from ^0.48.0 to ^0.48.1</li> <li><code>@opentelemetry/instrumentation-undici</code> bumped from ^0.13.0 to ^0.13.1</li> </ul> </li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/open-telemetry/opentelemetry-js-contrib/commits/auto-instrumentations-node-v0.60.1/packages/auto-instrumentations-node">compare view</a></li> </ul> </details> <br /> [](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 merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@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> |
||
|
|
1b6a0cd05a |
fix(billing): redirect to Stripe payment method setup when subscribing without payment method (#16827)
## Summary When users click 'Subscribe Now' during a trial period without a payment method configured, they previously saw an unhelpful error message: "No payment method found. Please update your billing details." This PR improves the UX by redirecting users directly to Stripe's billing portal payment method update flow, where they can add their payment information. After adding a payment method, users are redirected back to the billing settings page and can click 'Subscribe Now' again to successfully activate their subscription. ## Changes ### Backend - **stripe-billing-portal.service.ts**: Added `createBillingPortalSessionForPaymentMethodUpdate` method that creates a Stripe billing portal session with `flow_data.type: 'payment_method_update'` - **billing-portal.workspace-service.ts**: Added `computeBillingPortalSessionURLForPaymentMethodUpdate` method to build the portal URL - **billing-end-trial-period.output.ts**: Added optional `billingPortalUrl` field to the GraphQL output DTO - **billing-subscription.service.ts**: Modified `endTrialPeriod` to return `stripeCustomerId` when no payment method exists - **billing.resolver.ts**: Updated resolver to orchestrate billing portal URL generation when no payment method ### Frontend - **useEndSubscriptionTrialPeriod.ts**: Redirect to billing portal URL instead of showing error snackbar - **endSubscriptionTrialPeriod.ts**: Added `billingPortalUrl` to mutation response fields ## User Flow 1. User clicks "Subscribe Now" during trial 2. Backend checks for payment method 3. If no payment method → redirect to Stripe billing portal payment method update page 4. User adds payment method in Stripe 5. User is redirected back to `/settings/billing` 6. User clicks "Subscribe Now" again to activate subscription |
||
|
|
6bd14dc847 |
i18n - translations (#16825)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
7021a51747 |
feat(billing): implement credit rollover from one billing period to another (#16802)
## Summary This PR implements credit rollover functionality for billing, allowing unused credits from one billing period to carry over to the next (capped at the current period's subscription tier cap). ## Changes ### New Services - **StripeCreditGrantService**: Interacts with Stripe's Billing Credits API to create credit grants, retrieve customer credit balances, and void grants - **BillingCreditRolloverService**: Contains the rollover logic - calculates unused credits and creates new grants for the next period - **BillingWebhookCreditGrantService**: Handles `billing.credit_grant.created` and `billing.credit_grant.updated` webhooks to update billing alerts ### Modified Services - **StripeBillingAlertService**: Updated to include credit balance when calculating usage threshold alerts - **BillingUsageService**: Returns rollover credits to the frontend for display - **BillingSubscriptionService**: Queries credit balance when creating billing alerts - **BillingWebhookInvoiceService**: Triggers rollover processing on `invoice.finalized` webhook ### Frontend - Updated `SettingsBillingCreditsSection` to display base credits, rollover credits, and total available - Updated GraphQL query to fetch new `rolloverCredits` and `totalGrantedCredits` fields ### Stripe SDK Upgrade - Upgraded from v17.3.1 to v19.3.1 to get proper types for billing.credit_grant events - Fixed breaking changes: invoice.subscription path, subscription period fields location, removed properties ## How it works 1. When `invoice.finalized` webhook is received for `subscription_cycle`, the system: - Calculates usage from the previous period - Determines unused credits (tier cap - usage) - Caps rollover at current tier cap - Creates a Stripe credit grant with expiration at end of new period 2. When credit grants are created/updated/voided: - Billing alerts are recreated with the updated credit balance 3. The UI displays: - Base credits (from subscription tier) - Rollover credits (from previous periods) - Total available credits ## Edge Cases Handled - Credit grant voided: `billing.credit_grant.updated` webhook triggers alert update - Credit grant expired: Stripe's `creditBalanceSummary` API excludes expired grants - No unused credits: Rollover service skips grant creation - Customer ID as object: Controller extracts `.id` from expanded customer |
||
|
|
952dee955c |
fix: Stop autoscroll when user manually scrolls up during streaming (#16795)
https://github.com/user-attachments/assets/2ca908ca-63b8-4895-9ed7-7beaeea13ca9 |
||
|
|
7400a3051c |
Small improvements with views (#16821)
- when a view is deleted, it is removed from left menu + from list views in dropdown - deactivated fields are not suggested as options to group records by for a view (only in FE, not forbidden by BE) |
||
|
|
265345fd69 |
fix: prevent infinite loop when metadata version cache is empty (#16816)
## Context
After flushing the Redis cache (e.g., via `cache:flush` command), users
get stuck in an infinite loop showing "Your workspace has been updated
with a new data model. Please refresh the page." - refreshing the page
doesn't help.
## Root Cause
When the cache is flushed, `getMetadataVersion()` returns `undefined`.
The version comparison in the error handler then becomes:
```typescript
requestMetadataVersion !== `${currentMetadataVersion}`
// Evaluates to: "5" !== "undefined" → always true
```
This triggers the schema mismatch error on every request, even after
page refresh.
## History
| Date | Commit | What Happened |
|------|--------|---------------|
| Aug 2024 | #6691 (`17a1760afd`) | Introduced the
`${currentMetadataVersion}` template literal that converts `undefined`
to the string `"undefined"` |
| Dec 2025 | #16536 (`0035fc1145`) | Removed the safety check that would
throw an early error when cache is empty, allowing `undefined` to
propagate |
## Fix
Add `isDefined(currentMetadataVersion)` check before comparing versions.
If the server doesn't have a cached version, we shouldn't treat it as a
mismatch - the schema factory already handles populating the cache when
it actually needs the version.
```typescript
if (
requestMetadataVersion &&
isDefined(currentMetadataVersion) && // ← Added this check
requestMetadataVersion !== `${currentMetadataVersion}`
) {
```
## Testing
1. Flush the cache: `npx nx run twenty-server:command cache:flush`
2. Refresh the page
3. Verify no infinite loop occurs and app loads normally
|
||
|
|
bbdad09399 |
i18n - translations (#16823)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
c020f71ba1 |
Add "number of decimal" on currency field. (#16439)
Closes [571](https://github.com/twentyhq/core-team-issues/issues/571). Replicates the behavior of number field and allows specifying the number of decimals for currency field. <img width="931" height="858" alt="image" src="https://github.com/user-attachments/assets/f5100d58-b1b0-4a88-a090-e98b2feeebd0" /> Currencies around the world have a maximum of three decimal places - BHD, KWD etc. However, I have added a maximum of five decimal places in case someone wants to use the currency field type for displaying things like `per-second-billing` or `exchange rates`. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds configurable decimals (0–5) for currency fields, updating settings UI, types/schema, display/aggregate formatting, and input precision. > > - **Currency field settings**: > - Add `decimals` (0–5) to `FieldCurrencyMetadata.settings` and validate via `currencyFieldSettingsSchema`. > - Update `SettingsDataModelFieldCurrencyForm` to manage `format` (short/full) and `decimals` with counter when `full`; wire defaults via `useCurrencySettingsFormInitialValues`. > - **Display & aggregation**: > - `CurrencyDisplay` and `transformAggregateRawValueIntoAggregateDisplayValue` honor `decimals` when `format` is `full`; keep short format using `formatToShortNumber`. > - **Input**: > - Increase currency `IMaskInput` precision with `scale=5`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 959a8fc1ea726d206548ea32cada28d77c1c6eb9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> |
||
|
|
28dc3e470e |
i18n - translations (#16814)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
874e4e4666 |
i18n - translations (#16813)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
6547c11862 |
i18n - docs translations (#16799)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
06d0ac13c4 |
Ensure record fields uniqueness across widgets (#16781)
This PR dissociates record inputs so that several inputs for the same record field can live on the same page. ## Simple values demo https://github.com/user-attachments/assets/a8c224d8-4cd6-4fe3-9cf8-01f6bdd2fca9 ## Relations demo https://github.com/user-attachments/assets/87267a8b-8ce5-41ce-8a78-cba2384828bb ## Doesn't break Record Table https://github.com/user-attachments/assets/bcdd2b05-7cb4-4ed2-9093-58be3e04e43e ## Doesn't break Show Page https://github.com/user-attachments/assets/f9ab9e14-012c-451e-a35f-01a165523f95 |
||
|
|
6a4974e285 |
feat: enforce credit limits via Stripe alerts for all billing scenarios (#16801)
## Summary This PR ensures usage alerts are created for all billing scenarios. ## Background Per [Stripe documentation](https://docs.stripe.com/billing/subscriptions/usage-based/alerts), usage alerts are **one-time per customer** - they trigger once and only consider usage reported after the alert is created. This means we need to create a new alert whenever: 1. ✅ Subscription is created (trial) - Already implemented 2. ✅ Trial ends (user becomes Active subscriber) - **Added in this PR** 3. ✅ Credit tier changes (upgrade) - **Added in this PR** 4. ✅ **New billing cycle starts** - **Critical fix in this PR!** ## The Issue Previously, the invoice webhook reset `hasReachedCurrentPeriodCap = false` at cycle end, but didn't create a new alert. This meant after the first billing period, there was no alert to trigger and users could exceed their limit without being blocked. ## Changes ### 1. Invoice Webhook (`billing-webhook-invoice.service.ts`) When invoice is finalized for `subscription_cycle`: - Reset `hasReachedCurrentPeriodCap = false` ✅ (already done) - **NEW**: Create alert at the current tier cap ### 2. End Trial Period (`billing-subscription.service.ts`) In `endTrialPeriod()`: - **NEW**: Create alert at the paid tier cap (not trial cap) ### 3. Credit Tier Upgrades (`billing-subscription.service.ts`) In `changeMeteredPrice()`, when upgrading immediately (not scheduled for period end): - **NEW**: Reset `hasReachedCurrentPeriodCap = false` - **NEW**: Create alert at new tier cap ### 4. Alert Title Update (`stripe-billing-alert.service.ts`) Changed from "Trial usage cap" to "Usage cap" since alerts are now used for all scenarios. ## Stripe Alert Limits - Max 25 alerts per meter+customer combination - Alerts only evaluate usage reported after creation - One-time alerts trigger once per customer With monthly billing cycles + occasional tier changes, we should stay well under the 25 alert limit. ## Testing - TypeScript typechecking passes - Backend services properly inject new dependencies |
||
|
|
66daf69a5d |
[Tests E2E] Attempt to improve speed (#16755)
This PR presents an attempt to increase the speed of the tests to run, by using the same front-end built for Front and E2E CIs. It implied merging front and E2E in one CI, but allowed to still have two different status, and to have E2E run even if no front files have changed. Also now using depot to build FE. <img width="270" height="546" alt="image" src="https://github.com/user-attachments/assets/d9eccc62-4494-4102-ad4e-241fec4bd4ea" /> |
||
|
|
dc1bf8dac9 |
Fix Hide empty groups in List view when Group By is enabled (#16752)
Fixed inconsistency where List view (Group By) still showed empty groups while Kanban hides them. Update `visibleRecordGroupIdsComponentFamilySelector` now filters out groups with zero records using `recordIndexRecordIdsByGroupComponentFamilyState` and `recordIndexShouldHideEmptyRecordGroupsComponentState`, ensuring empty groups are consistently hidden across views. Fixes #16212 |
||
|
|
5d6c39ec7e |
i18n - translations (#16800)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> |
||
|
|
08527930d7 |
fix: 🐛 visible fields count updates when toggling field (#16789)
Fixes: #16734 Solution: The ObjectOptionsDropdownDefaultView was reading from recordIndexFieldDefinitionsState via useObjectOptionsForBoard, while field visibility changes update currentRecordFieldsComponentState. This caused the "X shown" count to remain stale after hiding fields. Changed to use visibleRecordFieldsComponentSelector (same state source used by ViewFieldsVisibleDropdownSection) so both components react to the same state updates. https://github.com/user-attachments/assets/62eb5c98-f15f-4ee8-bdce-1ab4e4752f66 |
||
|
|
b46e9d2e64 |
feat: add AI chat error handling for billing and API key errors (#16797)
## Summary This PR adds user-friendly error handling for AI chat features, specifically for **billing credits exhausted** and **API key not configured** errors. ## Changes ### Backend - Added `BILLING_CREDITS_EXHAUSTED` exception code with 402 status - Added `API_KEY_NOT_CONFIGURED` exception code with 503 status - Added billing check before AI chat streaming in `agent-chat.controller.ts` - Added error code to HTTP exception response body for frontend error type detection - Created `AgentRestApiExceptionFilter` for agent-specific errors ### Frontend - Created `AIChatBanner` - reusable banner component for error/warning messages - Created `AIChatCreditsExhaustedMessage` - shows upgrade prompts based on user permissions - Created `AIChatApiKeyNotConfiguredMessage` - shows configuration guidance with docs link - Created `AIChatErrorRenderer` - encapsulates error type switching logic (fixes nested ternary) - Created `AIChatStandaloneError` - displays errors when there are no messages - Split `aiChatErrorUtils.ts` into separate files (1 export per file): - `AIChatErrorCode.ts` - `extractErrorCode.ts` - `isAIChatErrorOfType.ts` - `isBillingCreditsExhaustedError.ts` - `isApiKeyNotConfiguredError.ts` - Added comprehensive test coverage (27 tests) ### Other - Updated trial period banner messaging ## Testing - All lint checks pass - All 27 new tests pass - TypeScript typecheck passes |