feat(core): Introduce company and external profile management with dedicated API, services, and data schema

This commit is contained in:
ghost2023
2026-06-03 16:01:07 +03:00
parent c2145b48f5
commit dc9244d66e
22 changed files with 993 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, OneToMany } from 'typeorm';
import { ExternalProfile } from './external-profile.entity';
export enum CompanyType {
Customer = 'customer',
Forwarder = 'forwarder',
Transporter = 'transporter',
Broker = 'broker',
}
export enum CompanyStatus {
Active = 'active',
Pending = 'pending',
Suspended = 'suspended',
Blacklisted = 'blacklisted',
}
@Entity({ schema: 'freight', name: 'companies' })
@Index(['tin'])
@Index(['type'])
export class Company extends BaseEntity {
@Column({ name: 'name', type: 'varchar', length: 200 })
name!: string;
@Column({ name: 'type', type: 'varchar', length: 32, enum: CompanyType })
type!: CompanyType;
@Column({ name: 'status', type: 'varchar', length: 32, default: CompanyStatus.Pending })
status!: CompanyStatus;
@Column({ name: 'tin', type: 'varchar', length: 10, unique: true })
tin!: string;
@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 })
fanNumber?: string | null;
@Column({ name: 'country', type: 'varchar', length: 32, default: 'Ethiopia' })
country!: string;
@Column({ name: 'address', type: 'text', nullable: true })
address?: string | null;
@Column({ name: 'phone', type: 'varchar', length: 20, nullable: true })
phone?: string | null;
@Column({ name: 'email', type: 'varchar', length: 150, nullable: true })
email?: string | null;
@Column({ name: 'website', type: 'varchar', length: 200, nullable: true })
website?: string | null;
@Column({ name: 'attributes', type: 'jsonb', nullable: true })
attributes?: Record<string, any> | null;
@OneToMany(() => ExternalProfile, (profile) => profile.company)
profiles?: ExternalProfile[];
}

View File

@@ -0,0 +1,39 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, ManyToOne, JoinColumn } from 'typeorm';
import { Company } from './company.entity';
@Entity({ schema: 'freight', name: 'external_profiles' })
@Index(['userId'])
@Index(['companyId'])
export class ExternalProfile extends BaseEntity {
@Column({ name: 'user_id', type: 'uuid' })
userId!: string;
@Column({ name: 'company_id', type: 'uuid' })
companyId!: string;
@ManyToOne(() => Company, (company) => company.profiles)
@JoinColumn({ name: 'company_id' })
company!: Company;
@Column({ name: 'first_name', type: 'varchar', length: 100 })
firstName!: string;
@Column({ name: 'last_name', type: 'varchar', length: 100 })
lastName!: string;
@Column({ name: 'email', type: 'varchar', length: 150, unique: true })
email!: string;
@Column({ name: 'phone', type: 'varchar', length: 20, nullable: true })
phone?: string | null;
@Column({ name: 'national_id', type: 'varchar', length: 50, nullable: true })
nationalId?: string | null;
@Column({ name: 'job_title', type: 'varchar', length: 100, nullable: true })
jobTitle?: string | null;
@Column({ name: 'is_primary_contact', type: 'boolean', default: false })
isPrimaryContact!: boolean;
}

View File

@@ -0,0 +1,37 @@
import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, ManyToOne, JoinColumn, Unique } from 'typeorm';
import { Company } from './company.entity';
export enum FFClientRelationship {
ManagedAccount = 'managed_account',
SubAgent = 'sub_agent',
}
@Entity({ schema: 'freight', name: 'ff_clients' })
@Unique(['forwarderCompanyId', 'clientCompanyId'])
@Index(['forwarderCompanyId'])
@Index(['clientCompanyId'])
export class FFClient extends BaseEntity {
@Column({ name: 'forwarder_company_id', type: 'uuid' })
forwarderCompanyId!: string;
@ManyToOne(() => Company)
@JoinColumn({ name: 'forwarder_company_id' })
forwarderCompany!: Company;
@Column({ name: 'client_company_id', type: 'uuid' })
clientCompanyId!: string;
@ManyToOne(() => Company)
@JoinColumn({ name: 'client_company_id' })
clientCompany!: Company;
@Column({ name: 'relationship_type', type: 'varchar', length: 32, default: FFClientRelationship.ManagedAccount })
relationshipType!: FFClientRelationship;
@Column({ name: 'can_book_on_behalf', type: 'boolean', default: true })
canBookOnBehalf!: boolean;
@Column({ name: 'can_view_documents', type: 'boolean', default: true })
canViewDocuments!: boolean;
}