From c33680508b26525eec538a2e1e7265fd6f4f83be Mon Sep 17 00:00:00 2001 From: Carson Full Date: Wed, 11 Jun 2025 15:00:09 -0500 Subject: [PATCH] Replace FOD memberships on open projects when a FieldRegion's zone changes --- ...ector-change-to-project-members.handler.ts | 50 +++++++++++++++++++ .../project-member/project-member.module.ts | 2 + 2 files changed, 52 insertions(+) create mode 100644 src/components/project/project-member/handlers/regions-zone-changes-applies-director-change-to-project-members.handler.ts diff --git a/src/components/project/project-member/handlers/regions-zone-changes-applies-director-change-to-project-members.handler.ts b/src/components/project/project-member/handlers/regions-zone-changes-applies-director-change-to-project-members.handler.ts new file mode 100644 index 0000000000..0f07d65d38 --- /dev/null +++ b/src/components/project/project-member/handlers/regions-zone-changes-applies-director-change-to-project-members.handler.ts @@ -0,0 +1,50 @@ +import { EventsHandler, ILogger, Logger, ResourceLoader } from '~/core'; +import { FieldRegionUpdatedEvent } from '../../../field-region/events/field-region-updated.event'; +import { ProjectMemberRepository } from '../project-member.repository'; + +@EventsHandler(FieldRegionUpdatedEvent) +export class RegionsZoneChangesAppliesDirectorChangeToProjectMembersHandler { + constructor( + private readonly repo: ProjectMemberRepository, + private readonly resources: ResourceLoader, + @Logger('project:members') private readonly logger: ILogger, + ) {} + + async handle(event: FieldRegionUpdatedEvent) { + const oldZoneId = event.previous.fieldZone.id; + const newZoneId = event.input.fieldZoneId; + if (!newZoneId) { + return; + } + const [oldZone, newZone] = await Promise.all([ + this.resources.load('FieldZone', oldZoneId), + this.resources.load('FieldZone', newZoneId), + ]); + const oldDirector = oldZone.director.value; + const newDirector = newZone.director.value; + if (!oldDirector || !newDirector) { + // Shouldn't really happen. I think everyone can see zones & directors rn. + throw new Error( + 'Cannot read field zone directors to apply project membership changes', + ); + } + + const stats = await this.repo.replaceMembershipsOnOpenProjects( + oldDirector.id, + newDirector.id, + 'FieldOperationsDirector', + ); + + this.logger.notice( + "FieldRegion's zone changed - Replaced FOD director memberships on open projects", + { + location: event.updated.id, + oldZone: oldZoneId, + newZone: newZoneId, + oldDirector: oldDirector.id, + newDirector: newDirector.id, + ...stats, + }, + ); + } +} diff --git a/src/components/project/project-member/project-member.module.ts b/src/components/project/project-member/project-member.module.ts index d6258155ff..0856380ca5 100644 --- a/src/components/project/project-member/project-member.module.ts +++ b/src/components/project/project-member/project-member.module.ts @@ -5,6 +5,7 @@ import { UserModule } from '../../user/user.module'; import { ProjectModule } from '../project.module'; import { AvailableRolesToProjectResolver } from './available-roles-to-project.resolver'; import { DirectorChangeApplyToProjectMembersHandler } from './handlers/director-change-apply-to-project-members.handler'; +import { RegionsZoneChangesAppliesDirectorChangeToProjectMembersHandler } from './handlers/regions-zone-changes-applies-director-change-to-project-members.handler'; import { AddInactiveAtMigration } from './migrations/add-inactive-at.migration'; import { ProjectMemberGelRepository } from './project-member.gel.repository'; import { ProjectMemberLoader } from './project-member.loader'; @@ -26,6 +27,7 @@ import { ProjectMemberService } from './project-member.service'; ProjectMemberLoader, AddInactiveAtMigration, DirectorChangeApplyToProjectMembersHandler, + RegionsZoneChangesAppliesDirectorChangeToProjectMembersHandler, ], exports: [ProjectMemberService], })