-- Generated by aether-data-schema from schema/logical/*.toml.
-- Do not edit generated files directly; edit logical schema or explicit overrides instead.

CREATE TABLE IF NOT EXISTS public.wallets (
    id character varying(64) NOT NULL,
    user_id character varying(64),
    api_key_id character varying(64),
    balance double precision DEFAULT 0 NOT NULL,
    gift_balance double precision DEFAULT 0 NOT NULL,
    limit_mode character varying(64) DEFAULT 'finite' NOT NULL,
    currency character varying(16) DEFAULT 'USD' NOT NULL,
    status character varying(64) DEFAULT 'active' NOT NULL,
    total_recharged double precision DEFAULT 0 NOT NULL,
    total_consumed double precision DEFAULT 0 NOT NULL,
    total_refunded double precision DEFAULT 0 NOT NULL,
    total_adjusted double precision DEFAULT 0 NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.wallets ADD CONSTRAINT wallets_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.wallets ADD CONSTRAINT wallets_user_id_key UNIQUE (user_id);
ALTER TABLE ONLY public.wallets ADD CONSTRAINT wallets_api_key_id_key UNIQUE (api_key_id);
CREATE INDEX IF NOT EXISTS wallets_api_key_id_idx ON public.wallets USING btree (api_key_id);
CREATE INDEX IF NOT EXISTS wallets_user_id_idx ON public.wallets USING btree (user_id);

CREATE TABLE IF NOT EXISTS public.wallet_transactions (
    id character varying(64) NOT NULL,
    wallet_id character varying(64) NOT NULL,
    category character varying(64) NOT NULL,
    reason_code character varying(64) NOT NULL,
    amount double precision NOT NULL,
    balance_before double precision NOT NULL,
    balance_after double precision NOT NULL,
    recharge_balance_before double precision NOT NULL,
    recharge_balance_after double precision NOT NULL,
    gift_balance_before double precision NOT NULL,
    gift_balance_after double precision NOT NULL,
    link_type character varying(64),
    link_id character varying(128),
    operator_id character varying(64),
    description text,
    created_at bigint NOT NULL
);

ALTER TABLE ONLY public.wallet_transactions ADD CONSTRAINT wallet_transactions_pkey PRIMARY KEY (id);
CREATE INDEX IF NOT EXISTS idx_wallet_tx_wallet_created ON public.wallet_transactions USING btree (wallet_id, created_at);
CREATE INDEX IF NOT EXISTS idx_wallet_tx_category_created ON public.wallet_transactions USING btree (category, created_at);
CREATE INDEX IF NOT EXISTS idx_wallet_tx_reason_created ON public.wallet_transactions USING btree (reason_code, created_at);
CREATE INDEX IF NOT EXISTS idx_wallet_tx_link ON public.wallet_transactions USING btree (link_type, link_id);
CREATE INDEX IF NOT EXISTS ix_wallet_transactions_operator_id ON public.wallet_transactions USING btree (operator_id);

CREATE TABLE IF NOT EXISTS public.wallet_daily_usage_ledgers (
    id character varying(64) NOT NULL,
    wallet_id character varying(64) NOT NULL,
    billing_date character varying(16) NOT NULL,
    billing_timezone character varying(64) NOT NULL,
    total_cost_usd double precision DEFAULT 0 NOT NULL,
    total_requests bigint DEFAULT 0 NOT NULL,
    input_tokens bigint DEFAULT 0 NOT NULL,
    output_tokens bigint DEFAULT 0 NOT NULL,
    cache_creation_tokens bigint DEFAULT 0 NOT NULL,
    cache_read_tokens bigint DEFAULT 0 NOT NULL,
    first_finalized_at bigint,
    last_finalized_at bigint,
    aggregated_at bigint NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.wallet_daily_usage_ledgers ADD CONSTRAINT wallet_daily_usage_ledgers_pkey PRIMARY KEY (id);
CREATE INDEX IF NOT EXISTS idx_wallet_daily_usage_wallet_date ON public.wallet_daily_usage_ledgers USING btree (wallet_id, billing_timezone, billing_date);

CREATE TABLE IF NOT EXISTS public.payment_orders (
    id character varying(64) NOT NULL,
    order_no character varying(128) NOT NULL,
    wallet_id character varying(64) NOT NULL,
    user_id character varying(64),
    amount_usd double precision NOT NULL,
    pay_amount double precision,
    pay_currency character varying(16),
    exchange_rate double precision,
    refunded_amount_usd double precision DEFAULT 0 NOT NULL,
    refundable_amount_usd double precision DEFAULT 0 NOT NULL,
    payment_method character varying(64) NOT NULL,
    payment_provider character varying(64),
    payment_channel character varying(64),
    order_kind character varying(64) DEFAULT 'wallet_recharge' NOT NULL,
    product_id character varying(64),
    product_snapshot jsonb,
    fulfillment_status character varying(64) DEFAULT 'pending' NOT NULL,
    fulfillment_error text,
    gateway_order_id character varying(128),
    gateway_response jsonb,
    status character varying(64) DEFAULT 'pending' NOT NULL,
    created_at bigint NOT NULL,
    paid_at bigint,
    credited_at bigint,
    expires_at bigint
);

ALTER TABLE ONLY public.payment_orders ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.payment_orders ADD CONSTRAINT uq_payment_orders_order_no UNIQUE (order_no);
CREATE INDEX IF NOT EXISTS idx_payment_orders_wallet_created ON public.payment_orders USING btree (wallet_id, created_at);
CREATE INDEX IF NOT EXISTS idx_payment_orders_user_created ON public.payment_orders USING btree (user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_payment_orders_status ON public.payment_orders USING btree (status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_gateway_order_id ON public.payment_orders USING btree (gateway_order_id);
CREATE INDEX IF NOT EXISTS idx_payment_orders_kind_status ON public.payment_orders USING btree (order_kind, status);
CREATE INDEX IF NOT EXISTS idx_payment_orders_product ON public.payment_orders USING btree (product_id);

CREATE TABLE IF NOT EXISTS public.user_invite_codes (
    user_id character varying(64) NOT NULL,
    invite_code character varying(64) NOT NULL,
    active boolean DEFAULT true NOT NULL,
    created_at timestamp with time zone NOT NULL,
    updated_at timestamp with time zone NOT NULL
);

ALTER TABLE ONLY public.user_invite_codes ADD CONSTRAINT user_invite_codes_pkey PRIMARY KEY (user_id);
ALTER TABLE ONLY public.user_invite_codes ADD CONSTRAINT user_invite_codes_invite_code_key UNIQUE (invite_code);
ALTER TABLE ONLY public.user_invite_codes ADD CONSTRAINT user_invite_codes_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;

CREATE TABLE IF NOT EXISTS public.user_referrals (
    id character varying(64) NOT NULL,
    inviter_user_id character varying(64) NOT NULL,
    invitee_user_id character varying(64) NOT NULL,
    invite_code_snapshot character varying(64) NOT NULL,
    source_json jsonb,
    first_paid_order_id character varying(64),
    first_paid_at timestamp with time zone,
    created_at timestamp with time zone NOT NULL,
    updated_at timestamp with time zone NOT NULL
);

ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_invitee_user_id_key UNIQUE (invitee_user_id);
CREATE INDEX IF NOT EXISTS idx_user_referrals_inviter ON public.user_referrals USING btree (inviter_user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_user_referrals_created ON public.user_referrals USING btree (created_at);
CREATE INDEX IF NOT EXISTS idx_user_referrals_invite_code ON public.user_referrals USING btree (invite_code_snapshot);
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.user_referrals ADD CONSTRAINT user_referrals_first_paid_order_fkey FOREIGN KEY (first_paid_order_id) REFERENCES public.payment_orders(id) ON DELETE SET NULL;

CREATE TABLE IF NOT EXISTS public.referral_rewards (
    id character varying(64) NOT NULL,
    referral_id character varying(64) NOT NULL,
    inviter_user_id character varying(64) NOT NULL,
    invitee_user_id character varying(64) NOT NULL,
    reward_type character varying(32) NOT NULL,
    trigger_point character varying(64) NOT NULL,
    source_order_id character varying(64),
    idempotency_key character varying(128) NOT NULL,
    amount_usd double precision NOT NULL,
    status character varying(32) DEFAULT 'pending' NOT NULL,
    wallet_transaction_id character varying(64),
    reversed_amount_usd double precision DEFAULT 0 NOT NULL,
    pending_reversal_amount_usd double precision DEFAULT 0 NOT NULL,
    failure_reason text,
    admin_operator_id character varying(64),
    admin_note text,
    created_at timestamp with time zone NOT NULL,
    updated_at timestamp with time zone NOT NULL
);

ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_idempotency_key_key UNIQUE (idempotency_key);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_inviter_status ON public.referral_rewards USING btree (inviter_user_id, status, created_at);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_inviter_created ON public.referral_rewards USING btree (inviter_user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_created ON public.referral_rewards USING btree (created_at);
CREATE INDEX IF NOT EXISTS idx_referral_rewards_source_order ON public.referral_rewards USING btree (source_order_id);
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_referral_id_fkey FOREIGN KEY (referral_id) REFERENCES public.user_referrals(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_inviter_user_id_fkey FOREIGN KEY (inviter_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_invitee_user_id_fkey FOREIGN KEY (invitee_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.referral_rewards ADD CONSTRAINT referral_rewards_source_order_fkey FOREIGN KEY (source_order_id) REFERENCES public.payment_orders(id) ON DELETE SET NULL;

CREATE TABLE IF NOT EXISTS public.payment_gateway_configs (
    provider character varying(64) NOT NULL,
    enabled boolean DEFAULT false NOT NULL,
    endpoint_url character varying(512) NOT NULL,
    callback_base_url character varying(512),
    merchant_id character varying(128) NOT NULL,
    merchant_key_encrypted text,
    pay_currency character varying(16) DEFAULT 'CNY' NOT NULL,
    usd_exchange_rate double precision DEFAULT 7.2 NOT NULL,
    min_recharge_usd double precision DEFAULT 1 NOT NULL,
    channels_json jsonb,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.payment_gateway_configs ADD CONSTRAINT payment_gateway_configs_pkey PRIMARY KEY (provider);

CREATE TABLE IF NOT EXISTS public.payment_callbacks (
    id character varying(64) NOT NULL,
    payment_order_id character varying(64),
    payment_method character varying(64) NOT NULL,
    callback_key character varying(128) NOT NULL,
    order_no character varying(128),
    gateway_order_id character varying(128),
    payload_hash character varying(128),
    signature_valid boolean DEFAULT false NOT NULL,
    status character varying(64) DEFAULT 'received' NOT NULL,
    payload jsonb,
    error_message text,
    created_at bigint NOT NULL,
    processed_at bigint
);

ALTER TABLE ONLY public.payment_callbacks ADD CONSTRAINT payment_callbacks_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.payment_callbacks ADD CONSTRAINT uq_payment_callbacks_callback_key UNIQUE (callback_key);
CREATE INDEX IF NOT EXISTS idx_payment_callbacks_order ON public.payment_callbacks USING btree (order_no);
CREATE INDEX IF NOT EXISTS idx_payment_callbacks_gateway_order ON public.payment_callbacks USING btree (gateway_order_id);
CREATE INDEX IF NOT EXISTS idx_payment_callbacks_created ON public.payment_callbacks USING btree (created_at);
CREATE INDEX IF NOT EXISTS ix_payment_callbacks_payment_order_id ON public.payment_callbacks USING btree (payment_order_id);

CREATE TABLE IF NOT EXISTS public.billing_plans (
    id character varying(64) NOT NULL,
    title character varying(128) NOT NULL,
    description text,
    price_amount double precision NOT NULL,
    price_currency character varying(16) DEFAULT 'CNY' NOT NULL,
    duration_unit character varying(32) NOT NULL,
    duration_value bigint NOT NULL,
    enabled boolean DEFAULT true NOT NULL,
    sort_order bigint DEFAULT 0 NOT NULL,
    max_active_per_user bigint DEFAULT 1 NOT NULL,
    purchase_limit_scope character varying(32) DEFAULT 'active_period' NOT NULL,
    entitlements_json jsonb NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.billing_plans ADD CONSTRAINT billing_plans_pkey PRIMARY KEY (id);
CREATE INDEX IF NOT EXISTS idx_billing_plans_enabled_sort ON public.billing_plans USING btree (enabled, sort_order);

CREATE TABLE IF NOT EXISTS public.user_plan_entitlements (
    id character varying(64) NOT NULL,
    user_id character varying(64) NOT NULL,
    plan_id character varying(64) NOT NULL,
    payment_order_id character varying(64) NOT NULL,
    status character varying(64) DEFAULT 'active' NOT NULL,
    starts_at bigint NOT NULL,
    expires_at bigint NOT NULL,
    entitlements_snapshot jsonb NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.user_plan_entitlements ADD CONSTRAINT user_plan_entitlements_pkey PRIMARY KEY (id);
CREATE INDEX IF NOT EXISTS idx_user_plan_entitlements_user_active ON public.user_plan_entitlements USING btree (user_id, status, expires_at);
CREATE INDEX IF NOT EXISTS idx_user_plan_entitlements_order ON public.user_plan_entitlements USING btree (payment_order_id);

CREATE TABLE IF NOT EXISTS public.entitlement_usage_ledgers (
    id character varying(64) NOT NULL,
    user_entitlement_id character varying(64) NOT NULL,
    user_id character varying(64) NOT NULL,
    request_id character varying(128) NOT NULL,
    amount_usd double precision NOT NULL,
    balance_before double precision NOT NULL,
    balance_after double precision NOT NULL,
    usage_date character varying(16) NOT NULL,
    created_at bigint NOT NULL
);

ALTER TABLE ONLY public.entitlement_usage_ledgers ADD CONSTRAINT entitlement_usage_ledgers_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.entitlement_usage_ledgers ADD CONSTRAINT uq_entitlement_usage_request UNIQUE (user_entitlement_id, request_id);
CREATE INDEX IF NOT EXISTS idx_entitlement_usage_user_date ON public.entitlement_usage_ledgers USING btree (user_id, usage_date);
CREATE INDEX IF NOT EXISTS idx_entitlement_usage_entitlement_date ON public.entitlement_usage_ledgers USING btree (user_entitlement_id, usage_date);

CREATE TABLE IF NOT EXISTS public.refund_requests (
    id character varying(64) NOT NULL,
    refund_no character varying(128) NOT NULL,
    wallet_id character varying(64) NOT NULL,
    user_id character varying(64),
    payment_order_id character varying(64),
    source_type character varying(64) NOT NULL,
    source_id character varying(128),
    refund_mode character varying(64) NOT NULL,
    amount_usd double precision NOT NULL,
    status character varying(64) DEFAULT 'pending_approval' NOT NULL,
    reason text,
    requested_by character varying(64),
    approved_by character varying(64),
    processed_by character varying(64),
    gateway_refund_id character varying(128),
    payout_method character varying(64),
    payout_reference character varying(255),
    payout_proof jsonb,
    failure_reason text,
    idempotency_key character varying(128),
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    processed_at bigint,
    completed_at bigint
);

ALTER TABLE ONLY public.refund_requests ADD CONSTRAINT refund_requests_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.refund_requests ADD CONSTRAINT uq_refund_requests_refund_no UNIQUE (refund_no);
ALTER TABLE ONLY public.refund_requests ADD CONSTRAINT uq_refund_requests_idempotency_key UNIQUE (idempotency_key);
CREATE INDEX IF NOT EXISTS idx_refund_wallet_created ON public.refund_requests USING btree (wallet_id, created_at);
CREATE INDEX IF NOT EXISTS idx_refund_user_created ON public.refund_requests USING btree (user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_refund_status ON public.refund_requests USING btree (status);
CREATE INDEX IF NOT EXISTS ix_refund_requests_payment_order_id ON public.refund_requests USING btree (payment_order_id);
CREATE INDEX IF NOT EXISTS ix_refund_requests_requested_by ON public.refund_requests USING btree (requested_by);
CREATE INDEX IF NOT EXISTS ix_refund_requests_approved_by ON public.refund_requests USING btree (approved_by);
CREATE INDEX IF NOT EXISTS ix_refund_requests_processed_by ON public.refund_requests USING btree (processed_by);

CREATE TABLE IF NOT EXISTS public.redeem_code_batches (
    id character varying(64) NOT NULL,
    name character varying(255) NOT NULL,
    amount_usd double precision NOT NULL,
    currency character varying(16) DEFAULT 'USD' NOT NULL,
    balance_bucket character varying(64) DEFAULT 'gift' NOT NULL,
    total_count integer NOT NULL,
    status character varying(64) DEFAULT 'active' NOT NULL,
    description text,
    created_by character varying(64),
    expires_at bigint,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.redeem_code_batches ADD CONSTRAINT redeem_code_batches_pkey PRIMARY KEY (id);
CREATE INDEX IF NOT EXISTS idx_redeem_code_batches_status ON public.redeem_code_batches USING btree (status, created_at);

CREATE TABLE IF NOT EXISTS public.redeem_codes (
    id character varying(64) NOT NULL,
    batch_id character varying(64) NOT NULL,
    code_hash character varying(128) NOT NULL,
    code_prefix character varying(16) NOT NULL,
    code_suffix character varying(16) NOT NULL,
    status character varying(64) DEFAULT 'active' NOT NULL,
    redeemed_by_user_id character varying(64),
    redeemed_wallet_id character varying(64),
    redeemed_payment_order_id character varying(64),
    redeemed_at bigint,
    disabled_by character varying(64),
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

ALTER TABLE ONLY public.redeem_codes ADD CONSTRAINT redeem_codes_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.redeem_codes ADD CONSTRAINT uq_redeem_codes_code_hash UNIQUE (code_hash);
CREATE INDEX IF NOT EXISTS idx_redeem_codes_batch_created ON public.redeem_codes USING btree (batch_id, created_at);
CREATE INDEX IF NOT EXISTS idx_redeem_codes_status ON public.redeem_codes USING btree (status, updated_at);
CREATE INDEX IF NOT EXISTS idx_redeem_codes_redeemed_user ON public.redeem_codes USING btree (redeemed_by_user_id, redeemed_at);
CREATE INDEX IF NOT EXISTS idx_redeem_codes_redeemed_order ON public.redeem_codes USING btree (redeemed_payment_order_id);

