import { MigrationInterface, QueryRunner } from 'typeorm'; export class F4DocumentWorkflowFoundation1790000000000 implements MigrationInterface { name = 'F4DocumentWorkflowFoundation1790000000000'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(`ALTER TABLE inspection_acts ALTER COLUMN code TYPE varchar(40)`); await queryRunner.query(`ALTER TABLE inspection_reports ALTER COLUMN code TYPE varchar(40)`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS urgency varchar(24) NOT NULL DEFAULT 'NON_URGENT'`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS deadline_days integer`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS deadline_day_type varchar(24)`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS deadline_basis varchar(24)`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS deadline_base_at timestamptz`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS deadline_at timestamptz`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS locked_at timestamptz`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS locked_by uuid`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS locked_sha256 char(64)`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS sealed_at timestamptz`); await queryRunner.query(`ALTER TABLE inspection_acts ADD COLUMN IF NOT EXISTS sealed_by uuid`); await queryRunner.query(`CREATE INDEX IF NOT EXISTS idx_inspection_acts_deadline ON inspection_acts(deadline_at)`); await queryRunner.query(`ALTER TABLE inspection_findings ADD COLUMN IF NOT EXISTS is_recurrence boolean NOT NULL DEFAULT false`); await queryRunner.query(`ALTER TABLE inspection_findings ADD COLUMN IF NOT EXISTS recurrence_of_finding_id uuid`); await queryRunner.query(`CREATE INDEX IF NOT EXISTS idx_inspection_findings_recurrence_of ON inspection_findings(recurrence_of_finding_id)`); await queryRunner.query(` DO $$ BEGIN ALTER TABLE inspection_findings ADD CONSTRAINT fk_inspection_findings_recurrence_of FOREIGN KEY (recurrence_of_finding_id) REFERENCES inspection_findings(id) ON DELETE RESTRICT; EXCEPTION WHEN duplicate_object THEN NULL; END $$; `); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS executive_summary text`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS report_description text`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_if_identifier varchar(255)`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_officialized_at timestamptz`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_pdf_original_name varchar(255)`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_pdf_stored_name varchar(255)`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_pdf_mime_type varchar(120)`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_pdf_size_bytes integer`); await queryRunner.query(`ALTER TABLE inspection_reports ADD COLUMN IF NOT EXISTS gedo_pdf_sha256 char(64)`); await queryRunner.query(`CREATE INDEX IF NOT EXISTS idx_inspection_reports_gedo_officialized_at ON inspection_reports(gedo_officialized_at)`); await queryRunner.query(` CREATE TABLE IF NOT EXISTS inspection_deadline_policies ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), urgent_days integer NOT NULL DEFAULT 5 CHECK (urgent_days > 0), urgent_day_type varchar(24) NOT NULL DEFAULT 'BUSINESS', non_urgent_days integer NOT NULL DEFAULT 10 CHECK (non_urgent_days > 0), non_urgent_day_type varchar(24) NOT NULL DEFAULT 'BUSINESS', updated_by uuid, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT ck_inspection_deadline_policy_urgent_type CHECK (urgent_day_type IN ('BUSINESS','CALENDAR')), CONSTRAINT ck_inspection_deadline_policy_non_urgent_type CHECK (non_urgent_day_type IN ('BUSINESS','CALENDAR')) ) `); await queryRunner.query(` INSERT INTO inspection_deadline_policies (urgent_days, urgent_day_type, non_urgent_days, non_urgent_day_type) SELECT 5, 'BUSINESS', 10, 'BUSINESS' WHERE NOT EXISTS (SELECT 1 FROM inspection_deadline_policies) `); await queryRunner.query(` CREATE TABLE IF NOT EXISTS inspection_business_calendar_days ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), date date NOT NULL, is_business_day boolean NOT NULL DEFAULT false, label varchar(200) NOT NULL, updated_by uuid, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT uq_inspection_business_calendar_day UNIQUE(date) ) `); await queryRunner.query(` CREATE TABLE IF NOT EXISTS inspection_report_follow_ups ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), report_id uuid NOT NULL, type varchar(40) NOT NULL, external_reference varchar(255), occurred_at timestamptz NOT NULL, description text, original_name varchar(255), stored_name varchar(255), mime_type varchar(120), size_bytes integer, sha256 char(64), created_by uuid, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT fk_inspection_report_follow_ups_report FOREIGN KEY(report_id) REFERENCES inspection_reports(id) ON DELETE CASCADE, CONSTRAINT ck_inspection_report_follow_up_type CHECK (type IN ('COMPANY_NOTE','COMPANY_DOCUMENT','INTERNAL_NOTE','VERIFICATION','OTHER')) ) `); await queryRunner.query(`CREATE INDEX IF NOT EXISTS idx_inspection_report_follow_ups_report_created ON inspection_report_follow_ups(report_id, created_at)`); await queryRunner.query(` CREATE TABLE IF NOT EXISTS system_smtp_settings ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), host varchar(255) NOT NULL, port integer NOT NULL CHECK (port > 0 AND port <= 65535), security_mode varchar(24) NOT NULL DEFAULT 'STARTTLS', username varchar(255), password_enc text, from_name varchar(200) NOT NULL, from_email varchar(320) NOT NULL, reply_to varchar(320), enabled boolean NOT NULL DEFAULT true, updated_by uuid, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT ck_system_smtp_security_mode CHECK (security_mode IN ('NONE','STARTTLS','TLS')) ) `); await queryRunner.query(` UPDATE inspection_acts SET deadline_days = COALESCE(deadline_days, 10), deadline_day_type = COALESCE(deadline_day_type, 'BUSINESS'), deadline_basis = COALESCE(deadline_basis, 'GEDO_DATE') WHERE deadline_days IS NULL OR deadline_day_type IS NULL OR deadline_basis IS NULL `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`DROP TABLE IF EXISTS system_smtp_settings`); await queryRunner.query(`DROP TABLE IF EXISTS inspection_report_follow_ups`); await queryRunner.query(`DROP TABLE IF EXISTS inspection_business_calendar_days`); await queryRunner.query(`DROP TABLE IF EXISTS inspection_deadline_policies`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_pdf_sha256`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_pdf_size_bytes`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_pdf_mime_type`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_pdf_stored_name`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_pdf_original_name`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_officialized_at`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS gedo_if_identifier`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS report_description`); await queryRunner.query(`ALTER TABLE inspection_reports DROP COLUMN IF EXISTS executive_summary`); await queryRunner.query(`ALTER TABLE inspection_findings DROP CONSTRAINT IF EXISTS fk_inspection_findings_recurrence_of`); await queryRunner.query(`ALTER TABLE inspection_findings DROP COLUMN IF EXISTS recurrence_of_finding_id`); await queryRunner.query(`ALTER TABLE inspection_findings DROP COLUMN IF EXISTS is_recurrence`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS sealed_by`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS sealed_at`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS locked_sha256`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS locked_by`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS locked_at`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS deadline_at`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS deadline_base_at`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS deadline_basis`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS deadline_day_type`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS deadline_days`); await queryRunner.query(`ALTER TABLE inspection_acts DROP COLUMN IF EXISTS urgency`); } }