# Introduction While removing the v1 https://github.com/twentyhq/twenty/pull/15823 I've encountered the method `objectMetadataService.deleteObjectsMetadata` that I didn't wanted to migrate as it is and if it's not challenging its existence legitimacy. ## Motivations In a nutshell on a workspace deletion object metadata and field metadata cascading deletion is correclty handled But that's not the case for all of a workspaces entities ( roles, workspaceMigrations ) I suspect that we did not defined the foreignKey explicitly through `typeorm` ## Battle testing v2 I still decided to give a try to a complex operation in the v2 such as a workspace all object metadata deletion. Spoiler it failed due to object being interdependent between them and not being topologically sorted ( morph relation can introduce circular dep anw ). Note: Even after removing the delete field on delete object aggregator we end up with an equivalent circular dep error which an object and its field metadata identifier connection. ## Elegant `DEFERRED` and `DEFERRABLE` foreign keys The most safe, low level solution would be to make all field relations deferrable and start the runner transaction as deferred. But this requires a quite invasive migration of existing FK ## On cascade solution I've opted for the quick fix, on object or field deletion spread cacasde. It's pretty safe as the builder priorly validates the deletion and and its related entities integrity Only for both field and object deletion action types in v2 runner ## Integration coverage Added a test that will scan a new workspace database core schema tables and expect now result after workspace deletion through its only user deletion
23 lines
563 B
TypeScript
23 lines
563 B
TypeScript
import { type ASTNode, print } from 'graphql';
|
|
import request from 'supertest';
|
|
|
|
type GraphqlOperation = {
|
|
query: ASTNode;
|
|
variables?: Record<string, unknown>;
|
|
};
|
|
|
|
export const makeMetadataAPIRequest = (
|
|
graphqlOperation: GraphqlOperation,
|
|
token: string = APPLE_JANE_ADMIN_ACCESS_TOKEN,
|
|
) => {
|
|
const client = request(`http://localhost:${APP_PORT}`);
|
|
|
|
return client
|
|
.post('/metadata')
|
|
.set('Authorization', `Bearer ${token}`)
|
|
.send({
|
|
query: print(graphqlOperation.query),
|
|
variables: graphqlOperation.variables || {},
|
|
});
|
|
};
|