import { Injectable, Logger } from "@nestjs/common"; import { Application, Organization, OrganizationConfiguration, Permission, Unit, } from "@tria-plc/iamapi-common"; import { DataSource, EntityManager } from "typeorm"; import { EDR_FREIGHT_APPLICATION, EDR_FREIGHT_PERMISSIONS, } from "./edr-freight.seed"; const EDR_UNIT_KEY = "edr_freight_app"; const EDR_UNIT_NAME = { en: "EDR Freight App" }; 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.ensureDefaultUnit(manager, organization.id); const application = await this.ensureApplication(manager); await this.ensurePermissions(manager, application.id); // Roles, positions and their permission links are intentionally NOT // seeded for now — only the application-scoped permission catalog, // mirroring how the default IAM seed relates permissions to their // application. Grants are assigned later through the IAM UI. }); 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 ensureDefaultUnit( manager: EntityManager, organizationId: string, ): Promise<{ id: string }> { const unitRepository = manager.getRepository(Unit); let unit = await unitRepository.findOne({ where: { key: EDR_UNIT_KEY, organizationId }, select: { id: true }, }); if (!unit) { const insertResult = await unitRepository.insert({ key: EDR_UNIT_KEY, name: EDR_UNIT_NAME, organizationId, }); this.logger.log(`Seeded EDR unit '${EDR_UNIT_KEY}'`); return { id: insertResult.identifiers[0]?.id as string }; } this.logger.log(`Ensured EDR unit '${EDR_UNIT_KEY}'`); return { id: unit.id }; } private async ensureApplication( manager: EntityManager, ): Promise<{ id: string }> { const applicationRepository = manager.getRepository(Application); const application = await applicationRepository.findOne({ where: { key: EDR_FREIGHT_APPLICATION.key }, select: { id: true }, }); if (!application?.id) { const insertResult = await applicationRepository.insert({ id: EDR_FREIGHT_APPLICATION.id, key: EDR_FREIGHT_APPLICATION.key, name: { ...EDR_FREIGHT_APPLICATION.name }, }); this.logger.log(`Seeded EDR application '${EDR_FREIGHT_APPLICATION.key}'`); return { id: insertResult.identifiers[0]?.id as string }; } this.logger.log(`Ensured EDR application '${EDR_FREIGHT_APPLICATION.key}'`); return { id: application.id }; } private async ensurePermissions( manager: EntityManager, applicationId: string, ) { const permissionRepository = manager.getRepository(Permission); // Upsert by key so reruns are idempotent; applicationId ties every // permission to the EDR Freight application (also backfills rows that // were previously seeded without the relation). await permissionRepository.upsert( EDR_FREIGHT_PERMISSIONS.map((permission) => ({ id: permission.id, key: permission.key, name: { ...permission.name }, applicationId, })), { conflictPaths: { key: true } }, ); this.logger.log( `Ensured ${EDR_FREIGHT_PERMISSIONS.length} permissions on application '${EDR_FREIGHT_APPLICATION.key}'`, ); } }