-- CreateTable CREATE TABLE "transfer_orders" ( "id" BIGSERIAL NOT NULL, "transfer_order_no" VARCHAR(50) NOT NULL, "seller_user_id" BIGINT NOT NULL, "seller_account_sequence" VARCHAR(20) NOT NULL, "buyer_user_id" BIGINT NOT NULL, "buyer_account_sequence" VARCHAR(20) NOT NULL, "source_order_no" VARCHAR(50) NOT NULL, "source_adoption_id" BIGINT NOT NULL, "tree_count" INTEGER NOT NULL, "contribution_per_tree" DECIMAL(20,10) NOT NULL, "original_adoption_date" DATE NOT NULL, "original_expire_date" DATE NOT NULL, "selected_province" VARCHAR(10) NOT NULL, "selected_city" VARCHAR(10) NOT NULL, "transfer_price" DECIMAL(20,8) NOT NULL, "platform_fee_rate" DECIMAL(5,4) NOT NULL, "platform_fee_amount" DECIMAL(20,8) NOT NULL, "seller_receive_amount" DECIMAL(20,8) NOT NULL, "status" VARCHAR(30) NOT NULL DEFAULT 'PENDING', "saga_step" VARCHAR(30) NOT NULL DEFAULT 'INIT', "fail_reason" VARCHAR(500), "retry_count" INTEGER NOT NULL DEFAULT 0, "seller_confirmed_at" TIMESTAMP(3), "payment_frozen_at" TIMESTAMP(3), "trees_locked_at" TIMESTAMP(3), "ownership_transferred_at" TIMESTAMP(3), "contribution_adjusted_at" TIMESTAMP(3), "stats_updated_at" TIMESTAMP(3), "payment_settled_at" TIMESTAMP(3), "completed_at" TIMESTAMP(3), "cancelled_at" TIMESTAMP(3), "rolled_back_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "transfer_orders_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "transfer_status_logs" ( "id" BIGSERIAL NOT NULL, "transfer_order_no" VARCHAR(50) NOT NULL, "from_status" VARCHAR(30) NOT NULL, "to_status" VARCHAR(30) NOT NULL, "from_saga_step" VARCHAR(30) NOT NULL, "to_saga_step" VARCHAR(30) NOT NULL, "operator_type" VARCHAR(20) NOT NULL, "operator_id" VARCHAR(50), "remark" VARCHAR(500), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "transfer_status_logs_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "outbox_events" ( "id" BIGSERIAL NOT NULL, "event_type" VARCHAR(100) NOT NULL, "topic" VARCHAR(200) NOT NULL, "key" VARCHAR(200) NOT NULL, "payload" JSONB NOT NULL, "aggregate_id" VARCHAR(100) NOT NULL, "aggregate_type" VARCHAR(100) NOT NULL, "status" VARCHAR(20) NOT NULL DEFAULT 'PENDING', "retry_count" INTEGER NOT NULL DEFAULT 0, "max_retries" INTEGER NOT NULL DEFAULT 5, "last_error" VARCHAR(1000), "published_at" TIMESTAMP(3), "next_retry_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "outbox_events_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "processed_events" ( "id" BIGSERIAL NOT NULL, "event_id" VARCHAR(200) NOT NULL, "event_type" VARCHAR(100) NOT NULL, "processed_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "processed_events_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "transfer_orders_transfer_order_no_key" ON "transfer_orders"("transfer_order_no"); -- CreateIndex CREATE INDEX "transfer_orders_seller_user_id_idx" ON "transfer_orders"("seller_user_id"); -- CreateIndex CREATE INDEX "transfer_orders_buyer_user_id_idx" ON "transfer_orders"("buyer_user_id"); -- CreateIndex CREATE INDEX "transfer_orders_source_order_no_idx" ON "transfer_orders"("source_order_no"); -- CreateIndex CREATE INDEX "transfer_orders_status_idx" ON "transfer_orders"("status"); -- CreateIndex CREATE INDEX "transfer_orders_created_at_idx" ON "transfer_orders"("created_at"); -- CreateIndex CREATE INDEX "transfer_status_logs_transfer_order_no_idx" ON "transfer_status_logs"("transfer_order_no"); -- CreateIndex CREATE INDEX "outbox_events_status_created_at_idx" ON "outbox_events"("status", "created_at"); -- CreateIndex CREATE INDEX "outbox_events_status_next_retry_at_idx" ON "outbox_events"("status", "next_retry_at"); -- CreateIndex CREATE UNIQUE INDEX "processed_events_event_id_key" ON "processed_events"("event_id"); -- AddForeignKey ALTER TABLE "transfer_status_logs" ADD CONSTRAINT "transfer_status_logs_transfer_order_no_fkey" FOREIGN KEY ("transfer_order_no") REFERENCES "transfer_orders"("transfer_order_no") ON DELETE RESTRICT ON UPDATE CASCADE;