related to https://github.com/twentyhq/core-team-issues/issues/601

## Done
- add a `onDbEvent` `Subscription` graphql endpoint to listen to
database_event using what we have done with webhooks:
- you can subscribe to any `action` (created, updated, ...) for any
`objectNameSingular` or a specific `recordId`. Parameters are nullable
and treated as wildcards when null.
  - returns events with following shape
```typescript
  @Field(() => String)
  eventId: string;

  @Field()
  emittedAt: string;

  @Field(() => DatabaseEventAction)
  action: DatabaseEventAction;

  @Field(() => String)
  objectNameSingular: string;

  @Field(() => GraphQLJSON)
  record: ObjectRecord;

  @Field(() => [String], { nullable: true })
  updatedFields?: string[];
```
- front provide a componentEffect `<ListenRecordUpdatesEffect />` that
listen for an `objectNameSingular`, a `recordId` and a list of
`listenedFields`. It subscribes to record updates and updates its apollo
cached value for specified `listenedFields`
- subscription is protected with credentials

## Result

Here is an application with `workflowRun`


https://github.com/user-attachments/assets/c964d857-3b54-495f-bf14-587ba26c5a8c

---------

Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
martmull
2025-04-17 16:03:51 +02:00
committed by GitHub
parent b112d06f66
commit 42e060ac74
25 changed files with 552 additions and 27 deletions

View File

@ -23,6 +23,7 @@ import { cookieStorage } from '~/utils/cookie-storage';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { ApolloManager } from '../types/apolloManager.interface';
import { loggerLink } from '../utils/loggerLink';
import { getTokenPair } from '../utils/getTokenPair';
const logger = loggerLink(() => 'Twenty');
@ -55,14 +56,6 @@ export class ApolloFactory<TCacheShape> implements ApolloManager<TCacheShape> {
this.currentWorkspaceMember = currentWorkspaceMember;
const getTokenPair = () => {
const stringTokenPair = cookieStorage.getItem('tokenPair');
const tokenPair = isDefined(stringTokenPair)
? (JSON.parse(stringTokenPair) as AuthTokenPair)
: undefined;
return tokenPair;
};
const buildApolloLink = (): ApolloLink => {
const httpLink = createUploadLink({
uri,

View File

@ -0,0 +1,10 @@
import { cookieStorage } from '~/utils/cookie-storage';
import { isDefined } from 'twenty-shared/utils';
import { AuthTokenPair } from '~/generated/graphql';
export const getTokenPair = () => {
const stringTokenPair = cookieStorage.getItem('tokenPair');
return isDefined(stringTokenPair)
? (JSON.parse(stringTokenPair) as AuthTokenPair)
: undefined;
};