# Introduction
Extracting the legacy fields build and dispatch out of the object one to
follow the generic flat entity build, also update caches entries for
object
## Main tasks
- flat field map cache
- flat field builder
- refactored the dispatch matrix to return flat entity maps instead of
flat entity arrays
- orchestrator aggregator
- removing legacy code
- making universal identifier aka standardId of standard field for
custom object deterministically dynamic
- perfs debug logs for v2
## TODO
- [x] Refactor the generic entity builder to be dependency flat maps in
order to main foreign keys list in flat parent
- [x] Refactor the flat object metadata to contain the array of related
fields and avoid costy find object fields
- [ ] Improve the create field handler to handle multiple field at once
- [ ] Refactor the dispatch to embbed the comparison
- [ ] Improve perf by extracting from elements out of existing
- [ ] Fix the labelIdentifierId validators on object before field
creation ( integ tests are in failing mode )
## Debug logs snippet
```ts
[EntityBuilder fieldMetadata] matrix computation: 0.027ms
[EntityBuilder fieldMetadata] creation validation: 0.001ms
[EntityBuilder fieldMetadata] deletion validation: 0.293ms
[EntityBuilder fieldMetadata] update validation: 0.006ms
[EntityBuilder fieldMetadata] entity processing: 0.363ms
[EntityBuilder fieldMetadata] validateAndBuild: 0.455ms
[EntityBuilder index] matrix computation: 0.005ms
[EntityBuilder index] creation validation: 0.001ms
[EntityBuilder index] deletion validation: 0.146ms
[EntityBuilder index] update validation: 0.004ms
[EntityBuilder index] entity processing: 0.199ms
[EntityBuilder index] validateAndBuild: 0.228ms
[Runner] Initial cache retrieval: 0.549ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForWorkspaceSchema: 11.665ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForMetadata: 12.864ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 1.476ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 6.816ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 0.062ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 0.889ms
[Runner] Transaction execution: 23.434ms
[Runner] Cache invalidation: 316.662ms
[Runner] Total execution: 340.767ms
```
As you can see cache invalidation is way to long, we could replace the
cache by the optimistic in the end
Fixes https://github.com/twentyhq/twenty/issues/14766
To reproduce
1. create a view with a any field filter and save it. After, remove any
field filter clicking on the X on the chip. No "Update view" shows.
2. now add another regular filter to the view and save it. Now remove
any field filter clicking on the X on the chip and remove the regular
filter you just added. Now "Update view" shows, click it and refresh the
page. Any field filter still shows
There were two problems
1. UpdateViewButtonGroup is in charge of showing "Update View" button.
But is never mounted if shouldExpandViewBar is falsy.
shouldExpandViewBar was not considering
viewAnyFieldFilterDifferentFromCurrentAnyFieldFilter so even if any
field filter had changed, UpdateViewButtonGroup still wasn't going to
show "Update view" button because it wasn't mounted
2. At save time, we added anyFieldFilterValue to the mutation payload if
```
...(view.anyFieldFilterValue && {
anyFieldFilterValue: view.anyFieldFilterValue,
}),
```,
but in JS an empty string evaluates to falsy.
twenty-cli serverless triggers follow up. Fixes:
- eventName don't support wildcard
- universalIdentifier not used to create or update trigger : update does
not work properly (does deletion then creation)
- add a base project in twenty-cli that is copied when creating a new
app
In this PR https://github.com/twentyhq/twenty/pull/14785 we deprecated
viewFilterOperand (from camelCase to capital snakeCase values), but we
had not migrated the existing workflow steps values. Hence they cannot
be executed!
Let's fix that by dealing with both operands, new and deprecated, to
mitigate the issue. Then we will add a command to migrate the values.
Tested :
- server level ok
- workspace level ok
- server level without canImpersonate or without allow impersonation -
fail ok
- workspace level without permission - fail ok
- add serverlessFunction schema in twenty-cli
- add trigger schema in twenty-cli
- update serverless function code save and get
- sync serverless function
# Calendar View: Add "+" Button to Calendar Day Cards
## Description
This PR implements the "+" button on calendar day cards in the Month
view, allowing users to create new records directly from the calendar.
- The "+" button appears **on hover** only.
- Newly created records include the **day representing the card** in the
payload (UTC, with only the date part).
- Respects **object permissions** and **soft delete filters**.
- Automatically integrates with **active filters** used in Table and
Kanban views.
## Implementation Notes
- `RecordCalendarAddNew` component handles button visibility and record
creation.
- UTC date is passed to the create function to ensure proper timezone
handling.
- No unit tests added yet (need senior guidance).
---
[Screencast from 2025-09-24
20-10-18.webm](https://github.com/user-attachments/assets/bd117b43-6c1b-4267-874f-b36844733d9e)
### Video ->
## Related Issues
Fixes: https://github.com/twentyhq/core-team-issues/issues/1552
---------
Co-authored-by: Weiko <corentin@twenty.com>
Legacy from early v2 implementation, we don't want to store relation ids
in the cache as the new implementation handle that with flat entities
properly already.
This causes some issues because when we return the updated view, it
contains an array of viewField objects with only the id in it so gql
complains because some fields are non-nullable in the output and the
resolver can't resolve viewField directly because viewField is in the
output (not complete though) already so it just ignores it.
Following https://github.com/twentyhq/twenty/pull/14762
In this PR
- moved logic around any field filter formatting to twenty-shared
- added any field filter to the filters applied to groupBy when viewId
is defined
- added integration test
In the BE we have stored filter operand as IS_EMPTY, IS_NOT_EMPTY, etc.
For some reason in the FE we were manipulating IsEmpty, IsNotEmpty, etc.
(maybe because they were used before in Views before they were moved to
core)
So we were converting the operands in the FE from IS to Is
(convertViewFilterOperandFromCore) to read and manipulate viewFilters,
and then back to BE version to send mutations etc., from Is to IS
(convertViewFilterOperandToCore).
The migration is now over, so we can remove and simplify that code.
(In the 1-5:migrate-views-to-core command we still do the migration from
Is format to IS format.)