mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 21:15:41 +00:00
54 lines
2.2 KiB
TypeScript
54 lines
2.2 KiB
TypeScript
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
|
|
/**
|
|
* CBE-protocol audit/idempotency ledger for the Unified Bill Payment integration
|
|
* (docs/cbe/CBE_IMPLEMENTATION_PLAN.md §4.2).
|
|
*
|
|
* - UNIQUE (end_to_end_txn_id, operation): DB-level backstop for the application idempotency
|
|
* checks — a concurrent duplicate of the same CBE attempt cannot create two rows.
|
|
* - Partial UNIQUE (cbe_txn_ref) on settled PAYMENTs: blocks Cbe_Txn_Ref replay across bills.
|
|
*
|
|
* DATA SAFETY: new table only; nothing existing is touched.
|
|
*/
|
|
export class CreateCbeBillOperation1782400000000 implements MigrationInterface {
|
|
name = "CreateCbeBillOperation1782400000000";
|
|
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(`
|
|
CREATE TABLE IF NOT EXISTS "edr_payment"."cbe_bill_operation" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
"operation" varchar(16) NOT NULL,
|
|
"bill_id" varchar(32) NOT NULL,
|
|
"end_to_end_txn_id" varchar(128) NOT NULL,
|
|
"cbe_txn_ref" varchar(128),
|
|
"destination_api_name" varchar(64),
|
|
"intent_id" uuid,
|
|
"trade_status" varchar(16) NOT NULL,
|
|
"failure_class" varchar(16),
|
|
"response_code" varchar(8),
|
|
"response_description" text,
|
|
"request_payload" jsonb NOT NULL,
|
|
"response_payload" jsonb,
|
|
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
"deleted_at" timestamptz
|
|
)
|
|
`);
|
|
await queryRunner.query(
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS "uq_cbe_bill_operation_e2e" ON "edr_payment"."cbe_bill_operation" ("end_to_end_txn_id", "operation")`,
|
|
);
|
|
await queryRunner.query(
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS "uq_cbe_bill_operation_txn_ref" ON "edr_payment"."cbe_bill_operation" ("cbe_txn_ref") WHERE "operation" = 'PAYMENT' AND "trade_status" = 'SUCCESS'`,
|
|
);
|
|
await queryRunner.query(
|
|
`CREATE INDEX IF NOT EXISTS "idx_cbe_bill_operation_bill" ON "edr_payment"."cbe_bill_operation" ("bill_id", "operation")`,
|
|
);
|
|
}
|
|
|
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(
|
|
`DROP TABLE IF EXISTS "edr_payment"."cbe_bill_operation"`,
|
|
);
|
|
}
|
|
}
|