-- V1__init_schema.sql
-- 初始表结构

-- postgres 扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- =====================================================
-- 用户相关表
-- =====================================================

-- 用户表
CREATE TABLE public.users (
    id bigint NOT NULL,
    mobile character varying(11) NOT NULL,
    password_hash character varying(255) NOT NULL,
    access_token text,
    token_expires_at bigint,
    avatar_url character varying(500),
    global_wallet_address character varying(100),
    is_active boolean DEFAULT true NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    deleted_at bigint
);

CREATE SEQUENCE public.users_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass);
ALTER TABLE ONLY public.users ADD CONSTRAINT users_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_users_mobile ON public.users USING btree (mobile);
CREATE INDEX idx_users_deleted_at ON public.users USING btree (deleted_at);
ALTER TABLE ONLY public.users ADD CONSTRAINT fk_users FOREIGN KEY (owner_uid) REFERENCES public.users(id) ON DELETE CASCADE;

-- 明星信息表
CREATE TABLE public.stars (
    star_id bigint NOT NULL,
    name character varying(100) NOT NULL,
    tag character varying(100),
    name_en character varying(100),
    pic_url character varying(500),
    description text,
    identity_id character varying(50) NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.stars_star_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.stars ALTER COLUMN star_id SET DEFAULT nextval('public.stars_star_id_seq'::regclass);
ALTER TABLE ONLY public.stars ADD CONSTRAINT stars_pkey PRIMARY KEY (star_id);
CREATE UNIQUE INDEX uk_stars_identity_id ON public.stars USING btree (identity_id);

-- 粉丝档案表
CREATE TABLE public.fan_profiles (
    id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    nickname character varying(50) NOT NULL,
    level integer DEFAULT 1 NOT NULL,
    times integer DEFAULT 1 NOT NULL,
    social integer DEFAULT 0 NOT NULL,
    experience bigint DEFAULT 0 NOT NULL,
    coin_balance bigint DEFAULT 0 NOT NULL,
    crystal_balance bigint DEFAULT 0 NOT NULL,
    tags jsonb,
    starbook_limit integer DEFAULT 3 NOT NULL,
    slot_limit integer DEFAULT 3 NOT NULL,
    assets_count integer DEFAULT 0 NOT NULL,
    chain_address character varying(100),
    is_active boolean DEFAULT true NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    avatar_url character varying(500)
);

CREATE SEQUENCE public.fan_profiles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.fan_profiles ALTER COLUMN id SET DEFAULT nextval('public.fan_profiles_id_seq'::regclass);
ALTER TABLE ONLY public.fan_profiles ADD CONSTRAINT fan_profiles_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_fan_profiles_user_star ON public.fan_profiles USING btree (user_id, star_id);
CREATE UNIQUE INDEX uk_fan_profiles_star_nickname ON public.fan_profiles USING btree (star_id, nickname);
CREATE INDEX idx_fan_profiles_user_id ON public.fan_profiles USING btree (user_id);
CREATE INDEX idx_fan_profiles_star_id ON public.fan_profiles USING btree (star_id);
ALTER TABLE ONLY public.fan_profiles ADD CONSTRAINT fk_fan_profiles_user FOREIGN KEY (user_id) REFERENCES public.users(id);
ALTER TABLE ONLY public.fan_profiles ADD CONSTRAINT fk_fan_profiles_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id);

-- =====================================================
-- 藏品相关表
-- =====================================================

-- 资产表（藏品）
CREATE TABLE public.assets (
    id bigint NOT NULL,
    owner_uid bigint NOT NULL,
    star_id bigint NOT NULL,
    name character varying(100) NOT NULL,
    cover_url character varying(500) NOT NULL,
    material_url character varying(500),
    description text,
    rarity integer,
    tags jsonb,
    visibility character varying(20) DEFAULT 'private'::character varying,
    status integer DEFAULT 0 NOT NULL,
    tx_hash character varying(100),
    block_number bigint,
    like_count integer DEFAULT 0 NOT NULL,
    is_original boolean DEFAULT false NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    minted_at bigint,
    deleted_at bigint,
    is_active boolean DEFAULT true NOT NULL,
    info text
);

CREATE SEQUENCE public.assets_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.assets ALTER COLUMN id SET DEFAULT nextval('public.assets_id_seq'::regclass);
ALTER TABLE ONLY public.assets ADD CONSTRAINT assets_pkey PRIMARY KEY (id);
CREATE INDEX idx_assets_created_at ON public.assets USING btree (created_at DESC);
CREATE INDEX idx_assets_deleted_at ON public.assets USING btree (deleted_at);
CREATE INDEX idx_assets_owner_star ON public.assets USING btree (owner_uid, star_id);
CREATE INDEX idx_assets_star_active ON public.assets USING btree (star_id, is_active);
CREATE INDEX idx_assets_status ON public.assets USING btree (status);
CREATE INDEX idx_assets_tx_hash ON public.assets USING btree (tx_hash);
ALTER TABLE ONLY public.assets ADD CONSTRAINT fk_assets_owner FOREIGN KEY (owner_uid) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.assets ADD CONSTRAINT fk_assets_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;

-- 资产注册表（星册体系）
CREATE TABLE public.asset_registry (
    id bigint NOT NULL,
    asset_id bigint NOT NULL,
    asset_type character varying(20) NOT NULL,
    owner_uid bigint NOT NULL,
    star_id bigint NOT NULL,
    grade integer,
    collection_category character varying(50),
    activity_id bigint,
    activity_type character varying(50),
    status integer DEFAULT 0 NOT NULL,
    like_count integer DEFAULT 0 NOT NULL,
    display_status integer DEFAULT 0 NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.asset_registry_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.asset_registry ALTER COLUMN id SET DEFAULT nextval('public.asset_registry_id_seq'::regclass);
ALTER TABLE ONLY public.asset_registry ADD CONSTRAINT asset_registry_pkey PRIMARY KEY (id);
CREATE INDEX idx_registry_owner_star ON public.asset_registry USING btree (owner_uid, star_id);
ALTER TABLE ONLY public.asset_registry ADD CONSTRAINT fk_registry_asset FOREIGN KEY (asset_id) REFERENCES public.assets(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.asset_registry ADD CONSTRAINT fk_registry_owner FOREIGN KEY (owner_uid) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.asset_registry ADD CONSTRAINT fk_registry_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;

-- 点赞记录表
CREATE TABLE public.asset_likes (
    id bigint NOT NULL,
    asset_id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    created_at bigint NOT NULL
);

CREATE SEQUENCE public.asset_likes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.asset_likes ALTER COLUMN id SET DEFAULT nextval('public.asset_likes_id_seq'::regclass);
ALTER TABLE ONLY public.asset_likes ADD CONSTRAINT asset_likes_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_asset_likes_user_asset ON public.asset_likes USING btree (user_id, asset_id);
CREATE INDEX idx_asset_likes_asset ON public.asset_likes USING btree (asset_id);
CREATE INDEX idx_asset_likes_user_star ON public.asset_likes USING btree (user_id, star_id);
ALTER TABLE ONLY public.asset_likes ADD CONSTRAINT fk_asset_likes_asset FOREIGN KEY (asset_id) REFERENCES public.assets(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.asset_likes ADD CONSTRAINT fk_asset_likes_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;
ALTER TABLE ONLY public.asset_likes ADD CONSTRAINT fk_asset_likes_user FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;

-- 铸造订单表
CREATE TABLE public.mint_orders (
    order_id character varying(100) NOT NULL,
    user_id bigint NOT NULL,
    asset_id bigint,
    star_id bigint NOT NULL,
    status character varying(20) DEFAULT 'PENDING'::character varying NOT NULL,
    cost_crystal bigint DEFAULT 0,
    error_message text,
    retry_count integer DEFAULT 0,
    material_url character varying(500),
    name character varying(100),
    description text,
    material_type character varying(50),
    event character varying(100),
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    minted_at bigint,
    info text
);

ALTER TABLE ONLY public.mint_orders ADD CONSTRAINT mint_orders_pkey PRIMARY KEY (order_id);
CREATE INDEX idx_mint_orders_asset ON public.mint_orders USING btree (asset_id);
CREATE INDEX idx_mint_orders_created_at ON public.mint_orders USING btree (created_at DESC);
CREATE INDEX idx_mint_orders_status ON public.mint_orders USING btree (status);
CREATE INDEX idx_mint_orders_user_star ON public.mint_orders USING btree (user_id, star_id);
ALTER TABLE ONLY public.mint_orders ADD CONSTRAINT fk_mint_orders_asset FOREIGN KEY (asset_id) REFERENCES public.assets(id) ON DELETE SET NULL;
ALTER TABLE ONLY public.mint_orders ADD CONSTRAINT fk_mint_orders_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;
ALTER TABLE ONLY public.mint_orders ADD CONSTRAINT fk_mint_orders_user FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;

-- =====================================================
-- 展馆相关表
-- =====================================================

-- 展位表
CREATE TABLE public.booth_slots (
    slot_id bigint NOT NULL,
    host_profile_id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    slot_index bigint NOT NULL,
    visibility character varying(20) DEFAULT 'public'::character varying,
    is_enabled boolean DEFAULT false,
    unlock_type character varying(20),
    unlock_value bigint,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.booth_slots_slot_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.booth_slots ALTER COLUMN slot_id SET DEFAULT nextval('public.booth_slots_slot_id_seq'::regclass);
ALTER TABLE ONLY public.booth_slots ADD CONSTRAINT booth_slots_pkey PRIMARY KEY (slot_id);
CREATE UNIQUE INDEX idx_host_slot ON public.booth_slots USING btree (host_profile_id, slot_index);
CREATE INDEX idx_star_enabled ON public.booth_slots USING btree (star_id);
CREATE INDEX idx_user_star ON public.booth_slots USING btree (user_id, star_id);
ALTER TABLE ONLY public.booth_slots ADD CONSTRAINT fk_booth_slots_profile FOREIGN KEY (host_profile_id) REFERENCES public.fan_profiles(id) ON DELETE CASCADE;

-- 展品展示表
CREATE TABLE public.exhibitions (
    id bigint NOT NULL,
    asset_id bigint NOT NULL,
    slot_id bigint NOT NULL,
    host_profile_id bigint NOT NULL,
    occupier_uid bigint NOT NULL,
    occupier_star_id bigint NOT NULL,
    start_time bigint NOT NULL,
    expire_at bigint NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    deleted_at bigint
);

CREATE SEQUENCE public.exhibitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.exhibitions ALTER COLUMN id SET DEFAULT nextval('public.exhibitions_id_seq'::regclass);
ALTER TABLE ONLY public.exhibitions ADD CONSTRAINT exhibitions_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_asset ON public.exhibitions USING btree (asset_id);
CREATE INDEX idx_expire ON public.exhibitions USING btree (expire_at);
CREATE INDEX idx_host ON public.exhibitions USING btree (host_profile_id);
CREATE INDEX idx_occupier ON public.exhibitions USING btree (occupier_uid, occupier_star_id);
CREATE INDEX idx_slot ON public.exhibitions USING btree (slot_id);
ALTER TABLE ONLY public.exhibitions ADD CONSTRAINT fk_exhibitions_asset FOREIGN KEY (asset_id) REFERENCES public.assets(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.exhibitions ADD CONSTRAINT fk_exhibitions_slot FOREIGN KEY (slot_id) REFERENCES public.booth_slots(slot_id) ON DELETE CASCADE;

-- 展览收入记录表
CREATE TABLE public.exhibition_revenue_records (
    id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    exhibition_id bigint NOT NULL,
    asset_id bigint NOT NULL,
    slot_id bigint NOT NULL,
    slot_owner_uid bigint NOT NULL,
    slot_type character varying(20) NOT NULL,
    crystal_amount bigint NOT NULL,
    cycle_start_time bigint NOT NULL,
    cycle_end_time bigint NOT NULL,
    status character varying(20) DEFAULT 'claimable'::character varying NOT NULL,
    claimed_at bigint,
    created_at bigint NOT NULL
);

CREATE SEQUENCE public.exhibition_revenue_records_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.exhibition_revenue_records ALTER COLUMN id SET DEFAULT nextval('public.exhibition_revenue_records_id_seq'::regclass);
ALTER TABLE ONLY public.exhibition_revenue_records ADD CONSTRAINT exhibition_revenue_records_pkey PRIMARY KEY (id);
CREATE INDEX idx_user_revenue ON public.exhibition_revenue_records USING btree (user_id, star_id);

-- =====================================================
-- 社交相关表
-- =====================================================

-- 好友请求表
CREATE TABLE public.friend_requests (
    id bigint NOT NULL,
    from_user_id bigint NOT NULL,
    to_user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    message character varying(200),
    status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    expires_at bigint,
    processed_at bigint
);

CREATE SEQUENCE public.friend_requests_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.friend_requests ALTER COLUMN id SET DEFAULT nextval('public.friend_requests_id_seq'::regclass);
ALTER TABLE ONLY public.friend_requests ADD CONSTRAINT friend_requests_pkey PRIMARY KEY (id);
CREATE INDEX idx_friend_requests_expires ON public.friend_requests USING btree (expires_at);
CREATE INDEX idx_friend_requests_from_status ON public.friend_requests USING btree (from_user_id, status, created_at DESC);
CREATE INDEX idx_friend_requests_star ON public.friend_requests USING btree (star_id);
CREATE INDEX idx_friend_requests_to_status ON public.friend_requests USING btree (to_user_id, status, created_at DESC);
CREATE INDEX idx_friend_requests_users_star ON public.friend_requests USING btree (from_user_id, to_user_id, star_id, created_at DESC);
ALTER TABLE ONLY public.friend_requests ADD CONSTRAINT fk_friend_requests_from_user FOREIGN KEY (from_user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.friend_requests ADD CONSTRAINT fk_friend_requests_to_user FOREIGN KEY (to_user_id) REFERENCES public.users(id) ON DELETE CASCADE;

-- 好友关系表
CREATE TABLE public.friendships (
    id bigint NOT NULL,
    user_id bigint NOT NULL,
    friend_id bigint NOT NULL,
    star_id bigint NOT NULL,
    status character varying(20) DEFAULT 'accepted'::character varying NOT NULL,
    remark character varying(50),
    intimacy integer DEFAULT 0 NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.friendships_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.friendships ALTER COLUMN id SET DEFAULT nextval('public.friendships_id_seq'::regclass);
ALTER TABLE ONLY public.friendships ADD CONSTRAINT friendships_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_friendships_user_friend_star ON public.friendships USING btree (user_id, friend_id, star_id);
CREATE INDEX idx_friendships_friend_star ON public.friendships USING btree (friend_id);
CREATE INDEX idx_friendships_list_query ON public.friendships USING btree (user_id, friend_id, star_id, status, remark, created_at);
CREATE INDEX idx_friendships_user_star_created ON public.friendships USING btree (user_id, star_id, created_at DESC);
CREATE INDEX idx_friendships_user_star_status ON public.friendships USING btree (user_id, star_id, status);
ALTER TABLE ONLY public.friendships ADD CONSTRAINT fk_friendships_friend FOREIGN KEY (friend_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.friendships ADD CONSTRAINT fk_friendships_user FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;

-- =====================================================
-- 任务相关表
-- =====================================================

-- 任务定义表
CREATE TABLE public.task_definitions (
    id bigint NOT NULL,
    task_key character varying(50) NOT NULL,
    task_type character varying(20) NOT NULL,
    name character varying(100) NOT NULL,
    description text,
    crystal_reward bigint DEFAULT 0 NOT NULL,
    exp_reward bigint DEFAULT 0 NOT NULL,
    sort_order integer DEFAULT 0 NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.task_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.task_definitions ALTER COLUMN id SET DEFAULT nextval('public.task_definitions_id_seq'::regclass);
ALTER TABLE ONLY public.task_definitions ADD CONSTRAINT task_definitions_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX idx_task_definitions_task_key ON public.task_definitions USING btree (task_key);

-- 用户任务进度表
CREATE TABLE public.user_task_progress (
    id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    task_key character varying(50) NOT NULL,
    status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
    completed_at bigint,
    claimed_at bigint,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.user_task_progress_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.user_task_progress ALTER COLUMN id SET DEFAULT nextval('public.user_task_progress_id_seq'::regclass);
ALTER TABLE ONLY public.user_task_progress ADD CONSTRAINT user_task_progress_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_user_task ON public.user_task_progress USING btree (user_id, star_id, task_key);

-- 用户引导状态表
CREATE TABLE public.user_onboarding_status (
    id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    is_onboarding_completed boolean DEFAULT false NOT NULL,
    is_onboarding_claimed boolean DEFAULT false NOT NULL,
    has_friend_display_bonus boolean DEFAULT false NOT NULL,
    onboarding_completed_at bigint,
    onboarding_claimed_at bigint,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.user_onboarding_status_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.user_onboarding_status ALTER COLUMN id SET DEFAULT nextval('public.user_onboarding_status_id_seq'::regclass);
ALTER TABLE ONLY public.user_onboarding_status ADD CONSTRAINT user_onboarding_status_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_user_star_onboarding ON public.user_onboarding_status USING btree (user_id, star_id);

-- =====================================================
-- 活动相关表
-- =====================================================

-- 活动表
CREATE TABLE public.activities (
    id bigint NOT NULL,
    activity_type character varying(50) NOT NULL,
    title character varying(100) NOT NULL,
    description text,
    star_id bigint NOT NULL,
    start_time bigint NOT NULL,
    end_time bigint NOT NULL,
    target_progress bigint DEFAULT 1000 NOT NULL,
    current_progress bigint DEFAULT 0 NOT NULL,
    status character varying(20) DEFAULT 'pending'::character varying,
    stage_configs jsonb,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL,
    theme character varying(100),
    overall_end_time bigint DEFAULT 0
);

CREATE SEQUENCE public.activities_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.activities ALTER COLUMN id SET DEFAULT nextval('public.activities_id_seq'::regclass);
ALTER TABLE ONLY public.activities ADD CONSTRAINT activities_pkey PRIMARY KEY (id);
CREATE INDEX idx_activities_star_id ON public.activities USING btree (star_id);
CREATE INDEX idx_activities_start_end ON public.activities USING btree (start_time, end_time);
CREATE INDEX idx_activities_status ON public.activities USING btree (status);

-- 活动道具表
CREATE TABLE public.activity_items (
    id bigint NOT NULL,
    activity_id bigint NOT NULL,
    item_type character varying(50) NOT NULL,
    item_name character varying(50) NOT NULL,
    icon_url character varying(500),
    crystal_cost bigint NOT NULL,
    contribution_points bigint NOT NULL,
    sort_order integer DEFAULT 0 NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.activity_items_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.activity_items ALTER COLUMN id SET DEFAULT nextval('public.activity_items_id_seq'::regclass);
ALTER TABLE ONLY public.activity_items ADD CONSTRAINT activity_items_pkey PRIMARY KEY (id);
CREATE INDEX idx_activity_items_activity ON public.activity_items USING btree (activity_id);
CREATE INDEX idx_activity_items_type ON public.activity_items USING btree (item_type);
ALTER TABLE ONLY public.activity_items ADD CONSTRAINT fk_activity_items_activity FOREIGN KEY (activity_id) REFERENCES public.activities(id) ON DELETE CASCADE;

-- 活动贡献记录表
CREATE TABLE public.activity_contributions (
    id bigint NOT NULL,
    activity_id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    item_id bigint NOT NULL,
    item_type character varying(50) NOT NULL,
    quantity integer DEFAULT 1 NOT NULL,
    crystal_spent bigint NOT NULL,
    contribution_points bigint NOT NULL,
    created_at bigint NOT NULL
);

CREATE SEQUENCE public.activity_contributions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.activity_contributions ALTER COLUMN id SET DEFAULT nextval('public.activity_contributions_id_seq'::regclass);
ALTER TABLE ONLY public.activity_contributions ADD CONSTRAINT activity_contributions_pkey PRIMARY KEY (id);
CREATE INDEX idx_activity_contributions_activity ON public.activity_contributions USING btree (activity_id);
CREATE INDEX idx_activity_contributions_created ON public.activity_contributions USING btree (created_at DESC);
CREATE INDEX idx_activity_contributions_user_star ON public.activity_contributions USING btree (user_id, star_id);
ALTER TABLE ONLY public.activity_contributions ADD CONSTRAINT fk_activity_contributions_activity FOREIGN KEY (activity_id) REFERENCES public.activities(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.activity_contributions ADD CONSTRAINT fk_activity_contributions_item FOREIGN KEY (item_id) REFERENCES public.activity_items(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.activity_contributions ADD CONSTRAINT fk_activity_contributions_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;
ALTER TABLE ONLY public.activity_contributions ADD CONSTRAINT fk_activity_contributions_user FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;

-- 用户活动统计表
CREATE TABLE public.activity_user_stats (
    id bigint NOT NULL,
    activity_id bigint NOT NULL,
    user_id bigint NOT NULL,
    star_id bigint NOT NULL,
    total_contribution bigint DEFAULT 0 NOT NULL,
    total_crystal_spent bigint DEFAULT 0 NOT NULL,
    total_items integer DEFAULT 0 NOT NULL,
    last_contribute_at bigint NOT NULL,
    created_at bigint NOT NULL,
    updated_at bigint NOT NULL
);

CREATE SEQUENCE public.activity_user_stats_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
ALTER TABLE ONLY public.activity_user_stats ALTER COLUMN id SET DEFAULT nextval('public.activity_user_stats_id_seq'::regclass);
ALTER TABLE ONLY public.activity_user_stats ADD CONSTRAINT activity_user_stats_pkey PRIMARY KEY (id);
CREATE UNIQUE INDEX uk_activity_user_star ON public.activity_user_stats UNIQUE (activity_id, user_id, star_id);
CREATE INDEX idx_activity_user_stats_activity ON public.activity_user_stats USING btree (activity_id);
CREATE INDEX idx_activity_user_stats_contribution ON public.activity_user_stats USING btree (activity_id, total_contribution DESC);
CREATE INDEX idx_activity_user_stats_user_star ON public.activity_user_stats USING btree (user_id, star_id);
ALTER TABLE ONLY public.activity_user_stats ADD CONSTRAINT fk_activity_user_stats_activity FOREIGN KEY (activity_id) REFERENCES public.activities(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.activity_user_stats ADD CONSTRAINT fk_activity_user_stats_star FOREIGN KEY (star_id) REFERENCES public.stars(star_id) ON DELETE CASCADE;
ALTER TABLE ONLY public.activity_user_stats ADD CONSTRAINT fk_activity_user_stats_user FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;