Files
edr-platform/apps/edr-freight-api/src/migrations/3440000000000-ShippingLineCompany.ts
marshalyordanos 9aae132dd4 feat: add shipping line companies management
- Implement ShippingLineCompaniesService for registering and managing shipping line companies.
- Create ResendActivationAction component for resending activation links to shipping lines.
- Develop ShippingLineCompaniesPage for listing and registering shipping lines with validation.
- Introduce shippingLineCompanies.service for API interactions related to shipping lines.
- Define types for shipping line companies, including registration and pagination.
- Add placeholder pages for shipping line portal, including home, bookings, help, invoices, and settings.
2026-08-13 08:54:20 +03:00

79 lines
2.9 KiB
TypeScript

import { MigrationInterface, QueryRunner } from 'typeorm';
/**
* Shipping lines — carriers registered by backoffice staff who sign in to the
* portal directly.
*
* Separate from `freight.companies` on purpose: a shipping line has no TIN,
* business licence, eTrade record, operational profile or onboarding state, so
* it shares none of the customer columns. `user_id` sits on the company row
* itself because the company IS the account — there is no contact-person row.
*
* No FK on `user_id`: `iam.users` belongs to the IAM service's schema, which
* this API reads but never owns.
*/
export class ShippingLineCompany3440000000000 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DO $$ BEGIN
CREATE TYPE freight.shipping_line_companies_status_enum
AS ENUM ('active', 'suspended');
EXCEPTION WHEN duplicate_object THEN NULL;
END $$
`);
await queryRunner.query(`
CREATE TABLE IF NOT EXISTS freight.shipping_line_companies (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL,
name varchar(200) NOT NULL,
scac_code varchar(4),
imo_number varchar(20),
bic_code varchar(20),
email varchar(150) NOT NULL,
phone_number varchar(30),
status freight.shipping_line_companies_status_enum
NOT NULL DEFAULT 'active',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz
)
`);
// One login per shipping line. Partial so a soft-deleted row frees its
// account for re-registration rather than blocking it forever.
await queryRunner.query(`
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_shipping_line_companies_user"
ON freight.shipping_line_companies (user_id)
WHERE deleted_at IS NULL
`);
// SCAC identifies the carrier globally — two live lines cannot share one.
await queryRunner.query(`
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_shipping_line_companies_scac"
ON freight.shipping_line_companies (scac_code)
WHERE scac_code IS NOT NULL AND deleted_at IS NULL
`);
await queryRunner.query(`
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_shipping_line_companies_email"
ON freight.shipping_line_companies (lower(email))
WHERE deleted_at IS NULL
`);
await queryRunner.query(`
CREATE INDEX IF NOT EXISTS "IDX_shipping_line_companies_status"
ON freight.shipping_line_companies (status)
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DROP TABLE IF EXISTS freight.shipping_line_companies`,
);
await queryRunner.query(
`DROP TYPE IF EXISTS freight.shipping_line_companies_status_enum`,
);
}
}