Commit Graph
9524 Commits
Author SHA1 Message Date
Paul RastoinandGitHub a6415db775 Refactor workspace migration and validation error types and centralize runner optimistic rendering (#16920)
# Introduction

In this PR we're:
- Refactoring the workspace migration action type introducing grain over
metadata and operation type ( for example operation `create` and
metadata `field` )
- Thanks to above point we can now factorize the runner optimistic
rendering out of each runner actions-handler file using the existing
into the generic one ( -3200 lines of code here )
- Still thanks to action type refactor we're able to dynamically compose
the response error type only send data when there's here. No more static
counter and static summary error message. This way we won't have to re
run snapshot every time we add a new entity to the engine ( huge
snapshot diff here )

## Noticeable points:
- We introduce an index update action to avoid any complex typing for
not having one or a tuple of actions instead. Now the drop and insert
logic is directly inferred from the update action handler instead of
being two action ( delete index and create index )

## TODO
- [x] Define base actions types
- [x] Migrate all actions to action type and metadata name pattern (
base actions )
- [x] Refactor flat entity validation type to embed metadata name
- [x] Refactor optimistic rendering within runner
- [x] Refactor legacy cache invalidation switch
- [x] Refactor response error format ( dynamic counter again + no empty
entries )
- [x] Try factorizing and removing redundant nor unused type declaration
in metadata actions type intermediary files
- [x] Adapt front to new response error format

## Remarks
- ~~Should create an issue for generic replace flat entity in related
flat entity maps~~ overkill
- Should create an issue for oneToMany foreignKey being nullable not
always cascade delete optimistic rendering edge case to either docs or
fix it in delete flat entity and related entity ( re-code the pg
cascading behavior )
- We could also factorize the builder to only implement validators and
not the intermediary file
2026-01-05 10:17:16 +01:00
Paul RastoinandGitHub 9b38254256 Refactor runner dynamic cache invalidation (#16913)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/1792
Refactoring the cache to invalidate to be more precise and prevent any
corrupted cache occurrences

## Next
The load dependency cache from the workspace migration, that's not
optimal it should be smart enough to infer it from the actions
themselves. For the moment their definition isn't granular enough and
inferring such info would be very dirty
2026-01-03 02:51:07 +01:00
Paul RastoinandGitHub 42c9ae1ebc Centralize metadata relations constant + simplification (#16901)
# Introduction
As we introduced a new grain on relation extraction thanks to low level
`SyncableEntity` and `WorkspaceRelatedEntity` we're able to strictly
typesafe extract metadata entity

The new constant centralizes both many to one and one to many constants
metadata entity constants in a more strictly typesafe way. Remains only
the flatEntityForeignKey aggregator which has to be chosen manually
across all available targeted flat entity ids properties
2026-01-02 16:49:06 +01:00
3cab1bf80b i18n - translations (#16909)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-01-02 15:36:03 +01:00
Félix MalfaitandGitHub 21ff42074d feat: implement skills system for AI agents (#16865)
## Summary
This PR introduces a Skills system for AI agents, inspired by the [Agent
Skills specification](https://agentskills.io/specification).

## Changes

### Backend
- **SkillEntity**: New database entity with migration for storing skills
- **V2 Sync Mechanism**: Implemented FlatSkill, builders, validators,
and action handlers following the v2 flat entity pattern
- **Standard Skills**: Pre-defined skills (workflow-building,
data-manipulation, dashboard-building, metadata-building, research,
code-interpreter, xlsx, pdf, docx, pptx)
- **GraphQL API**: CRUD operations for skills with proper guards and
permissions
- **Workspace Cache**: Integrated skills into the workspace cache system

### Frontend  
- **Skills Table**: Searchable table in AI settings showing all skills
- **Skill Form**: Create/edit page with Label (primary), Description,
and Content (markdown editor)
- **API Name**: Following existing patterns, name is derived from label
with advanced settings toggle for custom API names
- **Standard vs Custom**: Standard skills are read-only, custom skills
can be edited/deleted

## Key Design Decisions
- Skills are stored in the database (Salesforce-like approach) rather
than files
- Name is derived from Label by default (isLabelSyncedWithName pattern)
- Skills reference functions/files via @ mentions in markdown content
rather than explicit relations
- Standard skills are synced from code, custom skills are created via UI

## Screenshots
Skills table and form UI follow existing settings patterns.

## Testing
- [x] Lint passes
- [x] Typecheck passes
- [ ] CI tests
2026-01-02 14:22:01 +00:00
2a3fd788ae i18n - translations (#16908)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-01-02 14:24:15 +01:00
EtienneandGitHub 300738e8cb Fix database event emission (#16759)
Fixes https://github.com/twentyhq/private-issues/issues/395


When calling `removeUserFromWorkspaceAndPotentiallyDeleteWorkspace` from
`user.service`,
```
        await workspaceMemberRepository.delete({
          userId: userWorkspace.userId,
        });
```
related database event is not emitted.

Same issue with update has been fixed
[here](https://github.com/twentyhq/twenty/pull/13287/changes)

The database event is not emitted because `await
eventSelectQueryBuilder.getOne()` in `workspace-delete-query-builder`
returns `null`. This happens because the `selectQueryBuilder` has no
entity—the database request is sent and the raw result is not `null`,
but the entity is `null`, causing the final result to be null.

It can be fixed the same way update has been fixed, updating the
`workspace-entity-manager`
- Pros : consistant with update but we should not forget to fix
softDelete and restore
- Cons : `workspace-entity-manager` is a copy of typeORM logic +
permission injection. Should it be more ?
 
Alternatively (as featured in this PR), it can be fixed by updating
computeEventSelectQueryBuilder, inspired by TypeORM's logic in
typeorm/query-builder/QueryBuilder.js at line 67.
- Pros : it fit with typeORM logic + It fixes all repository operations
2026-01-02 14:23:47 +01:00
EtienneandGitHub ecd41fc9cb Reduce complexity on groupBy query (#16803)
fixes https://github.com/twentyhq/core-team-issues/issues/2009
2026-01-02 14:19:40 +01:00
Paul RastoinandGitHub 98a9ae2a0e Migrate view filter group to v2 (#16876)
## Introduction
On the side hanlded PR with a // agents on another repo
Made several iterations to fix behavior and direction
Find below auto-generated PR description

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

Created generic tooling for entity circular dep checking, will be useful
for permissions validation too @Weiko


## Migrate `viewFilterGroup` entity to v2 flat architecture

### Summary
Migrates the `viewFilterGroup` entity from v1 to the v2 flat entity
architecture, following the established patterns for other v2 entities
like `viewFilter`, `view`, and `viewField`.

### Changes

**Types & Constants**
- Added `FlatViewFilterGroup` and `FlatViewFilterGroupMaps` types
- Added editable properties constant for `viewFilterGroup`
- Registered `viewFilterGroup` in `ALL_METADATA_NAME`,
`ALL_METADATA_RELATION_PROPERTIES`,
`ALL_METADATA_MANY_TO_ONE_RELATIONS`, and related constants

**Cache Service**
- Created `WorkspaceFlatViewFilterGroupMapCacheService` with proper
relation loading for `viewFilters` and `childViewFilterGroups`
- Updated `WorkspaceFlatViewMapCacheService` to load `viewFilterGroups`
relation

**Builder & Validator**
- Created `WorkspaceMigrationV2ViewFilterGroupActionsBuilderService`
- Created `FlatViewFilterGroupValidatorService` with creation, update,
and deletion validation
- Integrated validation into the orchestrator service (runs before
`viewFilter` validation)

**Action Handlers**
- Created create, update, and delete action handlers for
`viewFilterGroup`

**Service Migration**
- Rewrote `ViewFilterGroupService` to use v2 migration pattern with
`WorkspaceMigrationValidateBuildAndRunService`
- Created utility functions for transforming DTOs to flat entities

**Database Migration**
- Added migration to make `parentViewFilterGroupId` foreign key
deferrable (handles self-referential parent/child insertions)

**ViewFilter Integration**
- Added `viewFilterGroupId` validation in
`FlatViewFilterValidatorService`
- Updated `viewFilter` many-to-one relations to include
`viewFilterGroup`

**Tests**
- Added integration tests for successful creation, update, deletion, and
destruction
- Added failing test cases for non-existent entities and invalid
references
- Added failing test for `viewFilter` creation with non-existent
`viewFilterGroupId`

### Breaking Changes
None - existing API contracts are preserved.
2026-01-02 14:16:01 +01:00
0adbe439d5 i18n - translations (#16895)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-01-01 15:35:33 +01:00
29de8ffba6 i18n - translations (#16894)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-01-01 15:20:55 +01:00
Paul RastoinandGitHub 1d9eb07ee0 Relation field metadata strict validation (#16890)
# Introduction

Now validating relation related object and field foreignkey integrity
2026-01-01 15:09:48 +01:00
Abdul RahmanandGitHub dff5e3cd7b feat: Add If/Else node (#16833)
Closes [#1265](https://github.com/twentyhq/core-team-issues/issues/1265)
2026-01-01 14:05:56 +00:00
Félix MalfaitandGitHub 5d5fd5fca5 fix: cache storybook-static folder to prevent EEXIST errors in tests (#16892)
## Problem

The `front-sb-test` jobs were sometimes failing with:
```
Error: EEXIST: file already exists, mkdir './storybook-static/images/icons/android'
```

## Root Cause

1. `front-sb-build` builds storybook and saves NX cache (but NOT
`storybook-static/` folder)
2. `front-sb-test` restores NX cache - NX thinks build is done, but
`storybook-static/` doesn't exist
3. `storybook:serve:static` depends on `storybook:build`, so NX re-runs
the build
4. Race condition in Storybook's file copy causes EEXIST error

The `storybook-static` folder was **never** included in the cache paths
- I verified this by checking git history back to when the save-cache
action was created.

## Solution

Add `storybook-static` to the `additional-paths` for both save and
restore cache steps. This ensures the built storybook is properly cached
and restored, eliminating the need for a rebuild during tests.
2026-01-01 14:24:43 +01:00
1d124a7a77 Enabled RLS seed dev (#16884)
And remove IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Removes deprecated feature flag and enables RLS predicates in dev**
> 
> - Deletes `IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED` from server enum
and frontend generated GraphQL types
> - Updates dev seeder to enable
`IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED` instead of the removed flag
> - Adjusts tests and mocked `GlobalWorkspaceDataSource` defaults to
drop the removed flag
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7f4d5a401a. 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>
2026-01-01 13:55:46 +01:00
Félix MalfaitandGitHub b521f53d24 fix: add NODE_OPTIONS to storybook build to prevent OOM errors (#16889)
## Description

The CI was failing with 'JavaScript heap out of memory' errors during
storybook builds:

```
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
```

The build was consuming ~6.4GB of memory before crashing.

## Solution

This inlines `NODE_OPTIONS='--max-old-space-size=10240'` directly in the
storybook build command, following the same pattern used for other
memory-intensive builds in the codebase (e.g., `front-build` job in CI).

## Notes

- The `project.json` had an `env` option with `NODE_OPTIONS`, but it
used underscores (`max_old_space_size`) instead of hyphens
(`max-old-space-size`), and the `env` option may not be reliably passed
through the `nx:run-commands` executor to subprocesses.
- Inlining the env variable in the command is more reliable and matches
the pattern used elsewhere in the codebase.
2026-01-01 09:34:12 +01:00
BOHEUSandGitHub daca127aa6 Update Mailchimp synchronizer README (#16885)
Leftover nitpick from #16875
2025-12-31 22:49:37 +01:00
9a5c2e4cea i18n - translations (#16882)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-31 16:34:31 +01:00
BOHEUSandGitHub 54332746a5 Disabling data import to actor type fields (#16867)
Fix for #15314
2025-12-31 16:31:54 +01:00
23f6acb43c i18n - translations (#16881)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-31 16:21:00 +01:00
15b21570ae Row level permissions - POC 1 (#16599)
## Context
This PR adds the core structure for RLS implementation:
- RLS data model
- RLS service layer
- RLS WorkspaceMigration and Syncable Entity + cache + Validations
- RLS resolver layer
- ORM layer with RLS Predicate to ORM WHERE clause conversion with
workspaceMember record transposition

Tests are missing though

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Establishes core row-level permissions infrastructure and enforcement
across the stack.
> 
> - Backend: new `rowLevelPermissionPredicate` and
`rowLevelPermissionPredicateGroup` entities, TypeORM migration, feature
flag `IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED`, flat-entity
maps/cache wiring, services and GraphQL resolvers for CRUD, and
inclusion of `workspaceMember` in auth context
> - ORM: applies row-level permission predicates to SELECT, DELETE, and
SOFT DELETE query builders; propagates context through
GlobalWorkspaceOrmManager/EntityManager
> - GraphQL: generated schema/types/queries/mutations for
creating/updating/deleting/fetching predicates and groups
> - Frontend: settings page adds a gated "Record-level" section
(placeholder) and metadata error handler labels for new entities
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fe955cc458. 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>
2025-12-31 16:15:17 +01:00
888a50c3be feat: batch updating (#16384)
#16383 

## Scope & Context
**Context**:
Added a **Bulk Update** feature to allow users to modify multiple
records simultaneously. This addresses the need for efficient data
management when dealing with large datasets.

**Scope**:
Enabling a "Bulk Update" flow that can be triggered for a filtered list
of records (e.g., current view). The feature guides the user through
selecting fields to modify, inputting new values, and executing the
update with real-time progress feedback.

## Current behavior
Currently, users must open and update records one by one.
To change the "Status" of 10 different opportunities, the user has to
navigate to each record detail page or use the inline cell editor 10
separate times. This is repetitive and time-consuming.

## Expected behavior
Users can trigger "Update Records" from the command menu or action bar.
1. **Choose Fields**: A step where users select which properties they
want to modify (e.g., check "Status" and "Assignee").
2. **Input Values**: Users provide the new values for the selected
fields.
3. **Execution**: Upon confirmation, the system updates all matching
records in the background.
4. **Feedback**: A progress indicator shows the number of processed
records, and a toast notification confirms completion.

*Key interactions:*
- Users can clear a field's value (set to null) by selecting the field
but leaving the input empty.
- The operation supports cancelling midway.


https://github.com/user-attachments/assets/c87366a3-246e-4615-9941-0bf63d70df86

## Technical inputs
**Core Functionality**:
- **Incremental Batch Processing**: Updates are performed in small
batches (using `useIncrementalUpdateManyRecords` to handle large
datasets without timing out or freezing the UI.
- **Global Feedback**: Integrated with the Snackbar system to notify
users of success or errors across the application.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces localization keys and generated messages to support the new
bulk update workflow.
> 
> - New strings for command menu selection info: `{totalCount} selected`
> - Footer actions for bulk update: `Apply`, `Cancel` in
`UpdateMultipleRecordsFooter`
> - Toasts in `UpdateMultipleRecordsContainer`: `Successfully updated
{count} records`, `Failed to update records. Please try again.`
> - Action labels: `Update`, `Update records` in
`DefaultRecordActionsConfig` and command menu hook
> - Adds/updates entries across multiple locale `.po` files and
regenerates `af-ZA` messages
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b1dce4c599. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Samuel Arbibe <samuelarbibe@Samuels-MacBook-Pro.local>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-12-31 15:02:27 +00:00
BOHEUSandGitHub 145790840d Update twenty-sdk to newest version in apps (#16875) 2025-12-31 15:41:42 +01:00
Paul RastoinandGitHub d6acef24d4 Fix timeline activities display (#16880)
Fixes https://github.com/twentyhq/twenty/issues/16809

# Introduction
Front was expected timeline activities field to be relation and not
morph relation

Also fixed the new v2 workspace creation that had a bug in the
createStandardRelation util ( it's not in production yet so everything's
fine )
2025-12-31 13:42:56 +00:00
Abdul RahmanandGitHub 229916def2 Fix: Change opportunity kanban view aggregate operation from MIN to SUM (#16879)
Closes #16806
2025-12-31 12:58:20 +00:00
Félix MalfaitandGitHub 73d2027391 fix: centralize lint:changed configuration in nx.json (#16877)
## Summary

The `lint:changed` command was not using the correct ESLint config for
`twenty-server`, causing it to use the root `eslint.config.mjs` instead
of the package-specific one. This PR fixes the issue and renames the
command to `lint:diff-with-main` for clarity.

## Problem

- `twenty-front` correctly specified `--config
packages/twenty-front/eslint.config.mjs`
- `twenty-server` just called `npx eslint` without specifying a config
- This meant `twenty-server` was missing important rules like:
  - `@typescript-eslint/no-explicit-any: 'error'`
  - `@stylistic/*` rules (linebreak-style, padding, etc.)
  - `import/order` with NestJS patterns
- Custom workspace rules (`@nx/workspace-inject-workspace-repository`,
etc.)

## Solution

1. **Renamed** `lint:changed` to `lint:diff-with-main` to be explicit
about what the command does
2. **Centralized** the configuration in `nx.json` targetDefaults:
- Uses `{projectRoot}` interpolation for paths (resolved by Nx at
runtime)
   - Each package automatically uses its own ESLint config
- Packages can override specific options (e.g., file extension pattern)
3. **Simplified** `project.json` files by inheriting from defaults

## Usage

```bash
# Lint only files changed vs main branch
npx nx lint:diff-with-main twenty-front
npx nx lint:diff-with-main twenty-server

# Auto-fix files changed vs main
npx nx lint:diff-with-main twenty-front --configuration=fix
```

## Changes

- **nx.json**: Added `lint:diff-with-main` target default with
configurable pattern
- **twenty-front/project.json**: Simplified to inherit from defaults
- **twenty-server/project.json**: Overrides pattern to include `.json`
files
- **CLAUDE.md** and **.cursor/rules**: Updated documentation
2025-12-31 13:47:20 +01:00
Paul RastoinandGitHub eeb91d9a96 [DO_NOT_RELEASE_MAIN_UNTIL_MERGED] Prevent migration failure due to workspace orphan metadata rows (#16863)
# Introduction
The `AddWorkspaceForeignKeys1767002571103` migration would fail when
released in production right now, as `foreignKey` be applicable as
there's a lof of orphan entries in database

As a workaround in order not to block any patch release we're
fallbacking the migration using save point and an upgrade command that
will attempt to apply the `foreignKey` on every workspace upgrade until
it succeed

We should keep in mind that any new fresh self installation will have
the foreignKey double checked that it would not implies regression on
workspace deletion using the integration tests

## Cleaning upgrade command
We won't implement the cleaning command in this PR yet either will I as
discussed with @Weiko someone else might be taking the subject starting
next week

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Strengthens workspace data integrity and makes the FK migration
resilient.
> 
> - Adds `upgrade:1-16:add-workspace-foreign-keys-migration` command to
apply `workspaceId` FKs once per run; wires into
`V1_16_UpgradeVersionCommandModule` and 1.16 upgrade sequence
> - Refactors migration `1767002571103` to use
`addWorkspaceForeignKeysQueries` util and wrap in a savepoint,
swallowing errors to avoid blocking releases
> - Extracts FK DDL into
`utils/1767002571103-addWorkspaceForeignKeys.util` for reuse by command
and migration
> - Removes duplicate `workspaceId` columns from entities (e.g.,
`cronTrigger`, `databaseEventTrigger`, `indexMetadata`,
`objectMetadata`, `roleTarget`, `role`, `serverlessFunction`) relying on
`SyncableEntity`; keeps indexes/relations
> - Marks legacy delete paths as deprecated; temporarily extends
`WorkspaceManagerService.delete` to also delete `serverlessFunction` by
`workspaceId`
> - Updates wiring to inject `ServerlessFunctionEntity` repository in
`workspace-manager` module/service and corresponding unit test
> - Extends integration tests and adds GraphQL helpers to create
serverless functions and triggers; verifies cascade deletion of related
metadata on workspace removal
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6805bf5d1b32828b4bb1e9f130bfe6e478f66aee. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-12-31 11:52:21 +00:00
Félix MalfaitandGitHub f8fa709abf refactor: Migrate CRUD services to use Common API (#16869)
This PR migrates the workflow CRUD services to use the Common API
(CommonQueryRunners) instead of directly accessing TwentyORM.

## Changes

- Created CommonApiContextBuilderService to build context for Common API
- Migrated CreateRecordService to use CommonCreateOneQueryRunnerService
- Migrated UpdateRecordService to use CommonUpdateOneQueryRunnerService
- Migrated DeleteRecordService to use CommonDeleteOneQueryRunnerService
- Migrated FindRecordsService to use CommonFindManyQueryRunnerService
- Migrated UpsertRecordService to use Common API with upsert flag
- Removed unused get-selected-columns-from-restricted-fields.util.ts
- Updated module dependencies

## Benefits

- Consistent permission checking via Common API
- Query hooks (before/after execution)
- Automatic input transformation
- Same behavior as REST/GraphQL APIs
- Reduced code duplication
2025-12-31 10:24:50 +01:00
Félix MalfaitandGitHub 009e7e05f2 feat(workflow): use authContext in CRUD services for Common API migration (#16857)
## Summary

This PR migrates workflow CRUD operations to properly use the Common API
layer's authentication context, addressing the issues from the reverted
PR #15875.

The original PR was reverted because the Common API required passing
either a User or an API Key for authentication, which was problematic
for workflows. Since then, the "Application" concept was introduced in
the Common API layer, allowing for token injection in serverless
functions.

This PR leverages the "Twenty Standard Application" concept for
non-manual workflow triggers, providing a clean authentication path
without the issues of user impersonation.

## Changes

### Core Infrastructure
- **RecordCrudExecutionContext**: Replace `workspaceId` with full
`authContext`
- **WorkflowExecutionContext**: Add `authContext` field to carry
authentication info
- **ToolGeneratorContext/ToolSpecification**: Add optional `authContext`
support for tool generation

### Authentication Flow
- **WorkflowExecutionContextService**: Build appropriate auth context
based on trigger type:
- **Manual triggers**: Use user's workspace auth context with their role
permissions
- **Non-manual triggers**: Use Twenty Standard Application auth context
(bypasses permission checks or uses default serverless function role)
- **ApplicationService**: Add `findTwentyStandardApplicationOrThrow`
method to retrieve the system application
- **UserWorkspaceService**: Make relations configurable in
`getUserWorkspaceForUserOrThrow` to load only what's needed

### CRUD Services Migration
All 5 record CRUD services now receive `authContext` instead of
`workspaceId`:
- `CreateRecordService`
- `UpdateRecordService`
- `DeleteRecordService`
- `FindRecordsService`
- `UpsertRecordService`

### Workflow Actions
All record CRUD workflow actions pass `executionContext.authContext` to
the services:
- `CreateRecordWorkflowAction`
- `UpdateRecordWorkflowAction`
- `DeleteRecordWorkflowAction`
- `FindRecordsWorkflowAction`
- `UpsertRecordWorkflowAction`

### AI Agent Integration
- AI agent workflow action passes auth context to agent executor
- Tool provider and MCP protocol service support auth context
propagation

## Benefits
-  Proper authentication for workflow CRUD operations via Common API
-  Non-manual triggers use system application context (no user
impersonation issues)
-  Manual triggers preserve user permissions correctly
-  Foundation for better permission handling in automated workflows
-  Cleaner separation between user-initiated and system-initiated
operations

## Related
- Reverted PR: #15875
2025-12-30 21:36:15 +01:00
Abdullah.andGitHub 62e496f65d Do not display border bottom for last widget of tab (#16856)
Closes [2030](https://github.com/twentyhq/core-team-issues/issues/2030).

Determines if a widget is the last visible widget in its parent tab. The
hook:
- Finds the tab containing the widget
- Filters widgets based on visibility rules (respects conditionalDisplay
and edit mode)
- Returns true if the current widget is the last in the filtered list
- Updated `WidgetCard`: Added isLastWidget prop to conditionally apply
border-bottom for the side-column variant
- Updated `WidgetRenderer`: Integrates the hook and passes isLastWidget
to WidgetCard
2025-12-31 01:28:59 +05:00
656a32be73 fix(twenty-front): properly manage focus stack in useInlineCell hook (#16309)
The useInlineCell hook was only managing the dropdown focus state
(activeDropdownFocusIdState/previousDropdownFocusIdState) but not the
focus stack (focusStackState). Since the hotkey system checks
currentFocusIdSelector which reads from focusStackState, closing an
inline cell in the side panel would leave the focus stack in an
incorrect state, causing hotkeys to not work properly.

This fix adds proper focus stack management:
- openInlineCell: pushes the inline cell to the focus stack
- closeInlineCell: removes the inline cell from the focus stack

Fixes #16224

### Tests Added
- Added unit tests for
[useInlineCell](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-front/src/modules/object-record/record-inline-cell/hooks/useInlineCell.ts:15:0-83:2)
hook to verify focus stack management
- Tests cover: opening inline cell, closing inline cell, and full
open/close cycles
- Tests ensure `focusStackState` and `activeDropdownFocusIdState` are
properly synchronized

---------

Co-authored-by: Joker <apple@Apples-MacBook-Pro.local>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-12-30 19:57:59 +00:00
Félix MalfaitandGitHub 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"
```
2025-12-30 18:02:04 +01:00
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
b309815700. 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>
2025-12-30 16:52:17 +00:00
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>
2025-12-30 16:49:31 +00:00
MarieandGitHub 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)
2025-12-30 15:57:38 +00:00
Paul RastoinandGitHub 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
2025-12-30 15:02:07 +00:00
Baptiste DevessierandGitHub 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
2025-12-30 14:43:58 +00:00
WeikoandGitHub 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.
2025-12-30 15:16:57 +01:00
Paul RastoinandGitHub 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[];
  };

```
2025-12-30 13:47:02 +00:00
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>
2025-12-30 14:05:26 +01:00
Harshit SinghandGitHub 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
2025-12-30 11:29:30 +01:00
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
7a8164cd2d. 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>
2025-12-30 09:34:08 +00:00
d39f105a03 i18n - translations (#16849)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-30 10:21:48 +01:00
MarieandGitHub 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.
2025-12-30 09:08:43 +00:00
7522ff6675 i18n - translations (#16848)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-30 10:03:15 +01:00
418377b867 i18n - translations (#16847)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-30 09:51:57 +01:00
Félix MalfaitandGitHub 4f1f0eb177 Redesign Object/Field tables (#16844)
Redesign the data model pages for more clarity / better distinction
between fields and relations
2025-12-30 09:49:55 +01:00
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
3766bac15e. 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>
2025-12-30 09:46:10 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Abdullah
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@monaco-editor/react&package-manager=npm_and_yarn&previous-version=4.6.0&new-version=4.7.0)](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>
2025-12-29 20:01:05 +01:00
Félix MalfaitandGitHub 3a673f99ba Disable updated By 2 (#16840)
Prepare for release, will re-enable them
2025-12-29 18:57:17 +01:00