-- QuyUn v2 数据库 DDL（PostgreSQL）
-- 说明：本文件用于规格参考，需与 backend/database/migrations 保持一致。

BEGIN;

-- Users
CREATE TABLE IF NOT EXISTS users(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    username varchar(255) NOT NULL UNIQUE, -- 用户名：唯一，用于登录
    password varchar(255) NOT NULL, -- 密码：加密存储
    roles text[] DEFAULT '{user}', -- 角色：用户角色列表，如 {user, super_admin}
    status varchar(50) DEFAULT 'active', -- 状态：active/inactive/banned
    metas jsonb DEFAULT '{}', -- 元数据：额外扩展信息
    balance bigint DEFAULT 0, -- 全局可用余额：分/最小货币单位
    balance_frozen bigint DEFAULT 0, -- 全局冻结余额：分/最小货币单位
    verified_at timestamp with time zone, -- 实名认证时间
    nickname varchar(255) DEFAULT '', -- 昵称：用户显示名称
    avatar varchar(512) DEFAULT '', -- 头像：URL地址
    gender varchar(32) DEFAULT 'secret', -- 性别：male/female/secret
    bio varchar(512) DEFAULT '', -- 简介：用户个人简介
    birthday date, -- 生日：YYYY-MM-DD
    location jsonb DEFAULT '{}', -- 位置：省市区信息 {province: "...", city: "..."}
    points bigint DEFAULT 0, -- 积分：用户积分
    phone varchar(32) DEFAULT '', -- 手机号：用于登录/验证
    is_real_name_verified boolean DEFAULT FALSE, -- 是否实名认证：true/false
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间：默认 now()
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间：默认 now()
    deleted_at timestamp with time zone -- 删除时间：软删除
);

-- Tenants
CREATE TABLE IF NOT EXISTS tenants(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    user_id bigint NOT NULL, -- 创建者ID：关联 users.id
    code varchar(64) NOT NULL UNIQUE, -- 租户代码：唯一标识，用于 URL 等
    uuid uuid NOT NULL, -- UUID：全局唯一标识
    name varchar(128) NOT NULL, -- 租户名称
    status varchar(64) NOT NULL, -- 状态：pending_verify/verified/banned
    config jsonb DEFAULT '{}', -- 配置：租户配置信息
    expired_at timestamp with time zone, -- 过期时间：租户有效期
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间：默认 now()
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间：默认 now()
);

CREATE INDEX IF NOT EXISTS idx_tenants_user_id ON tenants(user_id);

-- TenantUsers
CREATE TABLE IF NOT EXISTS tenant_users(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID：关联 tenants.id
    user_id bigint NOT NULL, -- 用户ID：关联 users.id
    role text[] DEFAULT '{member}', -- 角色：member/tenant_admin
    status varchar(50) DEFAULT 'verified', -- 状态：pending_verify/verified/banned
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间：默认 now()
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间：默认 now()
    UNIQUE (tenant_id, user_id)
);

-- Contents
CREATE TABLE IF NOT EXISTS contents(
    id bigserial PRIMARY KEY, -- 主键ID：自增；用于内容引用
    tenant_id bigint NOT NULL, -- 租户ID：多租户隔离关键字段
    user_id bigint NOT NULL, -- 用户ID：内容创建者/发布者
    title varchar(255) NOT NULL, -- 标题：用于列表展示与搜索
    description text NOT NULL, -- 描述：用于详情页展示
    status varchar(32) DEFAULT 'draft', -- 状态：draft/reviewing/published/unpublished/blocked
    visibility varchar(32) DEFAULT 'tenant_only', -- 可见性：public/tenant_only/private
    preview_seconds int DEFAULT 60, -- 试看秒数：默认 60
    preview_downloadable boolean DEFAULT FALSE, -- 试看是否允许下载
    published_at timestamp with time zone, -- 发布时间
    summary varchar(256) DEFAULT '', -- 简介：用于列表/卡片展示
    tags jsonb DEFAULT '[]', -- 标签：JSON 数组
    body text DEFAULT '', -- 内容主体：文章内容/详细介绍
    genre varchar(64) DEFAULT '', -- 类型/流派
    views int DEFAULT 0, -- 浏览量
    likes int DEFAULT 0, -- 点赞数
    key varchar(32) DEFAULT '', -- 音乐调性/主音
    is_pinned boolean DEFAULT FALSE, -- 是否置顶
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    deleted_at timestamp with time zone -- 软删除时间
);

CREATE INDEX IF NOT EXISTS idx_contents_tenant_id ON contents(tenant_id);

-- MediaAssets
CREATE TABLE IF NOT EXISTS media_assets(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID：多租户隔离关键字段
    user_id bigint NOT NULL, -- 用户ID：资源上传者
    type varchar(32) DEFAULT 'video', -- 资源类型：video/audio/image
    status varchar(32) DEFAULT 'uploaded', -- 处理状态：uploaded/processing/ready/failed/deleted
    provider varchar(64) NOT NULL, -- 存储提供方：s3/minio/oss/local
    bucket varchar(128) NOT NULL, -- 存储桶
    object_key varchar(512) NOT NULL, -- 对象键
    meta jsonb DEFAULT '{}', -- 元数据：JSON
    variant varchar(32) DEFAULT 'main', -- 产物类型：main/preview
    source_asset_id bigint DEFAULT 0, -- 派生来源资源ID
    hash varchar(64) DEFAULT '', -- 文件 MD5 哈希
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    deleted_at timestamp with time zone -- 软删除时间
);

CREATE INDEX IF NOT EXISTS idx_media_assets_hash ON media_assets (hash);

-- ContentAssets
CREATE TABLE IF NOT EXISTS content_assets(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    content_id bigint NOT NULL, -- 内容ID
    asset_id bigint NOT NULL, -- 资源ID
    role varchar(32) DEFAULT 'main', -- 资源角色：main/cover/preview
    sort int DEFAULT 0, -- 排序
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

-- ContentPrices
CREATE TABLE IF NOT EXISTS content_prices(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    content_id bigint NOT NULL, -- 内容ID
    currency varchar(16) DEFAULT 'CNY', -- 币种
    price_amount bigint NOT NULL, -- 基础价格：分
    discount_type varchar(16) DEFAULT 'none', -- 折扣类型：none/percent/amount
    discount_value bigint DEFAULT 0, -- 折扣值
    discount_start_at timestamp with time zone, -- 折扣开始时间
    discount_end_at timestamp with time zone, -- 折扣结束时间
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    UNIQUE (tenant_id, content_id)
);

-- ContentAccess
CREATE TABLE IF NOT EXISTS content_access(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    content_id bigint NOT NULL, -- 内容ID
    order_id bigint DEFAULT 0, -- 订单ID
    status varchar(16) DEFAULT 'active', -- 权益状态
    revoked_at timestamp with time zone, -- 撤销时间
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    UNIQUE (tenant_id, user_id, content_id)
);

-- Orders
CREATE TABLE IF NOT EXISTS orders(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    type varchar(32) DEFAULT 'content_purchase', -- 订单类型
    status varchar(32) DEFAULT 'created', -- 订单状态
    currency varchar(16) DEFAULT 'CNY', -- 币种
    amount_original bigint NOT NULL, -- 原价金额
    amount_discount bigint NOT NULL, -- 优惠金额
    amount_paid bigint NOT NULL, -- 实付金额
    snapshot jsonb DEFAULT '{}', -- 订单快照
    idempotency_key varchar(128) NOT NULL, -- 幂等键
    paid_at timestamp with time zone, -- 支付时间
    refunded_at timestamp with time zone, -- 退款时间
    refund_forced boolean DEFAULT FALSE, -- 是否强制退款
    refund_operator_user_id bigint DEFAULT 0, -- 退款操作人
    refund_reason varchar(255) DEFAULT '', -- 退款原因
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    coupon_id bigint DEFAULT 0 -- 关联优惠券ID (0表示未使用)
);

-- OrderItems
CREATE TABLE IF NOT EXISTS order_items(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    order_id bigint NOT NULL, -- 订单ID
    content_id bigint NOT NULL, -- 内容ID
    content_user_id bigint NOT NULL, -- 内容作者用户ID
    amount_paid bigint NOT NULL, -- 该行实付金额
    snapshot jsonb DEFAULT '{}', -- 内容快照
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

-- TenantLedgers
CREATE TABLE IF NOT EXISTS tenant_ledgers(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    order_id bigint DEFAULT 0, -- 关联订单ID
    type varchar(32) NOT NULL, -- 流水类型
    amount bigint NOT NULL, -- 流水金额
    balance_before bigint NOT NULL, -- 变更前可用余额
    balance_after bigint NOT NULL, -- 变更后可用余额
    frozen_before bigint NOT NULL, -- 变更前冻结余额
    frozen_after bigint NOT NULL, -- 变更后冻结余额
    idempotency_key varchar(128) NOT NULL, -- 幂等键
    remark varchar(255) NOT NULL, -- 备注
    operator_user_id bigint DEFAULT 0, -- 操作者用户ID
    biz_ref_type varchar(32) DEFAULT '', -- 业务引用类型
    biz_ref_id bigint DEFAULT 0, -- 业务引用ID
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

-- TenantInvites
CREATE TABLE IF NOT EXISTS tenant_invites(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 创建人用户ID
    code varchar(64) NOT NULL, -- 邀请码
    status varchar(32) DEFAULT 'active', -- 邀请状态
    max_uses int NOT NULL, -- 最大可使用次数
    used_count int DEFAULT 0, -- 已使用次数
    expires_at timestamp with time zone, -- 过期时间
    disabled_at timestamp with time zone, -- 禁用时间
    disabled_operator_user_id bigint DEFAULT 0, -- 禁用操作人用户ID
    remark varchar(255) DEFAULT '', -- 备注
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

-- TenantJoinRequests
CREATE TABLE IF NOT EXISTS tenant_join_requests(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 申请人用户ID
    status varchar(32) DEFAULT 'pending', -- 申请状态
    reason varchar(255) NOT NULL, -- 申请原因
    decided_at timestamp with time zone, -- 处理时间
    decided_operator_user_id bigint DEFAULT 0, -- 处理人用户ID
    decided_reason varchar(255) DEFAULT '', -- 处理说明
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

-- Comments
CREATE TABLE IF NOT EXISTS comments(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    content_id bigint NOT NULL, -- 内容ID
    reply_to bigint DEFAULT 0, -- 回复评论ID：0表示一级评论
    content text NOT NULL, -- 评论内容
    likes int DEFAULT 0, -- 点赞数
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
    deleted_at timestamp with time zone -- 软删除时间
);

CREATE INDEX IF NOT EXISTS idx_comments_content_id ON comments(content_id);
CREATE INDEX IF NOT EXISTS idx_comments_user_id ON comments(user_id);

-- User Content Actions (Like, Favorite)
CREATE TABLE IF NOT EXISTS user_content_actions(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    user_id bigint NOT NULL, -- 用户ID
    content_id bigint NOT NULL, -- 内容ID
    type varchar(32) NOT NULL, -- 类型：like, favorite
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    UNIQUE (user_id, content_id, type)
);

-- User Comment Actions (Like)
CREATE TABLE IF NOT EXISTS user_comment_actions(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    user_id bigint NOT NULL, -- 用户ID
    comment_id bigint NOT NULL, -- 评论ID
    type varchar(32) NOT NULL, -- 类型：like
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    UNIQUE (user_id, comment_id, type)
);

-- Payout Accounts
CREATE TABLE IF NOT EXISTS payout_accounts(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    tenant_id bigint NOT NULL, -- 租户ID
    user_id bigint NOT NULL, -- 用户ID
    type varchar(32) NOT NULL, -- 类型：bank, alipay
    name varchar(128) NOT NULL, -- 账户名称/开户行
    account varchar(128) NOT NULL, -- 账号
    realname varchar(128) NOT NULL, -- 真实姓名
    created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
    updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
);

CREATE INDEX IF NOT EXISTS idx_payout_accounts_tenant_id ON payout_accounts(tenant_id);

-- Notifications
CREATE TABLE IF NOT EXISTS notifications(
    id bigserial PRIMARY KEY, -- 主键ID：自增
    user_id bigint NOT NULL, -- 接收用户ID
    tenant_id bigint DEFAULT 0, -- 来源租户ID
    type varchar(32) NOT NULL, -- 类型：system, order, audit, interaction
    title varchar(255) NOT NULL, -- 标题
    content text NOT NULL, -- 内容
    is_read boolean DEFAULT FALSE, -- 是否已读
    created_at timestamp with time zone DEFAULT NOW() -- 创建时间
);

CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);

-- Coupons
CREATE TABLE IF NOT EXISTS coupons(
    id bigserial PRIMARY KEY, -- 主键ID
    tenant_id bigint NOT NULL DEFAULT 0, -- 租户ID
    title varchar(255) NOT NULL, -- 优惠券标题
    description text, -- 优惠券描述
    type varchar(32) NOT NULL, -- 优惠券类型: fix_amount/discount
    value bigint NOT NULL, -- 优惠券面值
    min_order_amount bigint NOT NULL DEFAULT 0, -- 最低订单金额门槛
    max_discount bigint, -- 最高抵扣金额
    total_quantity integer NOT NULL DEFAULT 0, -- 发行总量
    used_quantity integer NOT NULL DEFAULT 0, -- 已使用数量
    start_at timestamptz, -- 开始生效时间
    end_at timestamptz, -- 过期失效时间
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_coupons_tenant_id ON coupons(tenant_id);

CREATE TABLE IF NOT EXISTS user_coupons(
    id bigserial PRIMARY KEY,
    user_id bigint NOT NULL, -- 用户ID
    coupon_id bigint NOT NULL, -- 优惠券ID
    order_id bigint, -- 使用该优惠券的订单ID
    status varchar(32) NOT NULL DEFAULT 'unused', -- 状态: unused/used/expired
    used_at timestamptz, -- 使用时间
    created_at timestamptz NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_user_coupons_user_id ON user_coupons(user_id);
CREATE INDEX IF NOT EXISTS idx_user_coupons_coupon_id ON user_coupons(coupon_id);

COMMIT;
