mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 13:28:11 +00:00
Allows migration to run when enum already exists in prod DB. Prevents 'type already exists' error on redeployment. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
102 lines
3.8 KiB
TypeScript
102 lines
3.8 KiB
TypeScript
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
|
|
/**
|
|
* Freight billing — `invoices` + `invoice_lines` tables.
|
|
*
|
|
* Matches:
|
|
* - billing/entities/invoice.entity.ts
|
|
* - billing/entities/invoice-line.entity.ts
|
|
*
|
|
* The status enum mirrors `Freight.InvoiceStatus` and uses TypeORM's default
|
|
* enum-type name (`<table>_<column>_enum`) so the entity's `type: "enum"`
|
|
* column resolves to it without an explicit `enumName`.
|
|
*/
|
|
export class CreateInvoices1821000000002 implements MigrationInterface {
|
|
name = "CreateInvoices1821000000002";
|
|
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(`
|
|
CREATE TYPE IF NOT EXISTS freight.invoices_status_enum AS ENUM (
|
|
'DRAFT',
|
|
'PENDING',
|
|
'PAID',
|
|
'OVERDUE',
|
|
'CANCELLED',
|
|
'REFUNDED'
|
|
);
|
|
`);
|
|
|
|
await queryRunner.query(`
|
|
CREATE TABLE freight.invoices (
|
|
id uuid NOT NULL DEFAULT uuid_generate_v4(),
|
|
invoice_number varchar(64) NOT NULL,
|
|
company_id uuid NOT NULL,
|
|
company_profile_id uuid NOT NULL,
|
|
total_amount numeric(14, 2) NOT NULL,
|
|
currency varchar(8) NOT NULL DEFAULT 'ETB',
|
|
status freight.invoices_status_enum NOT NULL DEFAULT 'DRAFT',
|
|
source varchar(255) NOT NULL,
|
|
source_id varchar(255) NOT NULL,
|
|
type varchar(255) NOT NULL,
|
|
issued_at timestamptz,
|
|
payment_id uuid,
|
|
due_at timestamptz NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
deleted_at timestamptz,
|
|
CONSTRAINT pk_invoices PRIMARY KEY (id),
|
|
CONSTRAINT uq_invoices_invoice_number UNIQUE (invoice_number),
|
|
CONSTRAINT fk_invoices_company FOREIGN KEY (company_id)
|
|
REFERENCES freight.companies (id) ON DELETE RESTRICT,
|
|
CONSTRAINT fk_invoices_company_profile FOREIGN KEY (company_profile_id)
|
|
REFERENCES freight.company_profiles (id) ON DELETE RESTRICT,
|
|
CONSTRAINT fk_invoices_payment FOREIGN KEY (payment_id)
|
|
REFERENCES freight.payments (id) ON DELETE SET NULL
|
|
);
|
|
`);
|
|
|
|
await queryRunner.query(
|
|
`CREATE INDEX idx_invoices_company ON freight.invoices (company_id);`,
|
|
);
|
|
await queryRunner.query(
|
|
`CREATE INDEX idx_invoices_company_profile ON freight.invoices (company_profile_id);`,
|
|
);
|
|
await queryRunner.query(
|
|
`CREATE INDEX idx_invoices_source ON freight.invoices (source, source_id);`,
|
|
);
|
|
await queryRunner.query(
|
|
`CREATE INDEX idx_invoices_status ON freight.invoices (status);`,
|
|
);
|
|
|
|
await queryRunner.query(`
|
|
CREATE TABLE freight.invoice_lines (
|
|
id uuid NOT NULL DEFAULT uuid_generate_v4(),
|
|
invoice_id uuid NOT NULL,
|
|
charge_type varchar NOT NULL,
|
|
description varchar(255),
|
|
quantity numeric(12, 2) NOT NULL DEFAULT 1,
|
|
unit_rate numeric(14, 2) NOT NULL DEFAULT 0,
|
|
amount numeric(14, 2) NOT NULL,
|
|
currency varchar(8) NOT NULL DEFAULT 'ETB',
|
|
metadata jsonb,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
deleted_at timestamptz,
|
|
CONSTRAINT pk_invoice_lines PRIMARY KEY (id),
|
|
CONSTRAINT fk_invoice_lines_invoice FOREIGN KEY (invoice_id)
|
|
REFERENCES freight.invoices (id) ON DELETE CASCADE
|
|
);
|
|
`);
|
|
|
|
await queryRunner.query(
|
|
`CREATE INDEX idx_invoice_lines_invoice ON freight.invoice_lines (invoice_id);`,
|
|
);
|
|
}
|
|
|
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(`DROP TABLE IF EXISTS freight.invoice_lines;`);
|
|
await queryRunner.query(`DROP TABLE IF EXISTS freight.invoices;`);
|
|
await queryRunner.query(`DROP TYPE IF EXISTS freight.invoices_status_enum;`);
|
|
}
|
|
}
|