@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
22
33import { msg } from '@lingui/core/macro' ;
44import { QUERY_MAX_RECORDS } from 'twenty-shared/constants' ;
5- import { ObjectRecord } from 'twenty-shared/types' ;
5+ import { MetadataReadability , ObjectRecord } from 'twenty-shared/types' ;
66import { isDefined } from 'twenty-shared/utils' ;
77import {
88 Brackets ,
@@ -15,9 +15,11 @@ import {
1515import { CommonBaseQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-base-query-runner.service' ;
1616import { type ConflictingFieldGroup } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/types/conflicting-field-group.type' ;
1717import { PartialObjectRecordWithId } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/types/partial-object-record-with-id.type' ;
18+ import { buildRecordShareInputsForCreatedRecords } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/build-record-share-inputs-for-created-records.util' ;
1819import { buildWhereConditions } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/build-where-conditions.util' ;
1920import { categorizeRecords } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/categorize-records.util' ;
2021import { getConflictingFields } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/get-conflicting-fields.util' ;
22+ import { validateShareWithArg } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/utils/validate-share-with-arg.util' ;
2123import {
2224 CommonQueryRunnerException ,
2325 CommonQueryRunnerExceptionCode ,
@@ -33,6 +35,7 @@ import {
3335} from 'src/engine/api/common/types/common-query-args.type' ;
3436import { CommonSelectedFieldsResult } from 'src/engine/api/common/types/common-selected-fields-result.type' ;
3537import { type NestedRelationsReadPathOptions } from 'src/engine/api/common/types/nested-relations-read-path-options.type' ;
38+ import { type ShareWithInput } from 'src/engine/api/common/types/share-with-input.type' ;
3639import { buildColumnsToReturn } from 'src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-return' ;
3740import { buildColumnsToSelect } from 'src/engine/api/graphql/graphql-query-runner/utils/build-columns-to-select' ;
3841import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util' ;
@@ -46,6 +49,7 @@ import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-module
4649import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type' ;
4750import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type' ;
4851import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util' ;
52+ import { RecordShareService } from 'src/engine/record-share/services/record-share.service' ;
4953import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace-repository' ;
5054import { RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config' ;
5155import { containsNestedRelationCreate } from 'src/engine/twenty-orm/utils/contains-nested-relation-create.util' ;
@@ -60,23 +64,38 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
6064> {
6165 protected readonly operationName = CommonQueryNames . CREATE_MANY ;
6266
63- constructor ( private readonly recordPositionService : RecordPositionService ) {
67+ constructor (
68+ private readonly recordPositionService : RecordPositionService ,
69+ private readonly recordShareService : RecordShareService ,
70+ ) {
6471 super ( ) ;
6572 }
6673
6774 async run (
6875 args : CommonExtendedInput < CreateManyQueryArgs > ,
6976 queryRunnerContext : CommonExtendedQueryRunnerContext ,
7077 ) : Promise < ObjectRecord [ ] > {
78+ const isPrivateObject =
79+ queryRunnerContext . flatObjectMetadata . readability ===
80+ MetadataReadability . PRIVATE ;
81+
82+ if ( isPrivateObject ) {
83+ validateShareWithArg ( {
84+ authContext : queryRunnerContext . authContext ,
85+ shareWith : args . shareWith ,
86+ } ) ;
87+ }
88+
7189 if (
7290 ! isDefined ( queryRunnerContext . transactionScope ) &&
73- containsNestedRelationCreate (
74- args . data ,
75- getNestedRelationFieldNames ( {
76- flatObjectMetadata : queryRunnerContext . flatObjectMetadata ,
77- flatFieldMetadataMaps : queryRunnerContext . flatFieldMetadataMaps ,
78- } ) ,
79- )
91+ ( isPrivateObject ||
92+ containsNestedRelationCreate (
93+ args . data ,
94+ getNestedRelationFieldNames ( {
95+ flatObjectMetadata : queryRunnerContext . flatObjectMetadata ,
96+ flatFieldMetadataMaps : queryRunnerContext . flatFieldMetadataMaps ,
97+ } ) ,
98+ ) )
8099 ) {
81100 return this . workspaceOrmManager . runInWorkspaceTransaction (
82101 ( transactionScope ) =>
@@ -135,7 +154,13 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
135154 flatObjectMetadata,
136155 flatObjectMetadataMaps,
137156 flatFieldMetadataMaps,
138- repository,
157+ repository :
158+ isPrivateObject && isDefined ( queryRunnerContext . transactionScope )
159+ ? queryRunnerContext . transactionScope . getRepository (
160+ flatObjectMetadata . nameSingular ,
161+ { shouldBypassPermissionChecks : true } ,
162+ )
163+ : repository ,
139164 selectedFieldsResult : args . selectedFieldsResult ,
140165 } ) ;
141166
@@ -268,14 +293,23 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
268293
269294 const writeRepository = this . getWriteRepository ( queryRunnerContext ) ;
270295
271- return writeRepository . runInsert ( {
296+ const insertResult = await writeRepository . runInsert ( {
272297 records : await this . resolveNestedRelationsForCreate ( {
273298 records : args . data ,
299+ shareWith : args . shareWith ,
274300 queryRunnerContext,
275301 writeRepository,
276302 } ) ,
277303 columnsToReturn : selectedColumns ,
278304 } ) ;
305+
306+ await this . insertRecordShares ( {
307+ insertResult,
308+ shareWith : args . shareWith ,
309+ queryRunnerContext,
310+ } ) ;
311+
312+ return insertResult ;
279313 }
280314
281315 return this . performUpsertOperation ( {
@@ -359,6 +393,7 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
359393 flatFieldMetadataMaps,
360394 result,
361395 columnsToReturn,
396+ shareWith : args . shareWith ,
362397 queryRunnerContext,
363398 } ) ;
364399 }
@@ -367,6 +402,7 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
367402 recordsToInsert : recordsToInsertWithPosition ,
368403 result,
369404 columnsToReturn,
405+ shareWith : args . shareWith ,
370406 queryRunnerContext,
371407 } ) ;
372408
@@ -469,13 +505,15 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
469505 flatFieldMetadataMaps,
470506 result,
471507 columnsToReturn,
508+ shareWith,
472509 queryRunnerContext,
473510 } : {
474511 partialRecordsToUpdate : PartialObjectRecordWithId [ ] ;
475512 flatObjectMetadata : FlatObjectMetadata ;
476513 flatFieldMetadataMaps : FlatEntityMaps < OrmFlatFieldMetadata > ;
477514 result : InsertResult ;
478515 columnsToReturn : string [ ] ;
516+ shareWith ?: ShareWithInput [ ] ;
479517 queryRunnerContext : CommonExtendedQueryRunnerContext ;
480518 } ) : Promise < void > {
481519 const updateInputs = partialRecordsToUpdate
@@ -494,6 +532,7 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
494532 const writeRepository = this . getWriteRepository ( queryRunnerContext ) ;
495533 const resolvedData = await this . resolveNestedRelationsForCreate ( {
496534 records : updateInputs . map ( ( input ) => input . data ) ,
535+ shareWith,
497536 queryRunnerContext,
498537 writeRepository,
499538 } ) ;
@@ -518,11 +557,13 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
518557 recordsToInsert,
519558 result,
520559 columnsToReturn,
560+ shareWith,
521561 queryRunnerContext,
522562 } : {
523563 recordsToInsert : Partial < ObjectRecord > [ ] ;
524564 result : InsertResult ;
525565 columnsToReturn : string [ ] ;
566+ shareWith ?: ShareWithInput [ ] ;
526567 queryRunnerContext : CommonExtendedQueryRunnerContext ;
527568 } ) : Promise < void > {
528569 if ( recordsToInsert . length === 0 ) {
@@ -534,23 +575,60 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
534575 const insertResult = await writeRepository . runInsert ( {
535576 records : await this . resolveNestedRelationsForCreate ( {
536577 records : recordsToInsert ,
578+ shareWith,
537579 queryRunnerContext,
538580 writeRepository,
539581 } ) ,
540582 columnsToReturn,
541583 } ) ;
542584
585+ await this . insertRecordShares ( {
586+ insertResult,
587+ shareWith,
588+ queryRunnerContext,
589+ } ) ;
590+
543591 result . identifiers . push ( ...insertResult . identifiers ) ;
544592 result . generatedMaps . push ( ...insertResult . generatedMaps ) ;
545593 result . raw . push ( ...insertResult . raw ) ;
546594 }
547595
596+ private async insertRecordShares ( {
597+ insertResult,
598+ shareWith,
599+ queryRunnerContext,
600+ } : {
601+ insertResult : InsertResult ;
602+ shareWith ?: ShareWithInput [ ] ;
603+ queryRunnerContext : CommonExtendedQueryRunnerContext ;
604+ } ) : Promise < void > {
605+ const { authContext, flatObjectMetadata, transactionScope } =
606+ queryRunnerContext ;
607+
608+ if ( flatObjectMetadata . readability !== MetadataReadability . PRIVATE ) {
609+ return ;
610+ }
611+
612+ await this . recordShareService . insertMany ( {
613+ workspaceId : authContext . workspace . id ,
614+ recordShares : buildRecordShareInputsForCreatedRecords ( {
615+ recordIds : insertResult . generatedMaps . map ( ( record ) => record . id ) ,
616+ objectMetadataId : flatObjectMetadata . id ,
617+ authContext,
618+ shareWith,
619+ } ) ,
620+ transactionScope,
621+ } ) ;
622+ }
623+
548624 private resolveNestedRelationsForCreate ( {
549625 records,
626+ shareWith,
550627 queryRunnerContext,
551628 writeRepository,
552629 } : {
553630 records : Partial < ObjectRecord > [ ] ;
631+ shareWith ?: ShareWithInput [ ] ;
554632 queryRunnerContext : CommonExtendedQueryRunnerContext ;
555633 writeRepository : WorkspaceRepository ;
556634 } ) : Promise < Partial < ObjectRecord > [ ] > {
@@ -591,6 +669,7 @@ export class CommonCreateManyQueryRunnerService extends CommonBaseQueryRunnerSer
591669 const { results } = await this . execute (
592670 {
593671 data : targetRecords ,
672+ shareWith,
594673 selectedFields : { id : true } ,
595674 } ,
596675 {
0 commit comments