Files
edr-platform/apps/edr-freight-api/src/modules/companies/entities/company-change-request.entity.ts

88 lines
3.0 KiB
TypeScript

import { BaseEntity } from "@edr/api-common";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import { Company } from "./company.entity";
/**
* Lifecycle of a customer's proposed profile change. Edits made on the portal
* settings page by an already-approved company are staged here (not written to
* the live Company row) until a backoffice reviewer approves — at which point
* the snapshot is applied — or rejects with a note, after which the customer can
* amend and resubmit.
*/
export enum ChangeRequestStatus {
Pending = "pending",
Approved = "approved",
Rejected = "rejected",
}
/**
* A single staged business-license change on one company profile, awaiting
* review. `add` → a new file was uploaded under the pending code and becomes
* live on approval; `remove` → an existing live file is deleted on approval.
* A "replace" is recorded as a `remove` of the old file plus an `add` of the
* new one. `fileId` is the FileRecord id the op targets.
*/
export interface LicenseChangeIntent {
profileId: string;
op: "add" | "remove";
fileId: string;
/** File name, snapshotted for the backoffice review screen. */
fileName?: string;
}
/** File references staged alongside a change request (documents/licenses). */
export interface ChangeRequestDocuments {
/** FileRecord ids uploaded against the company while this request was open. */
documentFileIds?: string[];
/** Staged per-profile business-license add/remove intents. */
licenseChanges?: LicenseChangeIntent[];
}
@Entity({ schema: "freight", name: "company_change_request" })
@Index(["companyId"])
@Index(["status"])
export class CompanyChangeRequest extends BaseEntity {
@Column({ name: "company_id", type: "uuid" })
companyId!: string;
@ManyToOne(() => Company, { onDelete: "CASCADE" })
@JoinColumn({ name: "company_id" })
company?: Company;
/**
* Proposed profile field values, shaped as `Partial<UpdateProfileDto>`. Covers
* the Company / Contact / General Manager / Power-of-Attorney tabs (contact/GM/
* PoA fields land in `Company.attributes` on approval).
*/
@Column({ name: "snapshot", type: "jsonb" })
snapshot!: Record<string, any>;
/** Staged document/license file references (see {@link ChangeRequestDocuments}). */
@Column({ name: "documents", type: "jsonb", nullable: true })
documents?: ChangeRequestDocuments | null;
@Column({
name: "status",
type: "varchar",
length: 20,
default: ChangeRequestStatus.Pending,
})
status!: ChangeRequestStatus;
/** Backoffice reviewer's rejection note. */
@Column({ name: "note", type: "text", nullable: true })
note?: string | null;
@Column({ name: "submitted_by", type: "uuid", nullable: true })
submittedBy?: string | null;
@Column({ name: "submitted_at", type: "timestamptz", nullable: true })
submittedAt?: Date | null;
@Column({ name: "reviewed_by", type: "uuid", nullable: true })
reviewedBy?: string | null;
@Column({ name: "reviewed_at", type: "timestamptz", nullable: true })
reviewedAt?: Date | null;
}