rwadurian/backend/services/contribution-service/prisma/migrations/20260111000000_init/migration.sql

497 lines
22 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ============================================
-- Migration: contribution-service 初始化
--
-- 包含所有表的创建:
-- 1. CDC 同步表 (synced_users, synced_adoptions, synced_referrals)
-- 2. 算力账户表 (contribution_accounts)
-- 3. 算力明细表 (contribution_records)
-- 4. 解锁事件表 (unlock_events)
-- 5. 未分配算力表 (unallocated_contributions)
-- 6. 系统账户表 (system_accounts, system_contribution_records)
-- 7. 快照与统计表 (daily_contribution_snapshots, user_team_stats)
-- 8. CDC 同步状态表 (cdc_sync_progress, processed_events)
-- 9. 配置表 (contribution_configs, distribution_rate_configs)
-- 10. Outbox 事件表 (outbox_events)
-- ============================================
-- ============================================
-- 1. CDC 同步数据表
-- ============================================
-- 同步的用户数据
CREATE TABLE "synced_users" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
"original_user_id" BIGINT NOT NULL,
"phone" VARCHAR(20),
"status" VARCHAR(20),
"source_sequence_num" BIGINT NOT NULL,
"synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"contribution_calculated" BOOLEAN NOT NULL DEFAULT false,
"contribution_calculated_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "synced_users_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "synced_users_account_sequence_key" ON "synced_users"("account_sequence");
CREATE INDEX "synced_users_original_user_id_idx" ON "synced_users"("original_user_id");
CREATE INDEX "synced_users_contribution_calculated_idx" ON "synced_users"("contribution_calculated");
-- 同步的认种数据
CREATE TABLE "synced_adoptions" (
"id" BIGSERIAL NOT NULL,
"original_adoption_id" BIGINT NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
"tree_count" INTEGER NOT NULL,
"adoption_date" DATE NOT NULL,
"status" VARCHAR(20),
"contribution_per_tree" DECIMAL(20,10) NOT NULL,
"source_sequence_num" BIGINT NOT NULL,
"synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"contribution_distributed" BOOLEAN NOT NULL DEFAULT false,
"contribution_distributed_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "synced_adoptions_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "synced_adoptions_original_adoption_id_key" ON "synced_adoptions"("original_adoption_id");
CREATE INDEX "synced_adoptions_account_sequence_idx" ON "synced_adoptions"("account_sequence");
CREATE INDEX "synced_adoptions_adoption_date_idx" ON "synced_adoptions"("adoption_date");
CREATE INDEX "synced_adoptions_contribution_distributed_idx" ON "synced_adoptions"("contribution_distributed");
-- 同步的推荐关系数据
CREATE TABLE "synced_referrals" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
"referrer_account_sequence" VARCHAR(20),
"ancestor_path" TEXT,
"depth" INTEGER NOT NULL DEFAULT 0,
"source_sequence_num" BIGINT NOT NULL,
"synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "synced_referrals_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "synced_referrals_account_sequence_key" ON "synced_referrals"("account_sequence");
CREATE INDEX "synced_referrals_referrer_account_sequence_idx" ON "synced_referrals"("referrer_account_sequence");
-- ============================================
-- 2. 算力账户表
-- ============================================
-- 算力账户表(汇总)
-- 设计说明:
-- - 个人算力:自己认种,立即生效
-- - 层级算力下级1-15层认种的分成每层0.5%共7.5%
-- - 加成算力团队加成3档各2.5%共7.5%
-- 解锁规则:
-- - 自己认种解锁层级1-5 + 加成第1档
-- - 直推≥2人认种解锁加成第2档
-- - 直推≥3人认种解锁层级6-10
-- - 直推≥4人认种解锁加成第3档
-- - 直推≥5人认种解锁层级11-15
CREATE TABLE "contribution_accounts" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
-- 个人算力(立即生效)
"personal_contribution" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 15级层级算力待解锁
-- 第1档(1-5级):自己认种解锁
"level_1_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_2_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_3_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_4_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_5_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 第2档(6-10级)直推≥3人认种解锁
"level_6_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_7_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_8_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_9_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_10_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 第3档(11-15级)直推≥5人认种解锁
"level_11_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_12_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_13_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_14_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"level_15_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 3档加成算力待解锁
"bonus_tier_1_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"bonus_tier_2_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"bonus_tier_3_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 汇总字段
"total_level_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"total_bonus_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"total_pending" DECIMAL(30,10) NOT NULL DEFAULT 0,
"total_unlocked" DECIMAL(30,10) NOT NULL DEFAULT 0,
"effective_contribution" DECIMAL(30,10) NOT NULL DEFAULT 0,
-- 解锁条件状态
"has_adopted" BOOLEAN NOT NULL DEFAULT false,
"direct_referral_adopted_count" INTEGER NOT NULL DEFAULT 0,
"unlocked_level_depth" INTEGER NOT NULL DEFAULT 0,
"unlocked_bonus_tiers" INTEGER NOT NULL DEFAULT 0,
-- 乐观锁
"version" INTEGER NOT NULL DEFAULT 1,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "contribution_accounts_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "contribution_accounts_account_sequence_key" ON "contribution_accounts"("account_sequence");
CREATE INDEX "contribution_accounts_effective_contribution_idx" ON "contribution_accounts"("effective_contribution" DESC);
CREATE INDEX "contribution_accounts_has_adopted_idx" ON "contribution_accounts"("has_adopted");
CREATE INDEX "contribution_accounts_direct_referral_adopted_count_idx" ON "contribution_accounts"("direct_referral_adopted_count");
-- 添加字段注释
COMMENT ON COLUMN "contribution_accounts"."level_1_pending" IS '第1级待解锁算力 (0.5%)';
COMMENT ON COLUMN "contribution_accounts"."level_2_pending" IS '第2级待解锁算力 (0.5%)';
COMMENT ON COLUMN "contribution_accounts"."level_3_pending" IS '第3级待解锁算力 (0.5%)';
COMMENT ON COLUMN "contribution_accounts"."level_4_pending" IS '第4级待解锁算力 (0.5%)';
COMMENT ON COLUMN "contribution_accounts"."level_5_pending" IS '第5级待解锁算力 (0.5%)';
COMMENT ON COLUMN "contribution_accounts"."level_6_pending" IS '第6级待解锁算力 (0.5%) - 直推≥3人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_7_pending" IS '第7级待解锁算力 (0.5%) - 直推≥3人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_8_pending" IS '第8级待解锁算力 (0.5%) - 直推≥3人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_9_pending" IS '第9级待解锁算力 (0.5%) - 直推≥3人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_10_pending" IS '第10级待解锁算力 (0.5%) - 直推≥3人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_11_pending" IS '第11级待解锁算力 (0.5%) - 直推≥5人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_12_pending" IS '第12级待解锁算力 (0.5%) - 直推≥5人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_13_pending" IS '第13级待解锁算力 (0.5%) - 直推≥5人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_14_pending" IS '第14级待解锁算力 (0.5%) - 直推≥5人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."level_15_pending" IS '第15级待解锁算力 (0.5%) - 直推≥5人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."bonus_tier_1_pending" IS '第1档加成待解锁算力 (2.5%) - 自己认种解锁';
COMMENT ON COLUMN "contribution_accounts"."bonus_tier_2_pending" IS '第2档加成待解锁算力 (2.5%) - 直推≥2人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."bonus_tier_3_pending" IS '第3档加成待解锁算力 (2.5%) - 直推≥4人认种解锁';
COMMENT ON COLUMN "contribution_accounts"."unlocked_level_depth" IS '已解锁层级深度: 0=未解锁, 5=1-5级, 10=1-10级, 15=全部';
COMMENT ON COLUMN "contribution_accounts"."unlocked_bonus_tiers" IS '已解锁加成档位数: 0/1/2/3';
COMMENT ON COLUMN "contribution_accounts"."effective_contribution" IS '有效算力 = 个人算力 + 已解锁算力';
-- ============================================
-- 3. 算力明细表
-- ============================================
CREATE TABLE "contribution_records" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
-- 来源信息(可追溯)
"source_type" VARCHAR(30) NOT NULL,
"source_adoption_id" BIGINT NOT NULL,
"source_account_sequence" VARCHAR(20) NOT NULL,
-- 计算参数(审计用)
"tree_count" INTEGER NOT NULL,
"base_contribution" DECIMAL(20,10) NOT NULL,
"distribution_rate" DECIMAL(10,6) NOT NULL,
"level_depth" INTEGER,
"bonus_tier" INTEGER,
-- 金额
"amount" DECIMAL(30,10) NOT NULL,
-- 解锁状态
"status" VARCHAR(20) NOT NULL DEFAULT 'PENDING',
"unlocked_at" TIMESTAMP(3),
"unlock_reason" VARCHAR(200),
-- 有效期
"effective_date" DATE NOT NULL,
"expire_date" DATE NOT NULL,
"is_expired" BOOLEAN NOT NULL DEFAULT false,
"expired_at" TIMESTAMP(3),
-- 备注
"remark" VARCHAR(500),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "contribution_records_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "contribution_records_account_sequence_status_idx" ON "contribution_records"("account_sequence", "status");
CREATE INDEX "contribution_records_account_sequence_created_at_idx" ON "contribution_records"("account_sequence", "created_at" DESC);
CREATE INDEX "contribution_records_source_adoption_id_idx" ON "contribution_records"("source_adoption_id");
CREATE INDEX "contribution_records_source_account_sequence_idx" ON "contribution_records"("source_account_sequence");
CREATE INDEX "contribution_records_source_type_idx" ON "contribution_records"("source_type");
CREATE INDEX "contribution_records_status_idx" ON "contribution_records"("status");
CREATE INDEX "contribution_records_expire_date_idx" ON "contribution_records"("expire_date");
CREATE INDEX "contribution_records_is_expired_idx" ON "contribution_records"("is_expired");
COMMENT ON COLUMN "contribution_records"."status" IS '状态: PENDING(待解锁)/UNLOCKED(已解锁)/EFFECTIVE(已生效)';
COMMENT ON COLUMN "contribution_records"."source_type" IS '来源类型: PERSONAL/LEVEL_1~15/BONUS_TIER_1~3';
-- ============================================
-- 4. 解锁事件表
-- ============================================
CREATE TABLE "unlock_events" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
-- 触发信息
"trigger_type" VARCHAR(30) NOT NULL,
"trigger_adoption_id" BIGINT NOT NULL,
"trigger_account_sequence" VARCHAR(20) NOT NULL,
-- 解锁内容
"unlock_type" VARCHAR(30) NOT NULL,
"unlock_condition" VARCHAR(100) NOT NULL,
-- 解锁前后状态
"before_direct_referral_count" INTEGER NOT NULL,
"after_direct_referral_count" INTEGER NOT NULL,
"before_unlocked_level_depth" INTEGER NOT NULL,
"after_unlocked_level_depth" INTEGER NOT NULL,
"before_unlocked_bonus_tiers" INTEGER NOT NULL,
"after_unlocked_bonus_tiers" INTEGER NOT NULL,
-- 解锁金额
"unlocked_amount" DECIMAL(30,10) NOT NULL,
"unlocked_record_count" INTEGER NOT NULL,
-- 备注
"remark" VARCHAR(500),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "unlock_events_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "unlock_events_account_sequence_idx" ON "unlock_events"("account_sequence");
CREATE INDEX "unlock_events_trigger_account_sequence_idx" ON "unlock_events"("trigger_account_sequence");
CREATE INDEX "unlock_events_trigger_adoption_id_idx" ON "unlock_events"("trigger_adoption_id");
CREATE INDEX "unlock_events_unlock_type_idx" ON "unlock_events"("unlock_type");
CREATE INDEX "unlock_events_created_at_idx" ON "unlock_events"("created_at" DESC);
COMMENT ON TABLE "unlock_events" IS '解锁事件记录表 - 记录每次算力解锁的触发原因和结果';
COMMENT ON COLUMN "unlock_events"."trigger_type" IS '触发类型: SELF_ADOPT(自己认种) / REFERRAL_ADOPT(直推认种)';
COMMENT ON COLUMN "unlock_events"."unlock_type" IS '解锁类型: LEVEL_1_5/LEVEL_6_10/LEVEL_11_15/BONUS_TIER_1/BONUS_TIER_2/BONUS_TIER_3';
COMMENT ON COLUMN "unlock_events"."unlock_condition" IS '解锁条件描述,如"自己认种"、"直推认种人数达到3人"';
-- ============================================
-- 5. 未分配算力表
-- ============================================
CREATE TABLE "unallocated_contributions" (
"id" BIGSERIAL NOT NULL,
"source_adoption_id" BIGINT NOT NULL,
"source_account_sequence" VARCHAR(20) NOT NULL,
-- 未分配类型
"unalloc_type" VARCHAR(30) NOT NULL,
"would_be_account_sequence" VARCHAR(20),
"level_depth" INTEGER,
"bonus_tier" INTEGER,
"amount" DECIMAL(30,10) NOT NULL,
"reason" VARCHAR(200),
-- 分配状态
"status" VARCHAR(20) NOT NULL DEFAULT 'PENDING',
"allocated_at" TIMESTAMP(3),
"allocated_to_account_sequence" VARCHAR(20),
-- 有效期
"effective_date" DATE NOT NULL,
"expire_date" DATE NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "unallocated_contributions_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "unallocated_contributions_source_adoption_id_idx" ON "unallocated_contributions"("source_adoption_id");
CREATE INDEX "unallocated_contributions_would_be_account_sequence_idx" ON "unallocated_contributions"("would_be_account_sequence");
CREATE INDEX "unallocated_contributions_unalloc_type_idx" ON "unallocated_contributions"("unalloc_type");
CREATE INDEX "unallocated_contributions_status_idx" ON "unallocated_contributions"("status");
-- ============================================
-- 6. 系统账户表
-- ============================================
CREATE TABLE "system_accounts" (
"id" BIGSERIAL NOT NULL,
"account_type" VARCHAR(20) NOT NULL,
"name" VARCHAR(100) NOT NULL,
"contribution_balance" DECIMAL(30,10) NOT NULL DEFAULT 0,
"contribution_never_expires" BOOLEAN NOT NULL DEFAULT false,
"version" INTEGER NOT NULL DEFAULT 1,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "system_accounts_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "system_accounts_account_type_key" ON "system_accounts"("account_type");
CREATE TABLE "system_contribution_records" (
"id" BIGSERIAL NOT NULL,
"system_account_id" BIGINT NOT NULL,
"source_adoption_id" BIGINT NOT NULL,
"source_account_sequence" VARCHAR(20) NOT NULL,
"distribution_rate" DECIMAL(10,6) NOT NULL,
"amount" DECIMAL(30,10) NOT NULL,
"effective_date" DATE NOT NULL,
"expire_date" DATE,
"is_expired" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "system_contribution_records_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "system_contribution_records_system_account_id_idx" ON "system_contribution_records"("system_account_id");
CREATE INDEX "system_contribution_records_source_adoption_id_idx" ON "system_contribution_records"("source_adoption_id");
ALTER TABLE "system_contribution_records" ADD CONSTRAINT "system_contribution_records_system_account_id_fkey" FOREIGN KEY ("system_account_id") REFERENCES "system_accounts"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- ============================================
-- 7. 快照与统计表
-- ============================================
-- 每日算力快照
CREATE TABLE "daily_contribution_snapshots" (
"id" BIGSERIAL NOT NULL,
"snapshot_date" DATE NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
"effective_contribution" DECIMAL(30,10) NOT NULL,
"network_total_contribution" DECIMAL(30,10) NOT NULL,
"contribution_ratio" DECIMAL(30,18) NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "daily_contribution_snapshots_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "daily_contribution_snapshots_snapshot_date_account_sequence_key" ON "daily_contribution_snapshots"("snapshot_date", "account_sequence");
CREATE INDEX "daily_contribution_snapshots_snapshot_date_idx" ON "daily_contribution_snapshots"("snapshot_date");
CREATE INDEX "daily_contribution_snapshots_account_sequence_idx" ON "daily_contribution_snapshots"("account_sequence");
-- 用户团队统计
CREATE TABLE "user_team_stats" (
"id" BIGSERIAL NOT NULL,
"account_sequence" VARCHAR(20) NOT NULL,
"stats_date" DATE NOT NULL,
"level_1_trees" INTEGER NOT NULL DEFAULT 0,
"level_2_trees" INTEGER NOT NULL DEFAULT 0,
"level_3_trees" INTEGER NOT NULL DEFAULT 0,
"level_4_trees" INTEGER NOT NULL DEFAULT 0,
"level_5_trees" INTEGER NOT NULL DEFAULT 0,
"level_6_trees" INTEGER NOT NULL DEFAULT 0,
"level_7_trees" INTEGER NOT NULL DEFAULT 0,
"level_8_trees" INTEGER NOT NULL DEFAULT 0,
"level_9_trees" INTEGER NOT NULL DEFAULT 0,
"level_10_trees" INTEGER NOT NULL DEFAULT 0,
"level_11_trees" INTEGER NOT NULL DEFAULT 0,
"level_12_trees" INTEGER NOT NULL DEFAULT 0,
"level_13_trees" INTEGER NOT NULL DEFAULT 0,
"level_14_trees" INTEGER NOT NULL DEFAULT 0,
"level_15_trees" INTEGER NOT NULL DEFAULT 0,
"total_team_trees" INTEGER NOT NULL DEFAULT 0,
"direct_adopted_referrals" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "user_team_stats_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "user_team_stats_account_sequence_stats_date_key" ON "user_team_stats"("account_sequence", "stats_date");
CREATE INDEX "user_team_stats_account_sequence_idx" ON "user_team_stats"("account_sequence");
CREATE INDEX "user_team_stats_stats_date_idx" ON "user_team_stats"("stats_date");
-- ============================================
-- 8. CDC 同步状态表
-- ============================================
CREATE TABLE "cdc_sync_progress" (
"id" BIGSERIAL NOT NULL,
"source_topic" VARCHAR(100) NOT NULL,
"last_sequence_num" BIGINT NOT NULL DEFAULT 0,
"last_synced_at" TIMESTAMP(3),
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "cdc_sync_progress_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "cdc_sync_progress_source_topic_key" ON "cdc_sync_progress"("source_topic");
CREATE TABLE "processed_events" (
"id" BIGSERIAL NOT NULL,
"event_id" VARCHAR(100) NOT NULL,
"event_type" VARCHAR(50) NOT NULL,
"source_service" VARCHAR(50),
"processed_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "processed_events_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "processed_events_event_id_key" ON "processed_events"("event_id");
CREATE INDEX "processed_events_event_type_idx" ON "processed_events"("event_type");
CREATE INDEX "processed_events_processed_at_idx" ON "processed_events"("processed_at");
-- ============================================
-- 9. 配置表
-- ============================================
CREATE TABLE "contribution_configs" (
"id" BIGSERIAL NOT NULL,
"base_contribution" DECIMAL(20,10) NOT NULL DEFAULT 22617,
"increment_percentage" DECIMAL(10,6) NOT NULL DEFAULT 0.003,
"unit_size" INTEGER NOT NULL DEFAULT 100,
"start_tree_number" INTEGER NOT NULL DEFAULT 1000,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "contribution_configs_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "contribution_configs_is_active_idx" ON "contribution_configs"("is_active");
CREATE TABLE "distribution_rate_configs" (
"id" BIGSERIAL NOT NULL,
"rate_type" VARCHAR(30) NOT NULL,
"rate_value" DECIMAL(10,6) NOT NULL,
"description" VARCHAR(100),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "distribution_rate_configs_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "distribution_rate_configs_rate_type_key" ON "distribution_rate_configs"("rate_type");
CREATE INDEX "distribution_rate_configs_is_active_idx" ON "distribution_rate_configs"("is_active");
-- ============================================
-- 10. Outbox 事件表
-- ============================================
CREATE TABLE "outbox_events" (
"outbox_id" BIGSERIAL NOT NULL,
"event_type" VARCHAR(100) NOT NULL,
"topic" VARCHAR(100) NOT NULL,
"key" VARCHAR(200) NOT NULL,
"payload" JSONB NOT NULL,
"aggregate_id" VARCHAR(100) NOT NULL,
"aggregate_type" VARCHAR(50) 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" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"published_at" TIMESTAMP(3),
"next_retry_at" TIMESTAMP(3),
CONSTRAINT "outbox_events_pkey" PRIMARY KEY ("outbox_id")
);
CREATE INDEX "outbox_events_status_created_at_idx" ON "outbox_events"("status", "created_at");
CREATE INDEX "outbox_events_status_next_retry_at_idx" ON "outbox_events"("status", "next_retry_at");
CREATE INDEX "outbox_events_aggregate_type_aggregate_id_idx" ON "outbox_events"("aggregate_type", "aggregate_id");
CREATE INDEX "outbox_events_topic_idx" ON "outbox_events"("topic");