From f3be5e3d848a084651b63be505a399872ed2c236 Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Thu, 18 Jun 2026 15:32:44 +0300 Subject: [PATCH] feat(company): introduce CompanyProfile entity for detailed company roles --- .../1752000000000-CreateCompanyProfiles.ts | 103 ++++++++++++++++++ .../companies/dto/create-company.dto.ts | 5 - .../companies/dto/response-company.dto.ts | 2 - .../entities/company-profile.entity.ts | 62 +++++++++++ .../companies/entities/company.entity.ts | 99 +++++++++++------ 5 files changed, 230 insertions(+), 41 deletions(-) create mode 100644 apps/edr-freight-api/src/migrations/1752000000000-CreateCompanyProfiles.ts create mode 100644 apps/edr-freight-api/src/modules/companies/entities/company-profile.entity.ts diff --git a/apps/edr-freight-api/src/migrations/1752000000000-CreateCompanyProfiles.ts b/apps/edr-freight-api/src/migrations/1752000000000-CreateCompanyProfiles.ts new file mode 100644 index 000000000..a27cef3ad --- /dev/null +++ b/apps/edr-freight-api/src/migrations/1752000000000-CreateCompanyProfiles.ts @@ -0,0 +1,103 @@ +import { + MigrationInterface, + QueryRunner, + Table, + TableIndex, + TableForeignKey, +} from "typeorm"; + +export class CreateCompanyProfiles1752000000000 implements MigrationInterface { + name = "CreateCompanyProfiles1752000000000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + schema: "freight", + name: "company_profiles", + columns: [ + { + name: "id", + type: "uuid", + isPrimary: true, + generationStrategy: "uuid", + default: "gen_random_uuid()", + }, + { name: "company_id", type: "uuid" }, + { name: "type", type: "varchar", length: "32" }, + { name: "reference", type: "varchar", length: "20", isUnique: true }, + { + name: "status", + type: "varchar", + length: "32", + default: "'active'", + }, + { + name: "business_license", + type: "varchar", + length: "100", + isNullable: true, + }, + { name: "attributes", type: "jsonb", isNullable: true }, + { name: "created_at", type: "timestamptz", default: "now()" }, + { name: "updated_at", type: "timestamptz", default: "now()" }, + { name: "deleted_at", type: "timestamptz", isNullable: true }, + ], + }), + true, + ); + + await queryRunner.createForeignKey( + "freight.company_profiles", + new TableForeignKey({ + columnNames: ["company_id"], + referencedTableName: "companies", + referencedSchema: "freight", + referencedColumnNames: ["id"], + }), + ); + + await queryRunner.createIndex( + "freight.company_profiles", + new TableIndex({ columnNames: ["company_id"] }), + ); + await queryRunner.createIndex( + "freight.company_profiles", + new TableIndex({ columnNames: ["type"] }), + ); + + await queryRunner.query( + `CREATE SEQUENCE IF NOT EXISTS freight.seq_company_profile_ex START WITH 1`, + ); + await queryRunner.query( + `CREATE SEQUENCE IF NOT EXISTS freight.seq_company_profile_im START WITH 1`, + ); + await queryRunner.query( + `CREATE SEQUENCE IF NOT EXISTS freight.seq_company_profile_ffe START WITH 1`, + ); + await queryRunner.query( + `CREATE SEQUENCE IF NOT EXISTS freight.seq_company_profile_fwj START WITH 1`, + ); + await queryRunner.query( + `CREATE SEQUENCE IF NOT EXISTS freight.seq_company_profile_tr START WITH 1`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable("freight.company_profiles"); + await queryRunner.query( + `DROP SEQUENCE IF EXISTS freight.seq_company_profile_ex`, + ); + await queryRunner.query( + `DROP SEQUENCE IF EXISTS freight.seq_company_profile_im`, + ); + await queryRunner.query( + `DROP SEQUENCE IF EXISTS freight.seq_company_profile_ffe`, + ); + await queryRunner.query( + `DROP SEQUENCE IF EXISTS freight.seq_company_profile_fwj`, + ); + await queryRunner.query( + `DROP SEQUENCE IF EXISTS freight.seq_company_profile_tr`, + ); + } +} diff --git a/apps/edr-freight-api/src/modules/companies/dto/create-company.dto.ts b/apps/edr-freight-api/src/modules/companies/dto/create-company.dto.ts index b22334697..5718f541e 100644 --- a/apps/edr-freight-api/src/modules/companies/dto/create-company.dto.ts +++ b/apps/edr-freight-api/src/modules/companies/dto/create-company.dto.ts @@ -25,11 +25,6 @@ export class CreateCompanyDto { @MaxLength(50) vatNumber?: string; - @IsOptional() - @IsString() - @MaxLength(100) - businessLicense?: string; - @IsOptional() @IsString() @MaxLength(32) diff --git a/apps/edr-freight-api/src/modules/companies/dto/response-company.dto.ts b/apps/edr-freight-api/src/modules/companies/dto/response-company.dto.ts index 1879e25d6..748fbf73d 100644 --- a/apps/edr-freight-api/src/modules/companies/dto/response-company.dto.ts +++ b/apps/edr-freight-api/src/modules/companies/dto/response-company.dto.ts @@ -8,7 +8,6 @@ export class ResponseCompanyDto { status: CompanyStatus; tin: string; vatNumber?: string | null; - businessLicense?: string | null; fanNumber?: string | null; country: string; address?: string | null; @@ -27,7 +26,6 @@ export class ResponseCompanyDto { this.status = company.status; this.tin = company.tin; this.vatNumber = company.vatNumber; - this.businessLicense = company.businessLicense; this.fanNumber = company.fanNumber; this.country = company.country; this.address = company.address; diff --git a/apps/edr-freight-api/src/modules/companies/entities/company-profile.entity.ts b/apps/edr-freight-api/src/modules/companies/entities/company-profile.entity.ts new file mode 100644 index 000000000..84da76135 --- /dev/null +++ b/apps/edr-freight-api/src/modules/companies/entities/company-profile.entity.ts @@ -0,0 +1,62 @@ +import { BaseEntity } from "@edr/api-common"; +import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm"; +import { Company } from "./company.entity"; + +export enum ProfileType { + importer = "importer", + exporter = "exporter", + freightForwarder = "freight_forwarder", + djFreightForwarder = "dj_freight_forwarder", + transporter = "transporter", +} + +export enum ProfileStatus { + Active = "active", + Pending = "pending", + Suspended = "suspended", + Blacklisted = "blacklisted", +} + +@Entity({ schema: "freight", name: "company_profiles" }) +@Index(["reference"], { unique: true }) +@Index(["type"]) +@Index(["companyId"]) +export class CompanyProfile extends BaseEntity { + @Column({ name: "company_id", type: "uuid" }) + companyId!: string; + + @ManyToOne(() => Company, (company) => company.companyProfiles) + @JoinColumn({ name: "company_id" }) + company!: Company; + + @Column({ name: "type", type: "varchar", length: 32, enum: ProfileType }) + type!: ProfileType; + + @Column({ + name: "reference", + type: "varchar", + length: 20, + nullable: false, + unique: true, + }) + reference!: string; + + @Column({ + name: "status", + type: "varchar", + length: 32, + default: ProfileStatus.Active, + }) + status!: ProfileStatus; + + @Column({ + name: "business_license", + type: "varchar", + length: 100, + nullable: true, + }) + businessLicense?: string | null; + + @Column({ name: "attributes", type: "jsonb", nullable: true }) + attributes?: Record | null; +} diff --git a/apps/edr-freight-api/src/modules/companies/entities/company.entity.ts b/apps/edr-freight-api/src/modules/companies/entities/company.entity.ts index 070854eb8..ec578a3b7 100644 --- a/apps/edr-freight-api/src/modules/companies/entities/company.entity.ts +++ b/apps/edr-freight-api/src/modules/companies/entities/company.entity.ts @@ -1,79 +1,110 @@ -import { BaseEntity } from '@edr/api-common'; -import { Column, Entity, Index, OneToMany } from 'typeorm'; -import { ExternalProfile } from './external-profile.entity'; +import { BaseEntity } from "@edr/api-common"; +import { Column, Entity, Index, OneToMany } from "typeorm"; +import { ExternalProfile } from "./external-profile.entity"; +import { CompanyProfile } from "./company-profile.entity"; export enum CompanyType { - Customer = 'customer', - Forwarder = 'forwarder', - Transporter = 'transporter', - Broker = 'broker', + Customer = "customer", + FreightForwarder = "freight_forwarder", + DJFreightForwarder = "dj_freight_forwarder", + Transporter = "transporter", } export enum CompanyStatus { - Active = 'active', - Pending = 'pending', - Suspended = 'suspended', - Blacklisted = 'blacklisted', + Active = "active", + Pending = "pending", + Suspended = "suspended", + Blacklisted = "blacklisted", } -@Entity({ schema: 'freight', name: 'companies' }) -@Index(['tin']) -@Index(['type']) +@Entity({ schema: "freight", name: "companies" }) +@Index(["tin"]) +@Index(["type"]) export class Company extends BaseEntity { - @Column({ name: 'name', type: 'varchar', length: 200 }) + @Column({ name: "name", type: "varchar", length: 200 }) name!: string; - @Column({ name: 'type', type: 'varchar', length: 32, enum: CompanyType }) + @Column({ name: "type", type: "varchar", length: 32, enum: CompanyType }) type!: CompanyType; - @Column({ name: 'status', type: 'varchar', length: 32, default: CompanyStatus.Pending }) + @Column({ + name: "status", + type: "varchar", + length: 32, + default: CompanyStatus.Pending, + }) status!: CompanyStatus; - @Column({ name: 'tin', type: 'varchar', length: 10, unique: true }) + @Column({ name: "tin", type: "varchar", length: 10, unique: true }) tin!: string; - @Column({ name: 'vat_number', type: 'varchar', length: 50, nullable: true }) + @Column({ name: "vat_number", type: "varchar", length: 50, nullable: true }) vatNumber?: string | null; - @Column({ name: 'business_license', type: 'varchar', length: 100, nullable: true }) - businessLicense?: string | null; - - @Column({ name: 'fan_number', type: 'varchar', length: 16, nullable: true }) + @Column({ name: "fan_number", type: "varchar", length: 16, nullable: true }) fanNumber?: string | null; - @Column({ name: 'country', type: 'varchar', length: 32, default: 'Ethiopia' }) + @Column({ name: "country", type: "varchar", length: 32, default: "Ethiopia" }) country!: string; - @Column({ name: 'address', type: 'text', nullable: true }) + @Column({ name: "address", type: "text", nullable: true }) address?: string | null; - @Column({ name: 'phone', type: 'varchar', length: 20, nullable: true }) + @Column({ name: "phone", type: "varchar", length: 20, nullable: true }) phone?: string | null; - @Column({ name: 'email', type: 'varchar', length: 150, nullable: true }) + @Column({ name: "email", type: "varchar", length: 150, nullable: true }) email?: string | null; - @Column({ name: 'contact_person_name', type: 'varchar', length: 100, nullable: true }) + @Column({ + name: "contact_person_name", + type: "varchar", + length: 100, + nullable: true, + }) contactPersonName?: string | null; - @Column({ name: 'contact_person_phone', type: 'varchar', length: 20, nullable: true }) + @Column({ + name: "contact_person_phone", + type: "varchar", + length: 20, + nullable: true, + }) contactPersonPhone?: string | null; - @Column({ name: 'general_manager_name', type: 'varchar', length: 100, nullable: true }) + @Column({ + name: "general_manager_name", + type: "varchar", + length: 100, + nullable: true, + }) generalManagerName?: string | null; - @Column({ name: 'general_manager_email', type: 'varchar', length: 150, nullable: true }) + @Column({ + name: "general_manager_email", + type: "varchar", + length: 150, + nullable: true, + }) generalManagerEmail?: string | null; - @Column({ name: 'general_manager_phone', type: 'varchar', length: 20, nullable: true }) + @Column({ + name: "general_manager_phone", + type: "varchar", + length: 20, + nullable: true, + }) generalManagerPhone?: string | null; - @Column({ name: 'website', type: 'varchar', length: 200, nullable: true }) + @Column({ name: "website", type: "varchar", length: 200, nullable: true }) website?: string | null; - @Column({ name: 'attributes', type: 'jsonb', nullable: true }) + @Column({ name: "attributes", type: "jsonb", nullable: true }) attributes?: Record | null; @OneToMany(() => ExternalProfile, (profile) => profile.company) profiles?: ExternalProfile[]; + + @OneToMany(() => CompanyProfile, (profile) => profile.company) + companyProfiles?: CompanyProfile[]; }