mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix: make the reference generate on apporaval
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
/**
|
||||
* Company-profile references are now minted only when a profile is approved
|
||||
* (status → Active); pending profiles carry NULL. Drop the NOT NULL constraint
|
||||
* on freight.company_profiles.reference. The existing unique index is kept —
|
||||
* Postgres treats NULLs as distinct, so multiple pending (NULL) profiles don't
|
||||
* collide.
|
||||
*/
|
||||
export class MakeCompanyProfileReferenceNullable1810000000002
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = "MakeCompanyProfileReferenceNullable1810000000002";
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "freight"."company_profiles" ALTER COLUMN "reference" DROP NOT NULL`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
// Reinstating NOT NULL requires every row to have a reference; any pending
|
||||
// (NULL) profiles get a placeholder so the constraint can be re-applied.
|
||||
await queryRunner.query(
|
||||
`UPDATE "freight"."company_profiles" SET "reference" = 'PENDING-' || left(replace("id"::text, '-', ''), 12) WHERE "reference" IS NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "freight"."company_profiles" ALTER COLUMN "reference" SET NOT NULL`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -193,15 +193,13 @@ export class CompaniesService {
|
||||
input.type,
|
||||
);
|
||||
if (existing) continue;
|
||||
const reference = await this.companyProfilesRepo.generateReference(
|
||||
input.type,
|
||||
);
|
||||
// No reference yet — these profiles await backoffice approval, which
|
||||
// is when the reference is minted (see setCompanyProfileStatus).
|
||||
await this.companyProfilesRepo.create({
|
||||
companyId: company.id,
|
||||
type: input.type,
|
||||
reference,
|
||||
businessLicense: input.businessLicense ?? null,
|
||||
status: ProfileStatus.Active,
|
||||
status: ProfileStatus.Pending,
|
||||
});
|
||||
}
|
||||
company.companyProfiles = await this.companyProfilesRepo.findByCompanyId(
|
||||
@@ -310,12 +308,11 @@ export class CompaniesService {
|
||||
type,
|
||||
);
|
||||
if (existing) continue;
|
||||
const reference = await this.companyProfilesRepo.generateReference(type);
|
||||
// No reference yet — minted on backoffice approval (setCompanyProfileStatus).
|
||||
await this.companyProfilesRepo.create({
|
||||
companyId,
|
||||
type,
|
||||
reference,
|
||||
status: ProfileStatus.Active,
|
||||
status: ProfileStatus.Pending,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -680,10 +677,20 @@ export class CompaniesService {
|
||||
profileId: string,
|
||||
status: ProfileStatus,
|
||||
): Promise<CompanyProfile> {
|
||||
const updated = await this.companyProfilesRepo.updateStatus(
|
||||
profileId,
|
||||
status,
|
||||
);
|
||||
const existing = await this.companyProfilesRepo.findById(profileId);
|
||||
if (!existing)
|
||||
throw new NotFoundException(`Company profile ${profileId} not found`);
|
||||
|
||||
// A reference number is only minted the first time a profile is approved
|
||||
// (status → Active). Pending/unapproved profiles carry no reference.
|
||||
const patch: Partial<CompanyProfile> = { status };
|
||||
if (status === ProfileStatus.Active && !existing.reference) {
|
||||
patch.reference = await this.companyProfilesRepo.generateReference(
|
||||
existing.type,
|
||||
);
|
||||
}
|
||||
|
||||
const updated = await this.companyProfilesRepo.update(profileId, patch);
|
||||
if (!updated)
|
||||
throw new NotFoundException(`Company profile ${profileId} not found`);
|
||||
|
||||
@@ -718,7 +725,7 @@ export class CompaniesService {
|
||||
const existing = await this.companyProfilesRepo.findByType(companyId, type);
|
||||
if (existing) {
|
||||
throw new ConflictException(
|
||||
`Company already has a ${type} profile (${existing.reference})`,
|
||||
`Company already has a ${type} profile (${existing.reference ?? "pending approval"})`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -931,7 +938,7 @@ export class CompaniesService {
|
||||
const licenseProfiles = (company.companyProfiles ?? []).map((p) => ({
|
||||
profileId: p.id,
|
||||
type: p.type,
|
||||
reference: p.reference,
|
||||
reference: p.reference ?? "",
|
||||
uploaded: (p.businessLicenseFiles?.length ?? 0) > 0,
|
||||
}));
|
||||
const missingLicenses = licenseProfiles.filter((p) => !p.uploaded);
|
||||
|
||||
@@ -28,7 +28,7 @@ export class ResponseCompanyProfileDto {
|
||||
this.id = profile.id;
|
||||
this.companyId = profile.companyId;
|
||||
this.type = profile.type;
|
||||
this.reference = profile.reference;
|
||||
this.reference = profile.reference ?? '';
|
||||
this.status = profile.status;
|
||||
this.businessLicense = profile.businessLicense;
|
||||
this.licenseFiles = profile.businessLicenseFiles ?? [];
|
||||
|
||||
@@ -40,14 +40,19 @@ export class CompanyProfile extends BaseEntity {
|
||||
@Column({ name: "type", type: "varchar", length: 32, enum: ProfileType })
|
||||
type!: ProfileType;
|
||||
|
||||
/**
|
||||
* Official profile reference (e.g. "EX-00001"). Minted only when the profile
|
||||
* is approved (status → Active); pending/unapproved profiles carry NULL.
|
||||
* The unique index tolerates this because Postgres treats NULLs as distinct.
|
||||
* API responses surface it as "" when absent — see ResponseCompanyProfileDto.
|
||||
*/
|
||||
@Column({
|
||||
name: "reference",
|
||||
type: "varchar",
|
||||
length: 20,
|
||||
nullable: false,
|
||||
unique: true,
|
||||
nullable: true,
|
||||
})
|
||||
reference!: string;
|
||||
reference!: string | null;
|
||||
|
||||
@Column({
|
||||
name: "status",
|
||||
|
||||
Reference in New Issue
Block a user