From 6c1bc35bf5e0af8562587848cea2a3af39e1ce4e Mon Sep 17 00:00:00 2001 From: Rogee Date: Fri, 9 Jan 2026 14:15:17 +0800 Subject: [PATCH] chore: add sync init schema migration --- .../20260109061231_sync_init_schema.sql | 9 + .../20260109061311_sync_init_schema.sql | 360 ++++++++++++++++++ 2 files changed, 369 insertions(+) create mode 100644 backend/database/migrations/20260109061231_sync_init_schema.sql create mode 100644 backend/database/migrations/20260109061311_sync_init_schema.sql diff --git a/backend/database/migrations/20260109061231_sync_init_schema.sql b/backend/database/migrations/20260109061231_sync_init_schema.sql new file mode 100644 index 0000000..b9c449e --- /dev/null +++ b/backend/database/migrations/20260109061231_sync_init_schema.sql @@ -0,0 +1,9 @@ +-- +goose Up +-- +goose StatementBegin +SELECT 'up SQL query'; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +SELECT 'down SQL query'; +-- +goose StatementEnd diff --git a/backend/database/migrations/20260109061311_sync_init_schema.sql b/backend/database/migrations/20260109061311_sync_init_schema.sql new file mode 100644 index 0000000..256666d --- /dev/null +++ b/backend/database/migrations/20260109061311_sync_init_schema.sql @@ -0,0 +1,360 @@ +-- +goose Up +-- +goose StatementBegin +-- Users +CREATE TABLE IF NOT EXISTS users( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:用户唯一标识;约束:PK/不可为空 + username varchar(255) NOT NULL UNIQUE, -- 用户名:登录账号;用途:登录/展示;约束:唯一/非空/长度<=255 + password varchar(255) NOT NULL, -- 密码:加密存储;用途:登录校验;约束:非空/不得明文 + roles text[] DEFAULT '{user}', -- 角色:权限集合;用途:鉴权/授权;约束:枚举值数组/默认{user} + status varchar(50) DEFAULT 'active', -- 状态:账号状态;用途:禁用控制;约束:active/inactive/banned/默认active + metas jsonb DEFAULT '{}', -- 元数据:扩展信息;用途:灵活扩展;约束:JSON对象/默认{} + balance bigint DEFAULT 0, -- 余额:全局可用余额;用途:钱包/支付;约束:最小货币单位/默认0 + balance_frozen bigint DEFAULT 0, -- 冻结余额:冻结资金;用途:风控/结算;约束:最小货币单位/默认0 + verified_at timestamp with time zone, -- 实名认证时间:通过时间;用途:风控展示;约束:可空 + nickname varchar(255) DEFAULT '', -- 昵称:展示名称;用途:前台展示;约束:长度<=255/可空 + avatar varchar(512) DEFAULT '', -- 头像:URL地址;用途:展示;约束:长度<=512/可空 + gender varchar(32) DEFAULT 'secret', -- 性别:用户性别;用途:资料展示;约束:male/female/secret/默认secret + bio varchar(512) DEFAULT '', -- 简介:用户简介;用途:个人主页;约束:长度<=512/可空 + birthday date, -- 生日:YYYY-MM-DD;用途:资料展示;约束:可空 + location jsonb DEFAULT '{}', -- 位置:省市信息;用途:资料展示;约束:JSON对象/默认{} + points bigint DEFAULT 0, -- 积分:用户积分;用途:积分体系;约束:>=0/默认0 + phone varchar(32) DEFAULT '', -- 手机号:登录/验证;用途:OTP登录;约束:长度<=32/可空 + is_real_name_verified boolean DEFAULT FALSE, -- 实名认证:是否认证;用途:风控/展示;约束:布尔/默认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:自增;用途:租户唯一标识;约束:PK/不可为空 + user_id bigint NOT NULL, -- 创建者ID:关联users.id;用途:租户归属;约束:非空 + code varchar(64) NOT NULL UNIQUE, -- 租户代码:唯一编码;用途:URL/路由;约束:唯一/非空/长度<=64 + uuid uuid NOT NULL, -- UUID:全局唯一;用途:外部标识;约束:非空 + name varchar(128) NOT NULL, -- 租户名称:展示名;用途:后台展示;约束:非空/长度<=128 + status varchar(64) NOT NULL, -- 状态:租户状态;用途:启停控制;约束:pending_verify/verified/banned + config jsonb DEFAULT '{}', -- 配置:租户配置;用途:功能开关;约束:JSON对象/默认{} + 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:自增;用途:成员关系唯一标识;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:关联tenants.id;用途:多租户隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:关联users.id;用途:成员归属;约束:非空 + role text[] DEFAULT '{member}', -- 角色:成员角色;用途:权限控制;约束:member/tenant_admin/默认member + 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:自增;用途:内容唯一标识;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:内容作者;用途:归属;约束:非空 + title varchar(255) NOT NULL, -- 标题:内容标题;用途:列表展示/搜索;约束:非空/长度<=255 + 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, -- 试看秒数:试看时长;用途:试看控制;约束:>=0/默认60 + preview_downloadable boolean DEFAULT FALSE, -- 试看下载:是否允许下载;用途:权限控制;约束:布尔/默认false + published_at timestamp with time zone, -- 发布时间:发布时刻;用途:排序/展示;约束:可空 + summary varchar(256) DEFAULT '', -- 简介:列表摘要;用途:卡片展示;约束:长度<=256/可空 + tags jsonb DEFAULT '[]', -- 标签:标签列表;用途:筛选;约束:JSON数组/默认[] + body text DEFAULT '', -- 内容正文:图文内容;用途:详情页;约束:可空 + genre varchar(64) DEFAULT '', -- 流派:内容类型;用途:分类筛选;约束:长度<=64/可空 + views int DEFAULT 0, -- 浏览量:浏览计数;用途:热度排序;约束:>=0/默认0 + likes int DEFAULT 0, -- 点赞数:点赞计数;用途:热度排序;约束:>=0/默认0 + key varchar(32) DEFAULT '', -- 调性:音乐调性;用途:展示/筛选;约束:长度<=32/可空 + is_pinned boolean DEFAULT FALSE, -- 置顶:是否置顶;用途:首页推荐;约束:布尔/默认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 -- 删除时间:软删除;用途:逻辑删除;约束:可空 +); + +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:自增;用途:资源唯一标识;约束:PK/不可为空 + 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, -- 存储提供方:存储类型;用途:访问/迁移;约束:非空 + bucket varchar(128) NOT NULL, -- 存储桶:桶名称;用途:定位对象;约束:非空 + object_key varchar(512) NOT NULL, -- 对象Key:对象路径;用途:访问对象;约束:非空/长度<=512 + meta jsonb DEFAULT '{}', -- 元数据:资源信息;用途:文件元数据;约束:JSON对象/默认{} + variant varchar(32) DEFAULT 'main', -- 产物类型:衍生版本;用途:主片/预览;约束:main/preview/默认main + source_asset_id bigint DEFAULT 0, -- 来源资源ID:派生来源;用途:追溯;约束:0表示无 + hash varchar(64) DEFAULT '', -- 文件哈希:用于去重;用途:秒传/去重;约束:长度<=64/可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:记录更新;用途:审计;约束:默认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:自增;用途:内容资源关联;约束:PK/不可为空 + 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, -- 排序:展示排序;用途:前端排序;约束:>=0/默认0 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +-- ContentPrices +CREATE TABLE IF NOT EXISTS content_prices( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:价格记录;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:内容作者;用途:归属;约束:非空 + content_id bigint NOT NULL, -- 内容ID:关联内容;用途:定价归属;约束:非空 + currency varchar(16) DEFAULT 'CNY', -- 币种:货币类型;用途:计价;约束:ISO币种/默认CNY + price_amount bigint NOT NULL, -- 原价金额:最小货币单位;用途:计价;约束:>=0/非空 + discount_type varchar(16) DEFAULT 'none', -- 折扣类型:折扣规则;用途:促销;约束:none/percent/amount + discount_value bigint DEFAULT 0, -- 折扣值:折扣额度;用途:促销;约束:>=0/默认0 + discount_start_at timestamp with time zone, -- 折扣开始:起始时间;用途:促销;约束:可空 + discount_end_at timestamp with time zone, -- 折扣结束:结束时间;用途:促销;约束:可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:记录更新;用途:审计;约束:默认now() + UNIQUE (tenant_id, content_id) -- 约束:同租户同内容仅一条价格记录 +); + +-- ContentAccess +CREATE TABLE IF NOT EXISTS content_access( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:内容权益记录;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:权益持有者;用途:权限判断;约束:非空 + content_id bigint NOT NULL, -- 内容ID:关联内容;用途:权限判断;约束:非空 + order_id bigint DEFAULT 0, -- 订单ID:关联订单;用途:溯源;约束:0表示无 + status varchar(16) DEFAULT 'active', -- 权益状态:使用状态;用途:权限判断;约束:active/revoked + revoked_at timestamp with time zone, -- 撤销时间:撤销时刻;用途:审计;约束:可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:记录更新;用途:审计;约束:默认now() + UNIQUE (tenant_id, user_id, content_id) -- 约束:同用户同内容唯一权益 +); + +-- Orders +CREATE TABLE IF NOT EXISTS orders( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:订单唯一标识;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:下单用户;用途:归属;约束:非空 + type varchar(32) DEFAULT 'content_purchase', -- 订单类型:业务类型;用途:业务分支;约束:content_purchase/recharge + status varchar(32) DEFAULT 'created', -- 订单状态:支付状态;用途:流程控制;约束:created/paid/refunded/closed + currency varchar(16) DEFAULT 'CNY', -- 币种:货币类型;用途:计价;约束:ISO币种/默认CNY + amount_original bigint NOT NULL, -- 原价金额:订单原价;用途:结算;约束:>=0/非空 + amount_discount bigint NOT NULL, -- 优惠金额:优惠合计;用途:结算;约束:>=0/非空 + amount_paid bigint NOT NULL, -- 实付金额:实际支付;用途:结算;约束:>=0/非空 + snapshot jsonb DEFAULT '{}', -- 订单快照:下单快照;用途:审计/对账;约束:JSON对象/默认{} + idempotency_key varchar(128) NOT NULL, -- 幂等键:请求幂等;用途:重复请求保护;约束:非空/长度<=128 + paid_at timestamp with time zone, -- 支付时间:支付成功时间;用途:对账;约束:可空 + refunded_at timestamp with time zone, -- 退款时间:退款时间;用途:对账;约束:可空 + refund_forced boolean DEFAULT FALSE, -- 强制退款:是否强制;用途:风控;约束:布尔/默认false + refund_operator_user_id bigint DEFAULT 0, -- 退款操作人:操作者ID;用途:审计;约束:0表示无 + refund_reason varchar(255) DEFAULT '', -- 退款原因:原因说明;用途:审计;约束:长度<=255/可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:记录更新;用途:审计;约束:默认now() + coupon_id bigint DEFAULT 0 -- 优惠券ID:使用的券;用途:优惠计算;约束:0表示未使用 +); + +-- OrderItems +CREATE TABLE IF NOT EXISTS order_items( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:订单项唯一标识;约束:PK/不可为空 + 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, -- 实付金额:行实付;用途:结算;约束:>=0/非空 + snapshot jsonb DEFAULT '{}', -- 内容快照:下单内容快照;用途:审计;约束:JSON对象/默认{} + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +-- TenantLedgers +CREATE TABLE IF NOT EXISTS tenant_ledgers( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:流水唯一标识;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:租户主或操作者;用途:归属;约束:非空 + order_id bigint DEFAULT 0, -- 订单ID:关联订单;用途:溯源;约束:0表示无 + 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:人工操作人;用途:审计;约束:0表示无 + biz_ref_type varchar(32) DEFAULT '', -- 业务引用类型:外部关联;用途:对账;约束:长度<=32 + biz_ref_id bigint DEFAULT 0, -- 业务引用ID:外部关联;用途:对账;约束:0表示无 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +-- TenantInvites +CREATE TABLE IF NOT EXISTS tenant_invites( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:邀请记录;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:创建人;用途:溯源;约束:非空 + code varchar(64) NOT NULL, -- 邀请码:邀请码;用途:邀请加入;约束:非空/长度<=64 + status varchar(32) DEFAULT 'active', -- 邀请状态:是否可用;用途:控制邀请;约束:active/disabled/expired + max_uses int NOT NULL, -- 最大次数:可用次数;用途:限制;约束:>0/非空 + used_count int DEFAULT 0, -- 已使用:已用次数;用途:限制;约束:>=0/默认0 + expires_at timestamp with time zone, -- 过期时间:失效时间;用途:控制;约束:可空 + disabled_at timestamp with time zone, -- 禁用时间:禁用时刻;用途:审计;约束:可空 + disabled_operator_user_id bigint DEFAULT 0, -- 禁用操作人:操作者;用途:审计;约束:0表示无 + remark varchar(255) DEFAULT '', -- 备注:说明;用途:审计;约束:长度<=255/可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +-- TenantJoinRequests +CREATE TABLE IF NOT EXISTS tenant_join_requests( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:入驻申请;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:申请人;用途:溯源;约束:非空 + status varchar(32) DEFAULT 'pending', -- 申请状态:审核状态;用途:审核流程;约束:pending/approved/rejected + reason varchar(255) NOT NULL, -- 申请原因:申请说明;用途:审核;约束:非空/长度<=255 + decided_at timestamp with time zone, -- 处理时间:审核时间;用途:审计;约束:可空 + decided_operator_user_id bigint DEFAULT 0, -- 处理人ID:操作者;用途:审计;约束:0表示无 + decided_reason varchar(255) DEFAULT '', -- 处理说明:审核意见;用途:审计;约束:长度<=255/可空 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +-- Comments +CREATE TABLE IF NOT EXISTS comments( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:评论唯一标识;约束:PK/不可为空 + 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为一级;用途:楼中楼;约束:0表示无 + content text NOT NULL, -- 评论内容:评论文本;用途:展示;约束:非空 + likes int DEFAULT 0, -- 点赞数:点赞计数;用途:排序;约束:>=0/默认0 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:记录更新;用途:审计;约束:默认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:自增;用途:内容互动;约束:PK/不可为空 + 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(), -- 创建时间:记录创建;用途:审计;约束:默认now() + UNIQUE (user_id, content_id, type) -- 约束:同一用户同类型仅一次 +); + +-- User Comment Actions (Like) +CREATE TABLE IF NOT EXISTS user_comment_actions( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:评论互动;约束:PK/不可为空 + 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(), -- 创建时间:记录创建;用途:审计;约束:默认now() + UNIQUE (user_id, comment_id, type) -- 约束:同一用户同类型仅一次 +); + +-- Payout Accounts +CREATE TABLE IF NOT EXISTS payout_accounts( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:提现账户;约束:PK/不可为空 + tenant_id bigint NOT NULL, -- 租户ID:多租户隔离;用途:数据隔离;约束:非空 + user_id bigint NOT NULL, -- 用户ID:账户持有人;用途:归属;约束:非空 + type varchar(32) NOT NULL, -- 类型:账户类型;用途:打款方式;约束:bank/alipay + name varchar(128) NOT NULL, -- 账户名称:开户行/支付宝名称;用途:打款;约束:非空/长度<=128 + account varchar(128) NOT NULL, -- 账号:银行卡/支付宝账号;用途:打款;约束:非空/长度<=128 + realname varchar(128) NOT NULL, -- 真实姓名:收款人;用途:打款;约束:非空/长度<=128 + created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认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:自增;用途:通知唯一标识;约束:PK/不可为空 + user_id bigint NOT NULL, -- 用户ID:接收者;用途:归属;约束:非空 + tenant_id bigint DEFAULT 0, -- 租户ID:来源租户;用途:来源标识;约束:0表示无 + type varchar(32) NOT NULL, -- 类型:通知类型;用途:分类展示;约束:system/order/audit/interaction + title varchar(255) NOT NULL, -- 标题:通知标题;用途:展示;约束:非空/长度<=255 + content text NOT NULL, -- 内容:通知内容;用途:展示;约束:非空 + is_read boolean DEFAULT FALSE, -- 已读:是否已读;用途:状态管理;约束:布尔/默认false + created_at timestamp with time zone DEFAULT NOW() -- 创建时间:记录创建;用途:审计;约束:默认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:自增;用途:优惠券唯一标识;约束:PK/不可为空 + tenant_id bigint NOT NULL DEFAULT 0, -- 租户ID:适用租户;用途:范围控制;约束:0表示全局 + title varchar(255) NOT NULL, -- 标题:优惠券标题;用途:展示;约束:非空/长度<=255 + description text, -- 描述:优惠券说明;用途:展示;约束:可空 + type varchar(32) NOT NULL, -- 类型:优惠类型;用途:优惠计算;约束:fix_amount/discount + value bigint NOT NULL, -- 面值:优惠金额/折扣;用途:优惠计算;约束:>0 + min_order_amount bigint NOT NULL DEFAULT 0, -- 最低金额:使用门槛;用途:限制;约束:>=0/默认0 + max_discount bigint, -- 最高折扣:上限金额;用途:限制;约束:可空 + total_quantity integer NOT NULL DEFAULT 0, -- 总量:发行数量;用途:发放控制;约束:>=0/默认0 + used_quantity integer NOT NULL DEFAULT 0, -- 已用:已使用数量;用途:核销统计;约束:>=0/默认0 + start_at timestamptz, -- 开始时间:生效时间;用途:有效期控制;约束:可空 + end_at timestamptz, -- 结束时间:失效时间;用途:有效期控制;约束:可空 + created_at timestamptz NOT NULL DEFAULT NOW(), -- 创建时间:记录创建;用途:审计;约束:默认now() + updated_at timestamptz NOT NULL DEFAULT NOW() -- 更新时间:记录更新;用途:审计;约束:默认now() +); + +CREATE INDEX IF NOT EXISTS idx_coupons_tenant_id ON coupons(tenant_id); + +-- UserCoupons +CREATE TABLE IF NOT EXISTS user_coupons( + id bigserial PRIMARY KEY, -- 主键ID:自增;用途:用户券唯一标识;约束:PK/不可为空 + 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() -- 创建时间:记录创建;用途:审计;约束:默认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); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS user_coupons; +DROP TABLE IF EXISTS coupons; +DROP TABLE IF EXISTS notifications; +DROP TABLE IF EXISTS payout_accounts; +DROP TABLE IF EXISTS user_comment_actions; +DROP TABLE IF EXISTS user_content_actions; +DROP TABLE IF EXISTS comments; +DROP TABLE IF EXISTS tenant_join_requests; +DROP TABLE IF EXISTS tenant_invites; +DROP TABLE IF EXISTS tenant_ledgers; +DROP TABLE IF EXISTS order_items; +DROP TABLE IF EXISTS orders; +DROP TABLE IF EXISTS content_access; +DROP TABLE IF EXISTS content_prices; +DROP TABLE IF EXISTS content_assets; +DROP TABLE IF EXISTS media_assets; +DROP TABLE IF EXISTS contents; +DROP TABLE IF EXISTS tenant_users; +DROP TABLE IF EXISTS tenants; +DROP TABLE IF EXISTS users; +-- +goose StatementEnd