import { Injectable, Logger } from "@nestjs/common"; import { Organization, OrganizationConfiguration, Permission, Role, RolePermission, } from "@tria-plc/iamapi-common"; import { DataSource, EntityManager, In } from "typeorm"; import { EDR_FREIGHT_ROLES, type FreightSeedRole } from "./edr-freight.seed"; const EDR_ORG_KEY = "edr_freight"; const EDR_ORG_NAME = { en: "EDR Freight" }; const SEED_FLAG = "SEED_EDR_ORG"; type SeedOrganization = { id: string; key: string; }; @Injectable() export class EdrOrgSeeder { private readonly logger = new Logger(EdrOrgSeeder.name); constructor(private readonly dataSource: DataSource) {} async run() { if (!this.shouldSeed()) { this.logger.log(`Skipping EDR org seed because ${SEED_FLAG} is not enabled`); return; } await this.dataSource.transaction(async (manager) => { const organization = await this.ensureOrganization(manager); await this.ensureOrganizationConfiguration(manager, organization.id); await this.ensureRoles(manager, EDR_FREIGHT_ROLES); await this.ensureRolePermissions(manager, EDR_FREIGHT_ROLES); }); this.logger.log(`Ensured EDR organization seed for '${EDR_ORG_KEY}'`); } private shouldSeed() { return process.env[SEED_FLAG]?.trim().toLowerCase() === "true"; } private async ensureOrganization( manager: EntityManager, ): Promise { const organizationRepository = manager.getRepository(Organization); let organization = await organizationRepository.findOne({ where: { key: EDR_ORG_KEY }, select: { id: true, key: true }, }); if (!organization) { const insertResult = await organizationRepository.insert({ key: EDR_ORG_KEY, name: EDR_ORG_NAME, isGovernmentOrganization: true, }); this.logger.log(`Seeded EDR organization '${EDR_ORG_KEY}'`); return { id: insertResult.identifiers[0]?.id as string, key: EDR_ORG_KEY, }; } this.logger.log(`Ensured EDR organization '${EDR_ORG_KEY}'`); return { id: organization.id as string, key: EDR_ORG_KEY, }; } private async ensureOrganizationConfiguration( manager: EntityManager, organizationId: string, ) { const organizationConfigurationRepository = manager.getRepository(OrganizationConfiguration); await organizationConfigurationRepository.upsert({ organizationId, canCreateBranchByItself: true, canStartReceivingRecord: true, }, { conflictPaths: { organizationId: true }, }); this.logger.log( `Ensured organization configuration for '${EDR_ORG_KEY}'`, ); } private async ensureRoles(manager: EntityManager, seedRoles: FreightSeedRole[]) { await manager.getRepository(Role).upsert( seedRoles.map(({ key, name }) => ({ key, name })), { conflictPaths: { key: true }, }, ); this.logger.log( `Ensured EDR roles '${seedRoles.map((role) => role.key).join("', '")}'`, ); } private async ensureRolePermissions( manager: EntityManager, seedRoles: FreightSeedRole[], ) { const permissionKeys = [...new Set(seedRoles.flatMap((role) => role.permissionKeys))]; if (!permissionKeys.length) { this.logger.log("No EDR role permissions configured; skipping role-permission links"); return; } const roleRepository = manager.getRepository(Role); const rolePermissionRepository = manager.getRepository(RolePermission); const roles = await roleRepository.find({ where: { key: In(seedRoles.map((role) => role.key)) }, select: { id: true, key: true }, }); const seededPermissions = await manager.getRepository(Permission).find({ where: { key: In(permissionKeys) }, select: { id: true, key: true }, }); const roleByKey = new Map(roles.map((role) => [role.key, role])); const permissionByKey = new Map( seededPermissions.map((permission) => [permission.key, permission]), ); const rolePermissions = seedRoles.flatMap((role) => { const seededRole = roleByKey.get(role.key); if (!seededRole) { throw new Error(`missing_role:${role.key}`); } return role.permissionKeys.map((permissionKey) => { const seededPermission = permissionByKey.get(permissionKey); if (!seededPermission) { throw new Error(`missing_permission:${permissionKey}`); } return { roleId: seededRole.id, permissionId: seededPermission.id, }; }); }); await rolePermissionRepository.upsert(rolePermissions, { conflictPaths: { roleId: true, permissionId: true }, }); this.logger.log(`Ensured ${rolePermissions.length} EDR role-permission links`); } }