import { Resolver, Mutation, Ctx, Field, ObjectType, Int, Directive } from 'type-graphql' import { UserProvisioningService } from '../../controller/user-provisioning-service.js' @ObjectType({ description: 'User synchronization result' }) class UserSyncResult { @Field() success: boolean @Field() email: string @Field() action: string @Field({ nullable: true }) lsUserId?: string @Field({ nullable: true, description: 'Label Studio permissions (Admin/Staff/Inactive)' }) lsPermissions?: string @Field({ nullable: true }) error?: string } @ObjectType({ description: 'User synchronization summary' }) class UserSyncSummary { @Field(type => Int) total: number @Field(type => Int) created: number @Field(type => Int) updated: number @Field(type => Int) deactivated: number @Field(type => Int) skipped: number @Field(type => Int) errors: number @Field(type => [UserSyncResult]) results: UserSyncResult[] } @Resolver() export class UserSyncMutation { /** * 현재 사용자를 Label Studio에 동기화 */ @Mutation(returns => UserSyncResult, { description: 'Synchronize current user to Label Studio' }) @Directive('@privilege(domainOwnerGranted: true)') async syncMyUserToLabelStudio(@Ctx() context: ResolverContext): Promise { const { user, domain } = context.state const result = await UserProvisioningService.syncUser(domain, user) return result as UserSyncResult } /** * 도메인의 모든 사용자를 Label Studio에 일괄 동기화 */ @Mutation(returns => UserSyncSummary, { description: 'Synchronize all domain users to Label Studio (batch operation)' }) @Directive('@privilege(domainOwnerGranted: true)') async syncAllUsersToLabelStudio(@Ctx() context: ResolverContext): Promise { const { domain } = context.state const summary = await UserProvisioningService.syncAllUsers(domain) return summary as UserSyncSummary } }