Commit Graph

102 Commits

Author SHA1 Message Date
a374922902 Cannot delete label identifier associated field (#6340)
## Context
An object should always have a labelIdentifier (would be its primary key
at least). If the associated field is deleted by a user, it will break
the app. Ideally we should handle that on the DB level but we don't have
a FK for this column yet.
In the meantime I'm adding the validation check in the backend, note
that this is already handle on the FE side since the "archive/delete"
buttons don't appear for such fields so you need to reassign it to
another field first which is the desired behaviour.
2024-07-19 15:57:40 +02:00
67e2d5c73a Add label identifier to object decorator (#6227)
## Context
LabelIdentifier and ImageIdentifier are metadata info attached to
objectMetadata that are used to display a record in a more readable way.
Those columns point to existing fields that are part of the object.
For example, for a relation picker of a person, we will show a record
using the "name" labelIdentifier and the "avatarUrl" imageIdentifier.
<img width="215" alt="Screenshot 2024-07-11 at 18 45 51"
src="https://github.com/twentyhq/twenty/assets/1834158/488f8294-0d7c-4209-b763-2499716ef29d">

Currently, the FE has a specific logic for company and people objects
and we have a way to update this value via the API for custom objects,
but the code is not flexible enough to change other standard objects.

This PR updates the WorkspaceEntity API so we can now provide the
labelIdentifier and imageIdentifier in the WorkspaceEntity decorator.

Example:
```typescript
@WorkspaceEntity({
  standardId: STANDARD_OBJECT_IDS.activity,
  namePlural: 'activities',
  labelSingular: 'Activity',
  labelPlural: 'Activities',
  description: 'An activity',
  icon: 'IconCheckbox',
  labelIdentifierStandardId: ACTIVITY_STANDARD_FIELD_IDS.title,
})
@WorkspaceIsSystem()
export class ActivityWorkspaceEntity extends BaseWorkspaceEntity {
  @WorkspaceField({
    standardId: ACTIVITY_STANDARD_FIELD_IDS.title,
    type: FieldMetadataType.TEXT,
    label: 'Title',
    description: 'Activity title',
    icon: 'IconNotes',
  })
  title: string;
...
```
2024-07-19 14:24:04 +02:00
a4e82d643a Support custom composite field deletion (#6320)
as per title
Fixes #6033 and closes #4841
2024-07-18 15:28:32 +02:00
47ddc7be83 6181 workflows create a custom code executor (#6235)
Closes #6181

## Testing
- download Altair graphql dev tool https://altairgraphql.dev/#download
- create a file locally `test.ts` containing:
```
export const handler = async (event: object, context: object) => {
  return { test: 'toto', data: event['data'] };
}
```
- play those requests in Altair:
mutation UpsertFunction($file: Upload!) {
  upsertFunction(name: "toto", file: $file)
}

mutation ExecFunction {
  executeFunction(name:"toto", payload: {data: "titi"})
}
- it will run the local driver, add those env variable to test with
lambda driver
```
CUSTOM_CODE_ENGINE_DRIVER_TYPE=lambda
LAMBDA_REGION=eu-west-2
LAMBDA_ROLE=<ASK_ME>
```
2024-07-17 17:53:01 +02:00
34cbba5fd8 Add interceptors for auto-resolvers (#6270)
Services exceptions are not catch when the endpoint comes from an
auto-resolver.
We want to remove auto-resolver but it requires to implement pagination
by ourselves.

As a quick fix, here are interceptors that will trigger the exception
handler.
I had a hard time making it generic so I finally added one interceptor
for each since this is not supposed to stay
2024-07-16 10:49:18 +02:00
364caf0fdf fix: remove usage of probability field (#5877)
- fixes #5735

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2024-07-16 10:24:35 +02:00
aed0bf41ce Forbid default value nullification for non-nullable field (#6258)
as per title 


https://github.com/user-attachments/assets/ce07d437-eeeb-488c-8dfa-3fc07316f485
2024-07-15 14:22:15 +02:00
1dff5bf957 Fix custom errors thrown as 500 (#6238)
We call convertExceptionToGraphQLError in the exception handler for http
exceptions but we don't take into account those that already are
graphqlErrors and because of that the logic of convertExceptionToGraphql
is to fallback to a 500.
Now if the exception is a BaseGraphqlError (custom graphql error we
throw in the code), we throw them directly.

BEFORE
<img width="957" alt="Screenshot 2024-07-12 at 15 33 03"
src="https://github.com/user-attachments/assets/22ddae13-4996-4ad3-8f86-dd17c2922ca8">


AFTER
<img width="923" alt="Screenshot 2024-07-12 at 15 32 01"
src="https://github.com/user-attachments/assets/d3d6db93-6d28-495c-a4b4-ba4e47d45abd">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-07-12 17:56:21 +02:00
a44249287f Forbid creation of link field type (#6237)
This is the first step of Link field type deprecation
(https://github.com/twentyhq/twenty/issues/5909).
Forbid creation of link field type in product and api. Update to this
type is not a concern as we do not allow the update of field type.
2024-07-12 15:28:17 +02:00
6af1bcd55c [Flexible Schema] Create indexes for join columns (#6165)
## Context
We want to add an index on our foreign keys since PG does not do it for
us. An index can sometimes be expensive and not always meaningful
depending on different usages but in our case we decided to apply an
index for every foreign keys.

```typescript
  @WorkspaceIndex()
  @WorkspaceJoinColumn('author')
  authorId: string;
```
This syntax is valid but since we want to apply it to every join column
I've decided to update the code of WorkspaceJoinColumn so it properly
registers a new index at the same time which is less error-prone.

Note: We had a bug on index name generation since postgres index names
are unique per schema and not table, the object metadata id (hashed) has
been added to the formula that generates the name of the index

## Test
Sync metadata. We have 45 join columns as of today per workspace, we
should see 45 rows inside IndexMetadata table
2024-07-09 14:51:24 +02:00
6cd154aac6 Forbid names above 63 characters to comply with pg identifier limit (#6095)
Fixes #6032.

Pg has a char limit on identifiers (= table, columns, enum names) of 63
bytes.
Let's limit the metadata names that will be converted to identifiers
(objects names, fields names, relation names, enum values) to 63 chars.
For the sake of simplicity in the FE we will limit the input length of
labels.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-07-04 15:32:42 +02:00
4c642a0bb8 Text-to-SQL proof of concept (#5788)
Added:
- An "Ask AI" command to the command menu.
- A simple GraphQL resolver that converts the user's question into a
relevant SQL query using an LLM, runs the query, and returns the result.

<img width="428" alt="Screenshot 2024-06-09 at 20 53 09"
src="https://github.com/twentyhq/twenty/assets/171685816/57127f37-d4a6-498d-b253-733ffa0d209f">

No security concerns have been addressed, this is only a
proof-of-concept and not intended to be enabled in production.

All changes are behind a feature flag called `IS_ASK_AI_ENABLED`.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2024-07-04 08:57:26 +02:00
4183e5460d Use return await to catch exceptions (#6109)
So the exceptions are handled properly and filtered in sentry
2024-07-03 11:14:28 +02:00
bb627a91e2 Use invalid field input error for invalid object metadata input (#6083)
As title
2024-07-01 16:33:48 +02:00
a15884ea0a Add exceptions for metadata modules (#6070)
Class exception for each metadata module + handler to map on graphql
error

TODO left :
- find a way to call handler on auto-resolvers nestjs query (probably
interceptors)
- discuss what should be done for pre-hooks errors
- discuss what should be done for Unauthorized exception
2024-07-01 13:49:17 +02:00
f8c057deea Fix sign up broken because of missing workspace schema (#6013)
Allow workspace datasource factory to return null if the workspace
schema has not been created yet
2024-06-25 10:59:07 +02:00
e13dc7a1fc [FlexibleSchema] Add IndexMetadata decorator (#5981)
## Context
Our Flexible Schema engine dynamically generates entities/tables/APIs
for us but was not flexible enough to build indexes in the DB. With more
and more features involving heavy queries such as Messaging, we are now
adding a new WorkspaceIndex() decorator for our standard objects (will
come later for custom objects). This decorator will give enough
information to the workspace sync metadata manager to generate the
proper migrations that will create or drop indexes on demand.
To be aligned with the rest of the engine, we are adding 2 new tables:
IndexMetadata and IndexFieldMetadata, that will store the info of our
indexes.

## Implementation

```typescript
@WorkspaceEntity({
  standardId: STANDARD_OBJECT_IDS.person,
  namePlural: 'people',
  labelSingular: 'Person',
  labelPlural: 'People',
  description: 'A person',
  icon: 'IconUser',
})
export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
  @WorkspaceField({
    standardId: PERSON_STANDARD_FIELD_IDS.email,
    type: FieldMetadataType.EMAIL,
    label: 'Email',
    description: 'Contact’s Email',
    icon: 'IconMail',
  })
  @WorkspaceIndex()
  email: string;
```
By simply adding the WorkspaceIndex decorator, sync-metadata command
will create a new index for that column.
We can also add composite indexes, note that the order is important for
PSQL.
```typescript
@WorkspaceEntity({
  standardId: STANDARD_OBJECT_IDS.person,
  namePlural: 'people',
  labelSingular: 'Person',
  labelPlural: 'People',
  description: 'A person',
  icon: 'IconUser',
})
@WorkspaceIndex(['phone', 'email'])
export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
```

Currently composite fields and relation fields are not handled by
@WorkspaceIndex() and you will need to use this notation instead
```typescript
@WorkspaceIndex(['companyId', 'nameFirstName'])
export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
```
<img width="700" alt="Screenshot 2024-06-21 at 15 15 45"
src="https://github.com/twentyhq/twenty/assets/1834158/ac6da1d9-d315-40a4-9ba6-6ab9ae4709d4">

Next step: We might need to implement more complex index expressions,
this is why we have an expression column in IndexMetadata.
What I had in mind for the decorator, still open to discussion
```typescript
@WorkspaceIndex(['nameFirstName', 'nameLastName'], { expression: "$1 || ' ' || $2"})
export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
```

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-06-22 12:39:57 +02:00
de2b0527a3 Fix secondaryLinks field input (#5911)
PR https://github.com/twentyhq/twenty/pull/5785/files broke links
update.

Also, dropdown "Add link" will be displayed only if a link is already
added. Otherwise, it should be a normal input.
2024-06-17 18:09:46 +02:00
58fb86f2c3 Added support for Links filtering (#5785)
References #5741

---------

Co-authored-by: kiridarivaki <k.darivaki03@gmail.com>
2024-06-11 15:24:34 +02:00
1bbfc0b715 Add unicity constraint between object nameSingular and namePlural (#5737) 2024-06-04 22:27:27 +02:00
b1f12d7257 Fix input position backfill (#5731)
Some objects do not have position field so they should not be backfilled
2024-06-04 13:26:40 +02:00
c60a3e49cd Catch query timeout exceptions (#5680)
Query read timeouts happen when a remote server is not available. It
breaks:
- the remote server show page
- the record table page of imported remote tables

This PR will catch the exception so it does not go to Sentry in both
cases.

Also did 2 renaming.
2024-05-31 10:39:35 +02:00
5bb205bd6a Fix update remote field metadata (#5638)
Closes #5610.

& update fetch-policy when fetching database on the remote databases
show page to get freshest status.
2024-05-28 18:01:05 +02:00
ebb1aa0377 Add label to remote server (#5637)
Added label on remote server entity. 

Also added the possibility to update schema. 

<img width="688" alt="Capture d’écran 2024-05-28 à 15 36 31"
src="https://github.com/twentyhq/twenty/assets/22936103/c9786122-8459-4876-833e-c9a1d7d27829">
2024-05-28 15:54:57 +02:00
ae6d5afdfc Add missing stripe tables (#5621)
As title

Still adding not working tables / columns commented so we know why these
are not available.
2024-05-28 11:32:57 +02:00
def1774bf0 [Fix] Object names should be camel cased (#5571)
as per title
2024-05-25 10:29:00 +02:00
18fafbdeb5 Rename findAvailableTables endpoint (#5557)
As title
2024-05-24 10:57:46 +02:00
4bd0aafb8e [fix] Update remote table sync status in cache after schema update (#5553)
Upon schema update, sync status can change from synced to non_synced in
case the update regards a table that was deleted. Let's update the sync
status too to avoid displaying the table as still synchronized.


https://github.com/twentyhq/twenty/assets/51697796/7ff2342b-ce9f-4179-9b76-940617cf1292
2024-05-24 10:20:08 +02:00
fede721ba8 Add sorter for distant tables (#5546)
As title
2024-05-23 22:36:50 +02:00
fe5b558477 [FE] Update remote table schema + refactor Tables list (#5548)
Closes #5062.

Refactoring tables list to avoid rendering all toggles on each sync or
schema update while using fresh data:
- introducing id for RemoteTables in apollo cache
- manually updating the cache for the record that was updated after a
sync or schema update instead of fetching all tables again
2024-05-23 17:00:24 +02:00
0d6fe7b2b4 Handle relations separately for remotes (#5538)
Remote object id columns are not removed anymore when a remote object is
unsynced.
This is because we do not use relations anymore. We only created the id
field. So the current behavior that was implemented for custom objects,
to retrieve the fields to deleted, does not work.

Since remote object relations are really different, I extracted the
logic from `objectMetadataService`. It now handles only the relations
for custom objects creation and deletion (this part should be extracted
as well).

I create a new remote table relation service that will:
- fetch objects metadata linked to remotes (favorites,
activityTargets...)
- look for columns based on remote object name
- delete the fields and columns
2024-05-23 14:59:34 +02:00
6b1d4e0744 [Fix] Do not allow names with whitespaces (#5542)
As per title
2024-05-23 07:43:09 +02:00
5448512bdc Add quotes for table name (#5533)
As title
2024-05-22 14:21:32 +02:00
3deda2f29a Update foreign table to distant table schema (#5508)
Closes #5069 back-end part

And:
- do not display schemaPendingUpdates status on remote server lists as
this call will become too costly if there are dozens of servers
- (refacto) create foreignTableService

After this is merged we will be able to delete remoteTable's
availableTables column
2024-05-21 21:25:38 +02:00
66a23a852f fix: unwanted change moving back datetime to date (#5499)
Moving back datetime to date, due to an unwanted change.
2024-05-21 13:29:59 +02:00
0d16051ded [fix] Re-introduce beforeUpdateOneObject hook (#5495)
... and disable name edition in object edition form. This feature will
be introduced by #5491
2024-05-21 10:46:49 +02:00
4d479ee8ea Remove relations for remotes (#5455)
For remotes, we will only create the foreign key, without the relation
metadata. Expected behavior will be:
- possible to create an activity. But the remote object will not be
displayed in the relations of the activity
- the remote objects should not be available in the search for relations

Also switched the number settings to an enum, since we now have to
handle `BigInt` case.

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
2024-05-20 16:37:35 +02:00
8b5f79ddbf fix: multiple twenty orm issues & show an example of use (#5439)
This PR is fixing some issues and adding enhancement in TwentyORM:

- [x] Composite fields in nested relations are not formatted properly
- [x] Passing operators like `Any` in `where` condition is breaking the
query
- [x] Ability to auto load workspace-entities based on a regex path

I've also introduced an example of use for `CalendarEventService`:


https://github.com/twentyhq/twenty/pull/5439/files#diff-3a7dffc0dea57345d10e70c648e911f98fe237248bcea124dafa9c8deb1db748R15
2024-05-20 11:01:47 +02:00
36e54119a3 Enable remotes with existing name (#5433)
- Check if a table with the same name already exists
- If yes, add a number suffix, and check again

Co-authored-by: Thomas Trompette <thomast@twenty.com>
2024-05-17 10:38:17 +02:00
1694e0cccd Fix missing name validation on object names at update (#5434)
## Context
as per title

## How was it tested? 
local (/metadata + in product)
2024-05-16 18:15:56 +02:00
d741f4a5bd Minor refacto and fixes on Remotes updates (#5438)
In this PR

- Code refactoring
- v0 of adding "updates available" info in Connection sync status
<img width="835" alt="Capture d’écran 2024-05-16 à 17 02 07"
src="https://github.com/twentyhq/twenty/assets/51697796/9674d3ca-bed2-4520-a5a6-ba37bc242d06">

- fix distant table columns with not-camel case names are always
considered as new
2024-05-16 17:31:34 +02:00
63387424c3 Fix transliteration for metadata + transliterate select options (#5430)
## Context 
Fixes #5403

Transliteration is now integrated to form validation through the schema.
While it does not impede inputting an invalid value, it impedes
submitting a form that will fail as the transliteration is not possible.
Until then we were only performing the transliteration at save time in
the front-end, but it's best to provide the information as soon as
possible. Later we will add helpers to guide the user (eg "This name is
not valid": https://github.com/twentyhq/twenty/issues/5428).

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-05-15 21:43:58 +02:00
e1eead56c6 Alter comment on foreign key deletion (#5406)
We do not update the comment on the local table when a foreign table key
is deleted.
This was not breaking, which is why we did not see it. But comments
should be kept up to date.

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
2024-05-15 17:05:30 +02:00
38eb293b3c Compare distant tables schema with remote tables schema (#5413)
Closes #4532 and part of #5062
2024-05-15 15:47:54 +02:00
b9154f315e Enable deletion of relation fields (#5338)
In this PR
1. Enable deletion of relation fields in the product and via the api
(migration part was missing in the api)
3. Change wording, only use "deactivate" and "delete" everywhere (and
not a mix of the two + "disable", "erase")
2024-05-13 17:43:51 +02:00
7c3e82870c [fix] Increment cache version after object/field/relation update (#5316)
Fixes #5276.

Updates were not triggering a cache version incrementation because they
do not trigger migrations while that is where the caching version logic
was.
We have decided to move the cache incrementation logic to the services.
2024-05-07 16:30:25 +02:00
2c9f50ecb1 Fix enum defaultValue issues (#5307)
This PR fixes several issues:
- enum naming should be: {tableName}_{fieldName}_enum and respecting the
case
- defaultValue format handled in the FE should respect the one in the BE

In my opinion we should refactor the defaultValue:
- we should respect backend format: "'myDefault'" for constant default
and "0" for float, "now" for expressions, "true" for booleans. we can
rename it to defaultValueExpression if it is more clear but we should
not maintain a parallel system
- we should deprecate option: isDefaultValue which is confusing
- we should re-work backend to have a more unified approach between
fields and avoid having if everywhere about select, multiselect, and
currency cases. one unified "computeDefaultValue" function should do the
job

What is still broken:
- currency default Value on creation. I think we should do the refactor
first
- select default value edition.
These cases do not break the schema but are ignored currently
2024-05-06 17:00:38 +02:00
154ae99ed3 [flexible-schema] Add reserved keyword check on object creation (#5303)
## Context
Because creating an object in metadata also generates a graphql type and
because graphql does not allow 2 types with the same name, we have to
manage a list of reserved keywords that can't be used as object names.

Currently we were maintaining a list of the core objects but we also
have to introduce composite fields that are also generated as gql types.
2024-05-06 13:44:40 +02:00
f9c19c839b Build stripe integration on backend side (#5246)
Adding stripe integration by making the server logic independent of the
input fields:
- query factories (remote server, foreign data wrapper, foreign table)
to loop on fields and values without hardcoding the names of the fields
- adding stripe input and type
- add the logic to handle static schema. Simply creating a big object to
store into the server

Additional work:
- rename username field to user. This is the input intended for postgres
user mapping and we now need a matching by name

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
2024-05-02 17:13:15 +02:00
0d023e5e77 feat: update links field (#5212)
Closes #5113

---------

Co-authored-by: Jérémy Magrin <jeremy.magrin@gmail.com>
2024-05-01 14:56:55 +02:00