Files
feiqiu-ETL/etl_billiards/schema_v2.sql
2025-11-20 01:27:04 +08:00

1105 lines
57 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.
-- -*- coding: utf-8 -*-
-- Feiqiu-ETL schema (JSON-first alignment)
CREATE SCHEMA IF NOT EXISTS billiards;
CREATE SCHEMA IF NOT EXISTS billiards_ods;
CREATE SCHEMA IF NOT EXISTS etl_admin;
COMMENT ON SCHEMA billiards IS '门店业务数据 Schema存放维度/事实层(与 JSON 字段对应)';
COMMENT ON SCHEMA etl_admin IS 'ETL 调度、游标与运行记录 Schema';
-- =========================
-- Billiards ODS tables
-- =========================
CREATE TABLE IF NOT EXISTS billiards_ods.ods_order_settle (
store_id bigint NOT NULL,
order_settle_id bigint NOT NULL,
order_trade_no bigint,
page_no integer,
page_size integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, order_settle_id)
);
COMMENT ON TABLE billiards_ods.ods_order_settle IS '订单/结算 ODS/order/list、ticket 接口原始 JSON';
COMMENT ON COLUMN billiards_ods.ods_order_settle.store_id IS '门店 ID';
COMMENT ON COLUMN billiards_ods.ods_order_settle.order_settle_id IS '结算单 ID (order_settle_id)';
COMMENT ON COLUMN billiards_ods.ods_order_settle.order_trade_no IS '订单交易号 (order_trade_no)';
COMMENT ON COLUMN billiards_ods.ods_order_settle.page_no IS '来源分页序号';
COMMENT ON COLUMN billiards_ods.ods_order_settle.page_size IS '来源分页大小';
COMMENT ON COLUMN billiards_ods.ods_order_settle.source_file IS '离线导出文件名/路径';
COMMENT ON COLUMN billiards_ods.ods_order_settle.fetched_at IS '入 ODS 时间';
COMMENT ON COLUMN billiards_ods.ods_order_settle.payload IS '原始 JSON 负载';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_table_use_detail (
store_id bigint NOT NULL,
ledger_id bigint NOT NULL,
order_trade_no bigint,
order_settle_id bigint,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, ledger_id)
);
COMMENT ON TABLE billiards_ods.ods_table_use_detail IS '台费/开台流水 ODSsiteTableUseDetailsList 等接口)';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_assistant_ledger (
store_id bigint NOT NULL,
ledger_id bigint NOT NULL,
order_trade_no bigint,
order_settle_id bigint,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, ledger_id)
);
COMMENT ON TABLE billiards_ods.ods_assistant_ledger IS '助教流水 ODSorderAssistantDetails 等接口)';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_assistant_abolish (
store_id bigint NOT NULL,
abolish_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, abolish_id)
);
COMMENT ON TABLE billiards_ods.ods_assistant_abolish IS '助教作废记录 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_goods_ledger (
store_id bigint NOT NULL,
order_goods_id bigint NOT NULL,
order_trade_no bigint,
order_settle_id bigint,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, order_goods_id)
);
COMMENT ON TABLE billiards_ods.ods_goods_ledger IS '商品销售流水 ODSorderGoodsLedgers/orderGoodsList';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_payment (
store_id bigint NOT NULL,
pay_id bigint NOT NULL,
relate_type varchar(50),
relate_id bigint,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, pay_id)
);
COMMENT ON TABLE billiards_ods.ods_payment IS '支付流水 ODSpayRecord/payList';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_refund (
store_id bigint NOT NULL,
refund_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, refund_id)
);
COMMENT ON TABLE billiards_ods.ods_refund IS '退款流水 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_coupon_verify (
store_id bigint NOT NULL,
coupon_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, coupon_id)
);
COMMENT ON TABLE billiards_ods.ods_coupon_verify IS '团购/验券流水 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_member (
store_id bigint NOT NULL,
member_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, member_id)
);
COMMENT ON TABLE billiards_ods.ods_member IS '会员档案 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_member_card (
store_id bigint NOT NULL,
card_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, card_id)
);
COMMENT ON TABLE billiards_ods.ods_member_card IS '储值卡/会员卡 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_package_coupon (
store_id bigint NOT NULL,
package_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, package_id)
);
COMMENT ON TABLE billiards_ods.ods_package_coupon IS '团购套餐定义 ODS';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_inventory_stock (
store_id bigint NOT NULL,
site_goods_id bigint NOT NULL,
snapshot_key varchar(100) NOT NULL DEFAULT 'default',
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, site_goods_id, snapshot_key)
);
COMMENT ON TABLE billiards_ods.ods_inventory_stock IS '库存汇总 ODSinventorySummary 等接口)';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_inventory_change (
store_id bigint NOT NULL,
change_id bigint NOT NULL,
page_no integer,
source_file varchar(255),
fetched_at timestamptz NOT NULL DEFAULT now(),
payload jsonb NOT NULL,
PRIMARY KEY (store_id, change_id)
);
COMMENT ON TABLE billiards_ods.ods_inventory_change IS '库存变动记录 ODS';
-- =========================
-- Billiards dimension tables
-- =========================
CREATE TABLE IF NOT EXISTS billiards.dim_store (
store_id bigint PRIMARY KEY,
store_name varchar(200),
tenant_id bigint,
region_code varchar(30),
address varchar(500),
contact_name varchar(100),
contact_phone varchar(30),
created_time timestamptz,
updated_time timestamptz,
remark text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb
);
COMMENT ON TABLE billiards.dim_store IS '门店/场馆维度siteProfile 信息快照)';
COMMENT ON COLUMN billiards.dim_store.store_id IS '门店 ID主键API storeId';
COMMENT ON COLUMN billiards.dim_store.store_name IS '门店名称 (shop_name)';
COMMENT ON COLUMN billiards.dim_store.tenant_id IS '租户 ID (tenant_id)';
COMMENT ON COLUMN billiards.dim_store.region_code IS '区域编码/城市代码 (tenant_site_region_id)';
COMMENT ON COLUMN billiards.dim_store.address IS '完整地址 (full_address/address)';
COMMENT ON COLUMN billiards.dim_store.contact_name IS '联系人(可扩展)';
COMMENT ON COLUMN billiards.dim_store.contact_phone IS '联系电话 (business_tel)';
COMMENT ON COLUMN billiards.dim_store.created_time IS '创建时间';
COMMENT ON COLUMN billiards.dim_store.updated_time IS '更新时间';
COMMENT ON COLUMN billiards.dim_store.remark IS '备注';
COMMENT ON COLUMN billiards.dim_store.raw_data IS '原始 JSON 快照';
CREATE TABLE IF NOT EXISTS billiards.dim_assistant (
store_id bigint NOT NULL,
assistant_id bigint NOT NULL,
assistant_no varchar(64),
nickname varchar(100),
real_name varchar(100),
gender varchar(20),
mobile varchar(30),
level varchar(50),
team_id bigint,
team_name varchar(100),
assistant_status varchar(30),
work_status varchar(30),
entry_time timestamptz,
resign_time timestamptz,
start_time timestamptz,
end_time timestamptz,
create_time timestamptz,
update_time timestamptz,
system_role_id bigint,
online_status varchar(30),
allow_cx integer,
charge_way varchar(30),
pd_unit_price numeric(14,2),
cx_unit_price numeric(14,2),
is_guaranteed integer,
is_team_leader integer,
serial_number varchar(64),
show_sort integer,
is_delete integer,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, assistant_id)
);
COMMENT ON TABLE billiards.dim_assistant IS '助教/技师维度Assistant/List';
COMMENT ON COLUMN billiards.dim_assistant.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_assistant.assistant_id IS '助教 ID (id)';
COMMENT ON COLUMN billiards.dim_assistant.assistant_no IS '助教编号 (assistant_no)';
COMMENT ON COLUMN billiards.dim_assistant.nickname IS '昵称 (nickname)';
COMMENT ON COLUMN billiards.dim_assistant.real_name IS '真实姓名 (real_name)';
COMMENT ON COLUMN billiards.dim_assistant.gender IS '性别';
COMMENT ON COLUMN billiards.dim_assistant.mobile IS '手机号';
COMMENT ON COLUMN billiards.dim_assistant.level IS '等级/段位 (level)';
COMMENT ON COLUMN billiards.dim_assistant.team_id IS '团队 ID (team_id)';
COMMENT ON COLUMN billiards.dim_assistant.team_name IS '团队名称 (team_name)';
COMMENT ON COLUMN billiards.dim_assistant.assistant_status IS '账号状态 (assistant_status)';
COMMENT ON COLUMN billiards.dim_assistant.work_status IS '工作状态 (work_status)';
COMMENT ON COLUMN billiards.dim_assistant.entry_time IS '入职时间 (entry_time)';
COMMENT ON COLUMN billiards.dim_assistant.resign_time IS '离职时间 (resign_time)';
COMMENT ON COLUMN billiards.dim_assistant.start_time IS '可服务开始时间 (start_time)';
COMMENT ON COLUMN billiards.dim_assistant.end_time IS '可服务结束时间 (end_time)';
COMMENT ON COLUMN billiards.dim_assistant.create_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.dim_assistant.update_time IS '最近更新时间 (update_time)';
COMMENT ON COLUMN billiards.dim_assistant.system_role_id IS '系统角色 ID';
COMMENT ON COLUMN billiards.dim_assistant.online_status IS '在线/离线状态';
COMMENT ON COLUMN billiards.dim_assistant.allow_cx IS '是否允许撤销/重开';
COMMENT ON COLUMN billiards.dim_assistant.charge_way IS '计费方式 (charge_way)';
COMMENT ON COLUMN billiards.dim_assistant.pd_unit_price IS '陪打单价 (pd_unit_price)';
COMMENT ON COLUMN billiards.dim_assistant.cx_unit_price IS '拆洗/其它单价 (cx_unit_price)';
COMMENT ON COLUMN billiards.dim_assistant.is_guaranteed IS '是否保底';
COMMENT ON COLUMN billiards.dim_assistant.is_team_leader IS '是否队长';
COMMENT ON COLUMN billiards.dim_assistant.serial_number IS '序列号/展示码 (serial_number)';
COMMENT ON COLUMN billiards.dim_assistant.show_sort IS '展示排序 (show_sort)';
COMMENT ON COLUMN billiards.dim_assistant.is_delete IS '删除标记';
COMMENT ON COLUMN billiards.dim_assistant.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.dim_assistant.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.dim_member (
store_id bigint NOT NULL,
member_id bigint NOT NULL,
member_name varchar(100),
phone varchar(30),
balance numeric(18,4),
status varchar(30),
register_time timestamptz,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, member_id)
);
COMMENT ON TABLE billiards.dim_member IS '会员维度MemberProfile/GetTenantMemberList';
COMMENT ON COLUMN billiards.dim_member.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_member.member_id IS '会员 ID (memberId)';
COMMENT ON COLUMN billiards.dim_member.member_name IS '会员名称 (memberName)';
COMMENT ON COLUMN billiards.dim_member.phone IS '手机号 (phone)';
COMMENT ON COLUMN billiards.dim_member.balance IS '储值余额 (balance)';
COMMENT ON COLUMN billiards.dim_member.status IS '会员状态 (status)';
COMMENT ON COLUMN billiards.dim_member.register_time IS '注册时间 (registerTime)';
COMMENT ON COLUMN billiards.dim_member.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.dim_member.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.dim_package_coupon (
store_id bigint NOT NULL,
package_id bigint NOT NULL,
package_code varchar(100),
package_name varchar(200),
table_area_id bigint,
table_area_name varchar(100),
selling_price numeric(14,2),
duration_seconds integer,
start_time timestamptz,
end_time timestamptz,
type varchar(50),
is_enabled integer,
is_delete integer,
usable_count integer,
creator_name varchar(100),
date_type varchar(50),
group_type varchar(50),
coupon_money numeric(14,2),
area_tag_type varchar(50),
system_group_type varchar(50),
card_type_ids text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, package_id)
);
COMMENT ON TABLE billiards.dim_package_coupon IS '团购/套餐定义维度Package/List';
COMMENT ON COLUMN billiards.dim_package_coupon.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_package_coupon.package_id IS '套餐主键 (id)';
COMMENT ON COLUMN billiards.dim_package_coupon.package_code IS '套餐编码 (package_id 或自定义编码)';
COMMENT ON COLUMN billiards.dim_package_coupon.package_name IS '套餐名称 (package_name)';
COMMENT ON COLUMN billiards.dim_package_coupon.table_area_id IS '适用台桌区域 ID';
COMMENT ON COLUMN billiards.dim_package_coupon.table_area_name IS '适用台桌区域名称';
COMMENT ON COLUMN billiards.dim_package_coupon.selling_price IS '售卖价格 (selling_price)';
COMMENT ON COLUMN billiards.dim_package_coupon.duration_seconds IS '可用时长(秒)(duration)';
COMMENT ON COLUMN billiards.dim_package_coupon.start_time IS '可用时间起';
COMMENT ON COLUMN billiards.dim_package_coupon.end_time IS '可用时间止';
COMMENT ON COLUMN billiards.dim_package_coupon.type IS '套餐类型 (type/group_type)';
COMMENT ON COLUMN billiards.dim_package_coupon.is_enabled IS '是否启用 (is_enabled)';
COMMENT ON COLUMN billiards.dim_package_coupon.is_delete IS '删除标记 (is_delete)';
COMMENT ON COLUMN billiards.dim_package_coupon.usable_count IS '可使用次数 (usable_count)';
COMMENT ON COLUMN billiards.dim_package_coupon.creator_name IS '创建人 (creator_name)';
COMMENT ON COLUMN billiards.dim_package_coupon.date_type IS '日期限制 (date_type)';
COMMENT ON COLUMN billiards.dim_package_coupon.group_type IS '渠道/团购类型 (group_type)';
COMMENT ON COLUMN billiards.dim_package_coupon.coupon_money IS '券面额 (coupon_money)';
COMMENT ON COLUMN billiards.dim_package_coupon.area_tag_type IS '区域标签类型';
COMMENT ON COLUMN billiards.dim_package_coupon.system_group_type IS '系统套餐类型 (system_group_type)';
COMMENT ON COLUMN billiards.dim_package_coupon.card_type_ids IS '适用会员卡类型列表 (card_type_ids)';
COMMENT ON COLUMN billiards.dim_package_coupon.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.dim_package_coupon.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.dim_product (
store_id bigint NOT NULL,
product_id bigint NOT NULL,
site_product_id bigint,
product_name varchar(200) NOT NULL,
category_id bigint,
category_name varchar(100),
second_category_id bigint,
unit varchar(20),
cost_price numeric(14,4),
sale_price numeric(14,4),
allow_discount boolean,
status varchar(30),
supplier_id bigint,
barcode varchar(128),
is_combo boolean,
created_time timestamptz,
updated_time timestamptz,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, product_id)
);
COMMENT ON TABLE billiards.dim_product IS '商品维度TenantGoods/QueryTenantGoods';
COMMENT ON COLUMN billiards.dim_product.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_product.product_id IS '商品 ID (siteGoodsId/tenantGoodsId)';
COMMENT ON COLUMN billiards.dim_product.site_product_id IS '站点/门店商品 ID (siteGoodsId)';
COMMENT ON COLUMN billiards.dim_product.product_name IS '商品名称 (goodsName/productName)';
COMMENT ON COLUMN billiards.dim_product.category_id IS '一级分类 ID (goodsCategoryId)';
COMMENT ON COLUMN billiards.dim_product.category_name IS '一级分类名称 (categoryName)';
COMMENT ON COLUMN billiards.dim_product.second_category_id IS '二级分类 ID (goodsSecondCategoryId)';
COMMENT ON COLUMN billiards.dim_product.unit IS '计量单位 (goodsUnit)';
COMMENT ON COLUMN billiards.dim_product.cost_price IS '成本价 (costPrice)';
COMMENT ON COLUMN billiards.dim_product.sale_price IS '销售价 (goodsPrice/salePrice)';
COMMENT ON COLUMN billiards.dim_product.allow_discount IS '是否允许折扣 (able_discount)';
COMMENT ON COLUMN billiards.dim_product.status IS '商品状态 (goodsState/status)';
COMMENT ON COLUMN billiards.dim_product.supplier_id IS '供应商 ID';
COMMENT ON COLUMN billiards.dim_product.barcode IS '条码 (barcode)';
COMMENT ON COLUMN billiards.dim_product.is_combo IS '是否组合/套餐商品 (isCombo)';
COMMENT ON COLUMN billiards.dim_product.created_time IS '创建时间 (createTime)';
COMMENT ON COLUMN billiards.dim_product.updated_time IS '更新时间 (updateTime)';
COMMENT ON COLUMN billiards.dim_product.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.dim_product.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.dim_product_price_scd (
product_scd_id bigserial PRIMARY KEY,
store_id bigint NOT NULL,
product_id bigint NOT NULL,
product_name varchar(200),
category_id bigint,
category_name varchar(100),
second_category_id bigint,
cost_price numeric(14,4),
sale_price numeric(14,4),
allow_discount boolean,
status varchar(30),
valid_from timestamptz NOT NULL DEFAULT now(),
valid_to timestamptz,
is_current boolean NOT NULL DEFAULT true,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
CONSTRAINT fk_dpps_product FOREIGN KEY (store_id, product_id)
REFERENCES billiards.dim_product(store_id, product_id) ON DELETE CASCADE,
CONSTRAINT ck_dpps_range CHECK (
valid_from < COALESCE(valid_to, '9999-12-31 00:00:00+00'::timestamptz)
),
CONSTRAINT uq_dpps_current UNIQUE (store_id, product_id) WHERE (is_current)
);
COMMENT ON TABLE billiards.dim_product_price_scd IS '商品维度价格 SCD记录价格/分类变动历史)';
COMMENT ON COLUMN billiards.dim_product_price_scd.product_scd_id IS '价格 SCD 主键';
COMMENT ON COLUMN billiards.dim_product_price_scd.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_product_price_scd.product_id IS '商品 ID';
COMMENT ON COLUMN billiards.dim_product_price_scd.product_name IS '商品名称(冗余,方便简单查询)';
COMMENT ON COLUMN billiards.dim_product_price_scd.category_id IS '一级分类 ID';
COMMENT ON COLUMN billiards.dim_product_price_scd.category_name IS '一级分类名称';
COMMENT ON COLUMN billiards.dim_product_price_scd.second_category_id IS '二级分类 ID';
COMMENT ON COLUMN billiards.dim_product_price_scd.cost_price IS '成本价';
COMMENT ON COLUMN billiards.dim_product_price_scd.sale_price IS '销售价';
COMMENT ON COLUMN billiards.dim_product_price_scd.allow_discount IS '是否允许折扣';
COMMENT ON COLUMN billiards.dim_product_price_scd.status IS '商品状态 (上/下架)';
COMMENT ON COLUMN billiards.dim_product_price_scd.valid_from IS '生效时间';
COMMENT ON COLUMN billiards.dim_product_price_scd.valid_to IS '失效时间NULL 表示当前版本';
COMMENT ON COLUMN billiards.dim_product_price_scd.is_current IS '当前有效版本标记';
COMMENT ON COLUMN billiards.dim_product_price_scd.raw_data IS '原始 JSON 快照';
CREATE VIEW IF NOT EXISTS billiards.dim_product_price_current AS
SELECT product_scd_id,
store_id,
product_id,
product_name,
category_id,
category_name,
second_category_id,
cost_price,
sale_price,
allow_discount,
status,
valid_from,
valid_to,
raw_data
FROM billiards.dim_product_price_scd
WHERE is_current;
COMMENT ON VIEW billiards.dim_product_price_current IS '商品价格 SCD 当前有效版本视图';
COMMENT ON COLUMN billiards.dim_product_price_current.product_scd_id IS '价格 SCD 主键';
COMMENT ON COLUMN billiards.dim_product_price_current.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_product_price_current.product_id IS '商品 ID';
COMMENT ON COLUMN billiards.dim_product_price_current.product_name IS '商品名称';
COMMENT ON COLUMN billiards.dim_product_price_current.category_id IS '一级分类 ID';
COMMENT ON COLUMN billiards.dim_product_price_current.category_name IS '一级分类名称';
COMMENT ON COLUMN billiards.dim_product_price_current.second_category_id IS '二级分类 ID';
COMMENT ON COLUMN billiards.dim_product_price_current.cost_price IS '成本价';
COMMENT ON COLUMN billiards.dim_product_price_current.sale_price IS '销售价';
COMMENT ON COLUMN billiards.dim_product_price_current.allow_discount IS '是否允许折扣';
COMMENT ON COLUMN billiards.dim_product_price_current.status IS '商品状态';
COMMENT ON COLUMN billiards.dim_product_price_current.valid_from IS '生效时间';
COMMENT ON COLUMN billiards.dim_product_price_current.valid_to IS '失效时间';
COMMENT ON COLUMN billiards.dim_product_price_current.raw_data IS '原始 JSON';
CREATE TABLE IF NOT EXISTS billiards.dim_table (
store_id bigint NOT NULL,
table_id bigint NOT NULL,
site_id bigint,
area_id bigint,
area_name varchar(100),
table_name varchar(100) NOT NULL,
table_price numeric(14,4),
table_status varchar(30),
table_status_name varchar(50),
light_status integer,
is_rest_area integer,
show_status integer,
virtual_table integer,
charge_free integer,
only_allow_groupon integer,
is_online_reservation integer,
created_time timestamptz,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, table_id)
);
COMMENT ON TABLE billiards.dim_table IS '台桌档案维度Table/GetSiteTables';
COMMENT ON COLUMN billiards.dim_table.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.dim_table.table_id IS '台桌 ID (id)';
COMMENT ON COLUMN billiards.dim_table.site_id IS '场馆/站点 ID (site_id)';
COMMENT ON COLUMN billiards.dim_table.area_id IS '区域 ID (site_table_area_id)';
COMMENT ON COLUMN billiards.dim_table.area_name IS '区域名称 (areaName)';
COMMENT ON COLUMN billiards.dim_table.table_name IS '台桌名称 (table_name)';
COMMENT ON COLUMN billiards.dim_table.table_price IS '台费单价 (table_price)';
COMMENT ON COLUMN billiards.dim_table.table_status IS '台桌状态代码 (table_status)';
COMMENT ON COLUMN billiards.dim_table.table_status_name IS '台桌状态名称 (tableStatusName)';
COMMENT ON COLUMN billiards.dim_table.light_status IS '灯光状态 (light_status)';
COMMENT ON COLUMN billiards.dim_table.is_rest_area IS '是否休息区 (is_rest_area)';
COMMENT ON COLUMN billiards.dim_table.show_status IS '是否展示 (show_status)';
COMMENT ON COLUMN billiards.dim_table.virtual_table IS '是否虚拟台 (virtual_table)';
COMMENT ON COLUMN billiards.dim_table.charge_free IS '是否免收费 (charge_free)';
COMMENT ON COLUMN billiards.dim_table.only_allow_groupon IS '是否仅限团购 (only_allow_groupon)';
COMMENT ON COLUMN billiards.dim_table.is_online_reservation IS '是否可线上预约 (is_online_reservation)';
COMMENT ON COLUMN billiards.dim_table.created_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.dim_table.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.dim_table.updated_at IS 'ETL 更新时间';
-- =========================
-- Billiards fact tables
-- =========================
CREATE TABLE IF NOT EXISTS billiards.fact_assistant_abolish (
store_id bigint NOT NULL,
abolish_id bigint NOT NULL,
table_id bigint,
table_name varchar(100),
table_area_id bigint,
table_area varchar(100),
assistant_no varchar(64),
assistant_name varchar(100),
charge_minutes integer,
abolish_amount numeric(14,4),
create_time timestamptz,
trash_reason text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, abolish_id)
);
COMMENT ON TABLE billiards.fact_assistant_abolish IS '助教作废/撤单流水Assistant/AbolishList';
COMMENT ON COLUMN billiards.fact_assistant_abolish.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_assistant_abolish.abolish_id IS '作废记录 ID (id)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.table_id IS '台桌 ID (tableId)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.table_name IS '台桌名称';
COMMENT ON COLUMN billiards.fact_assistant_abolish.table_area_id IS '台桌区域 ID';
COMMENT ON COLUMN billiards.fact_assistant_abolish.table_area IS '台桌区域名称';
COMMENT ON COLUMN billiards.fact_assistant_abolish.assistant_no IS '助教编号 (assistantOn)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.assistant_name IS '助教姓名';
COMMENT ON COLUMN billiards.fact_assistant_abolish.charge_minutes IS '计费分钟 (pdChargeMinutes)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.abolish_amount IS '作废金额 (assistantAbolishAmount)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.create_time IS '创建时间 (createTime)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.trash_reason IS '作废原因 (trashReason)';
COMMENT ON COLUMN billiards.fact_assistant_abolish.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_assistant_abolish.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_assistant_ledger (
store_id bigint NOT NULL,
ledger_id bigint NOT NULL,
assistant_no varchar(64),
assistant_name varchar(100),
nickname varchar(100),
level_name varchar(50),
table_name varchar(100),
ledger_unit_price numeric(14,4),
ledger_count numeric(14,4),
ledger_amount numeric(14,4),
projected_income numeric(14,4),
service_money numeric(14,4),
member_discount_amount numeric(14,4),
manual_discount_amount numeric(14,4),
coupon_deduct_money numeric(14,4),
order_trade_no bigint,
order_settle_id bigint,
operator_id bigint,
operator_name varchar(100),
assistant_team_id bigint,
assistant_level varchar(50),
site_table_id bigint,
order_assistant_id bigint,
site_assistant_id bigint,
user_id bigint,
ledger_start_time timestamptz,
ledger_end_time timestamptz,
start_use_time timestamptz,
last_use_time timestamptz,
income_seconds integer,
real_use_seconds integer,
is_trash integer,
trash_reason text,
is_confirm integer,
ledger_status varchar(30),
create_time timestamptz,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, ledger_id)
);
COMMENT ON TABLE billiards.fact_assistant_ledger IS '助教陪打计费流水Assistant/LedgerList';
COMMENT ON COLUMN billiards.fact_assistant_ledger.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_id IS '流水 ID (id)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.assistant_no IS '助教编号';
COMMENT ON COLUMN billiards.fact_assistant_ledger.assistant_name IS '助教姓名';
COMMENT ON COLUMN billiards.fact_assistant_ledger.nickname IS '昵称';
COMMENT ON COLUMN billiards.fact_assistant_ledger.level_name IS '等级名称';
COMMENT ON COLUMN billiards.fact_assistant_ledger.table_name IS '服务台桌名称';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_unit_price IS '计费单价 (ledger_unit_price)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_count IS '计费数量 (ledger_count)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_amount IS '计费金额 (ledger_amount)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.projected_income IS '预计收益 (projected_income)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.service_money IS '服务费 (service_money)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.member_discount_amount IS '会员折扣金额';
COMMENT ON COLUMN billiards.fact_assistant_ledger.manual_discount_amount IS '手动折扣金额';
COMMENT ON COLUMN billiards.fact_assistant_ledger.coupon_deduct_money IS '券抵扣金额';
COMMENT ON COLUMN billiards.fact_assistant_ledger.order_trade_no IS '订单交易号 (order_trade_no)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.order_settle_id IS '结算单 ID (order_settle_id)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.operator_id IS '操作人 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.operator_name IS '操作人姓名';
COMMENT ON COLUMN billiards.fact_assistant_ledger.assistant_team_id IS '助教团队 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.assistant_level IS '助教等级';
COMMENT ON COLUMN billiards.fact_assistant_ledger.site_table_id IS '台桌 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.order_assistant_id IS '订单内助教 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.site_assistant_id IS '场馆助教 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.user_id IS '会员/顾客 ID';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_start_time IS '计费开始时间';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_end_time IS '计费结束时间';
COMMENT ON COLUMN billiards.fact_assistant_ledger.start_use_time IS '开始使用时间';
COMMENT ON COLUMN billiards.fact_assistant_ledger.last_use_time IS '最后使用时间';
COMMENT ON COLUMN billiards.fact_assistant_ledger.income_seconds IS '计费秒数 (income_seconds)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.real_use_seconds IS '实际使用秒数 (real_use_seconds)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.is_trash IS '是否作废 (is_trash)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.trash_reason IS '作废原因 (trash_reason)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.is_confirm IS '是否确认 (is_confirm)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.ledger_status IS '状态 (ledger_status)';
COMMENT ON COLUMN billiards.fact_assistant_ledger.create_time IS '创建时间';
COMMENT ON COLUMN billiards.fact_assistant_ledger.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_assistant_ledger.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_inventory_change (
store_id bigint NOT NULL,
change_id bigint NOT NULL,
site_goods_id bigint,
stock_type varchar(50),
goods_name varchar(200),
change_time timestamptz,
start_qty numeric(18,4),
end_qty numeric(18,4),
change_qty numeric(18,4),
unit varchar(20),
price numeric(14,4),
operator_name varchar(100),
remark text,
goods_category_id bigint,
goods_second_category_id bigint,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, change_id)
);
COMMENT ON TABLE billiards.fact_inventory_change IS '库存变更流水Inventory/ChangeList';
COMMENT ON COLUMN billiards.fact_inventory_change.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_inventory_change.change_id IS '库存变动 ID (siteGoodsStockId)';
COMMENT ON COLUMN billiards.fact_inventory_change.site_goods_id IS '门店商品 ID (siteGoodsId)';
COMMENT ON COLUMN billiards.fact_inventory_change.stock_type IS '变动类型 (stockType)';
COMMENT ON COLUMN billiards.fact_inventory_change.goods_name IS '商品名称 (goodsName)';
COMMENT ON COLUMN billiards.fact_inventory_change.change_time IS '变动时间 (createTime)';
COMMENT ON COLUMN billiards.fact_inventory_change.start_qty IS '变动前数量 (startNum)';
COMMENT ON COLUMN billiards.fact_inventory_change.end_qty IS '变动后数量 (endNum)';
COMMENT ON COLUMN billiards.fact_inventory_change.change_qty IS '变化数量 (changeNum)';
COMMENT ON COLUMN billiards.fact_inventory_change.unit IS '单位 (unit)';
COMMENT ON COLUMN billiards.fact_inventory_change.price IS '单价 (price)';
COMMENT ON COLUMN billiards.fact_inventory_change.operator_name IS '操作人 (operatorName)';
COMMENT ON COLUMN billiards.fact_inventory_change.remark IS '备注 (remark)';
COMMENT ON COLUMN billiards.fact_inventory_change.goods_category_id IS '一级分类 ID';
COMMENT ON COLUMN billiards.fact_inventory_change.goods_second_category_id IS '二级分类 ID';
COMMENT ON COLUMN billiards.fact_inventory_change.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_inventory_change.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_order (
store_id bigint NOT NULL,
order_id bigint NOT NULL,
order_no varchar(64),
member_id bigint,
table_id bigint,
order_time timestamptz,
end_time timestamptz,
total_amount numeric(14,4),
discount_amount numeric(14,4),
final_amount numeric(14,4),
pay_status varchar(30),
order_status varchar(30),
remark text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, order_id)
);
COMMENT ON TABLE billiards.fact_order IS '订单事实表(/order/list 返回的结账记录)';
COMMENT ON COLUMN billiards.fact_order.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_order.order_id IS '订单 ID (orderId)';
COMMENT ON COLUMN billiards.fact_order.order_no IS '订单编号 (orderNo)';
COMMENT ON COLUMN billiards.fact_order.member_id IS '会员 ID (memberId)';
COMMENT ON COLUMN billiards.fact_order.table_id IS '台桌 ID (tableId)';
COMMENT ON COLUMN billiards.fact_order.order_time IS '开单时间/开始时间 (orderTime)';
COMMENT ON COLUMN billiards.fact_order.end_time IS '结账时间 (endTime)';
COMMENT ON COLUMN billiards.fact_order.total_amount IS '订单总金额 (totalAmount)';
COMMENT ON COLUMN billiards.fact_order.discount_amount IS '折扣金额 (discountAmount)';
COMMENT ON COLUMN billiards.fact_order.final_amount IS '应付金额 (finalAmount)';
COMMENT ON COLUMN billiards.fact_order.pay_status IS '支付状态 (payStatus)';
COMMENT ON COLUMN billiards.fact_order.order_status IS '订单状态 (orderStatus)';
COMMENT ON COLUMN billiards.fact_order.remark IS '备注 (remark)';
COMMENT ON COLUMN billiards.fact_order.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_order.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_payment (
store_id bigint NOT NULL,
pay_id bigint NOT NULL,
order_id bigint,
order_settle_id bigint,
relate_type varchar(50),
relate_id bigint,
site_id bigint,
tenant_id bigint,
pay_time timestamptz,
create_time timestamptz,
pay_amount numeric(14,4),
pay_type varchar(50),
payment_method varchar(50),
online_pay_channel varchar(50),
pay_status varchar(30),
pay_terminal varchar(50),
remark text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, pay_id)
);
COMMENT ON TABLE billiards.fact_payment IS '支付流水pay/records';
COMMENT ON COLUMN billiards.fact_payment.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_payment.pay_id IS '支付记录 ID (payId)';
COMMENT ON COLUMN billiards.fact_payment.order_id IS '旧版订单 ID (orderId),保留兼容';
COMMENT ON COLUMN billiards.fact_payment.order_settle_id IS '结算单 ID (relate_id 当 relate_type=2)';
COMMENT ON COLUMN billiards.fact_payment.relate_type IS '关联类型 (relate_type)';
COMMENT ON COLUMN billiards.fact_payment.relate_id IS '关联 ID (relate_id)';
COMMENT ON COLUMN billiards.fact_payment.site_id IS '门店 ID冗余自 payload';
COMMENT ON COLUMN billiards.fact_payment.tenant_id IS '租户 ID';
COMMENT ON COLUMN billiards.fact_payment.pay_time IS '支付时间 (payTime)';
COMMENT ON COLUMN billiards.fact_payment.create_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.fact_payment.pay_amount IS '支付金额 (payAmount)';
COMMENT ON COLUMN billiards.fact_payment.pay_type IS '支付渠道 (payType)';
COMMENT ON COLUMN billiards.fact_payment.payment_method IS '支付方式 (payment_method)';
COMMENT ON COLUMN billiards.fact_payment.online_pay_channel IS '线上支付渠道 (online_pay_channel)';
COMMENT ON COLUMN billiards.fact_payment.pay_status IS '支付状态 (payStatus)';
COMMENT ON COLUMN billiards.fact_payment.pay_terminal IS '支付终端 (pay_terminal)';
COMMENT ON COLUMN billiards.fact_payment.remark IS '备注';
COMMENT ON COLUMN billiards.fact_payment.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_payment.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_refund (
store_id bigint NOT NULL,
refund_id bigint NOT NULL,
site_id bigint,
tenant_id bigint,
pay_amount numeric(14,4),
pay_status varchar(30),
pay_time timestamptz,
create_time timestamptz,
relate_type varchar(50),
relate_id bigint,
payment_method varchar(50),
refund_amount numeric(14,4),
action_type varchar(30),
pay_terminal varchar(50),
operator_id bigint,
channel_pay_no varchar(100),
channel_fee numeric(14,4),
is_delete integer,
member_id bigint,
member_card_id bigint,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, refund_id)
);
COMMENT ON TABLE billiards.fact_refund IS '退款流水Pay/RefundList';
COMMENT ON COLUMN billiards.fact_refund.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_refund.refund_id IS '退款记录 ID (id)';
COMMENT ON COLUMN billiards.fact_refund.site_id IS '场地 ID (site_id)';
COMMENT ON COLUMN billiards.fact_refund.tenant_id IS '租户 ID (tenant_id)';
COMMENT ON COLUMN billiards.fact_refund.pay_amount IS '原支付金额 (pay_amount)';
COMMENT ON COLUMN billiards.fact_refund.pay_status IS '支付状态 (pay_status)';
COMMENT ON COLUMN billiards.fact_refund.pay_time IS '支付时间 (pay_time)';
COMMENT ON COLUMN billiards.fact_refund.create_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.fact_refund.relate_type IS '关联对象类型 (relate_type)';
COMMENT ON COLUMN billiards.fact_refund.relate_id IS '关联对象 ID (relate_id)';
COMMENT ON COLUMN billiards.fact_refund.payment_method IS '支付方式 (payment_method)';
COMMENT ON COLUMN billiards.fact_refund.refund_amount IS '退款金额 (refund_amount)';
COMMENT ON COLUMN billiards.fact_refund.action_type IS '操作类型 (action_type)';
COMMENT ON COLUMN billiards.fact_refund.pay_terminal IS '终端类型 (pay_terminal)';
COMMENT ON COLUMN billiards.fact_refund.operator_id IS '操作人 ID (operator_id)';
COMMENT ON COLUMN billiards.fact_refund.channel_pay_no IS '渠道支付单号 (channel_pay_no)';
COMMENT ON COLUMN billiards.fact_refund.channel_fee IS '渠道手续费 (channel_fee)';
COMMENT ON COLUMN billiards.fact_refund.is_delete IS '删除标记 (is_delete)';
COMMENT ON COLUMN billiards.fact_refund.member_id IS '会员 ID (member_id)';
COMMENT ON COLUMN billiards.fact_refund.member_card_id IS '会员卡 ID (member_card_id)';
COMMENT ON COLUMN billiards.fact_refund.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_refund.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_table_discount (
store_id bigint NOT NULL,
discount_id bigint NOT NULL,
adjust_type varchar(50),
applicant_id bigint,
applicant_name varchar(100),
operator_id bigint,
operator_name varchar(100),
ledger_amount numeric(14,4),
ledger_count numeric(14,4),
ledger_name varchar(100),
ledger_status varchar(30),
order_settle_id bigint,
order_trade_no bigint,
site_table_id bigint,
table_area_id bigint,
table_area_name varchar(100),
create_time timestamptz,
is_delete integer,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, discount_id)
);
COMMENT ON TABLE billiards.fact_table_discount IS '台费调价/折扣记录Table/AdjustList';
COMMENT ON COLUMN billiards.fact_table_discount.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_table_discount.discount_id IS '调价记录 ID (id)';
COMMENT ON COLUMN billiards.fact_table_discount.adjust_type IS '调价类型 (adjust_type/adjustType)';
COMMENT ON COLUMN billiards.fact_table_discount.applicant_id IS '申请人 ID (applicant_id)';
COMMENT ON COLUMN billiards.fact_table_discount.applicant_name IS '申请人姓名 (applicant_name)';
COMMENT ON COLUMN billiards.fact_table_discount.operator_id IS '操作人 ID (operator_id)';
COMMENT ON COLUMN billiards.fact_table_discount.operator_name IS '操作人姓名 (operator_name)';
COMMENT ON COLUMN billiards.fact_table_discount.ledger_amount IS '台费金额调整 (ledger_amount)';
COMMENT ON COLUMN billiards.fact_table_discount.ledger_count IS '台费数量调整 (ledger_count)';
COMMENT ON COLUMN billiards.fact_table_discount.ledger_name IS '科目名称 (ledger_name)';
COMMENT ON COLUMN billiards.fact_table_discount.ledger_status IS '记录状态 (ledger_status)';
COMMENT ON COLUMN billiards.fact_table_discount.order_settle_id IS '结算单 ID (order_settle_id)';
COMMENT ON COLUMN billiards.fact_table_discount.order_trade_no IS '订单号 (order_trade_no)';
COMMENT ON COLUMN billiards.fact_table_discount.site_table_id IS '台桌 ID (site_table_id)';
COMMENT ON COLUMN billiards.fact_table_discount.table_area_id IS '台桌区域 ID';
COMMENT ON COLUMN billiards.fact_table_discount.table_area_name IS '台桌区域名称';
COMMENT ON COLUMN billiards.fact_table_discount.create_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.fact_table_discount.is_delete IS '删除标记 (is_delete)';
COMMENT ON COLUMN billiards.fact_table_discount.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_table_discount.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_topup (
store_id bigint NOT NULL,
topup_id bigint NOT NULL,
member_id bigint,
member_name varchar(100),
member_phone varchar(30),
card_id bigint,
card_type_name varchar(100),
pay_amount numeric(14,4),
consume_money numeric(14,4),
settle_status varchar(30),
settle_type varchar(30),
settle_name varchar(100),
settle_relate_id bigint,
pay_time timestamptz,
create_time timestamptz,
operator_id bigint,
operator_name varchar(100),
payment_method varchar(50),
refund_amount numeric(14,4),
cash_amount numeric(14,4),
card_amount numeric(14,4),
balance_amount numeric(14,4),
online_amount numeric(14,4),
rounding_amount numeric(14,4),
adjust_amount numeric(14,4),
goods_money numeric(14,4),
table_charge_money numeric(14,4),
service_money numeric(14,4),
coupon_amount numeric(14,4),
order_remark text,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, topup_id)
);
COMMENT ON TABLE billiards.fact_topup IS '储值充值结算流水Topup/SettleList';
COMMENT ON COLUMN billiards.fact_topup.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_topup.topup_id IS '充值记录 ID (id)';
COMMENT ON COLUMN billiards.fact_topup.member_id IS '会员 ID (memberId)';
COMMENT ON COLUMN billiards.fact_topup.member_name IS '会员姓名 (memberName)';
COMMENT ON COLUMN billiards.fact_topup.member_phone IS '会员手机号 (memberPhone)';
COMMENT ON COLUMN billiards.fact_topup.card_id IS '会员卡 ID (tenantMemberCardId)';
COMMENT ON COLUMN billiards.fact_topup.card_type_name IS '会员卡类型名称 (memberCardTypeName)';
COMMENT ON COLUMN billiards.fact_topup.pay_amount IS '支付金额 (payAmount)';
COMMENT ON COLUMN billiards.fact_topup.consume_money IS '可消费金额/储值 (consumeMoney)';
COMMENT ON COLUMN billiards.fact_topup.settle_status IS '结算状态 (settleStatus)';
COMMENT ON COLUMN billiards.fact_topup.settle_type IS '结算方式 (settleType)';
COMMENT ON COLUMN billiards.fact_topup.settle_name IS '结算名称 (settleName)';
COMMENT ON COLUMN billiards.fact_topup.settle_relate_id IS '结算关联 ID (settleRelateId)';
COMMENT ON COLUMN billiards.fact_topup.pay_time IS '支付时间 (payTime)';
COMMENT ON COLUMN billiards.fact_topup.create_time IS '创建时间 (createTime)';
COMMENT ON COLUMN billiards.fact_topup.operator_id IS '操作人 ID (operatorId)';
COMMENT ON COLUMN billiards.fact_topup.operator_name IS '操作人姓名 (operatorName)';
COMMENT ON COLUMN billiards.fact_topup.payment_method IS '支付方式 (paymentMethod)';
COMMENT ON COLUMN billiards.fact_topup.refund_amount IS '退款金额 (refundAmount)';
COMMENT ON COLUMN billiards.fact_topup.cash_amount IS '现金金额 (cashAmount)';
COMMENT ON COLUMN billiards.fact_topup.card_amount IS '银行卡金额 (cardAmount)';
COMMENT ON COLUMN billiards.fact_topup.balance_amount IS '余额抵扣金额 (balanceAmount)';
COMMENT ON COLUMN billiards.fact_topup.online_amount IS '在线支付金额 (onlineAmount)';
COMMENT ON COLUMN billiards.fact_topup.rounding_amount IS '抹零金额 (roundingAmount)';
COMMENT ON COLUMN billiards.fact_topup.adjust_amount IS '调整金额 (adjustAmount)';
COMMENT ON COLUMN billiards.fact_topup.goods_money IS '商品金额 (goodsMoney)';
COMMENT ON COLUMN billiards.fact_topup.table_charge_money IS '台费金额 (tableChargeMoney)';
COMMENT ON COLUMN billiards.fact_topup.service_money IS '服务费 (serviceMoney)';
COMMENT ON COLUMN billiards.fact_topup.coupon_amount IS '券抵扣金额 (couponAmount)';
COMMENT ON COLUMN billiards.fact_topup.order_remark IS '备注 (orderRemark)';
COMMENT ON COLUMN billiards.fact_topup.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_topup.updated_at IS 'ETL 更新时间';
CREATE TABLE IF NOT EXISTS billiards.fact_coupon_usage (
store_id bigint NOT NULL,
usage_id bigint NOT NULL,
coupon_code varchar(100),
coupon_channel varchar(50),
coupon_name varchar(200),
sale_price numeric(14,4),
coupon_money numeric(14,4),
coupon_free_time integer,
use_status varchar(30),
create_time timestamptz,
consume_time timestamptz,
operator_id bigint,
operator_name varchar(100),
table_id bigint,
site_order_id bigint,
group_package_id bigint,
coupon_remark text,
deal_id varchar(100),
certificate_id varchar(100),
verify_id varchar(100),
is_delete integer,
raw_data jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (store_id, usage_id)
);
COMMENT ON TABLE billiards.fact_coupon_usage IS '平台券验券/核销流水Coupon/UsageList';
COMMENT ON COLUMN billiards.fact_coupon_usage.store_id IS '门店 ID';
COMMENT ON COLUMN billiards.fact_coupon_usage.usage_id IS '核销记录 ID (id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_code IS '券码 (coupon_code)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_channel IS '券渠道 (coupon_channel)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_name IS '券名称 (coupon_name)';
COMMENT ON COLUMN billiards.fact_coupon_usage.sale_price IS '售卖价 (sale_price)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_money IS '券面额 (coupon_money)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_free_time IS '赠送/免单时长 (coupon_free_time)';
COMMENT ON COLUMN billiards.fact_coupon_usage.use_status IS '核销状态 (use_status)';
COMMENT ON COLUMN billiards.fact_coupon_usage.create_time IS '创建时间 (create_time)';
COMMENT ON COLUMN billiards.fact_coupon_usage.consume_time IS '核销时间 (consume_time)';
COMMENT ON COLUMN billiards.fact_coupon_usage.operator_id IS '操作人 ID (operator_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.operator_name IS '操作人姓名 (operator_name)';
COMMENT ON COLUMN billiards.fact_coupon_usage.table_id IS '台桌 ID (table_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.site_order_id IS '场馆订单 ID (site_order_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.group_package_id IS '套餐 ID (group_package_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.coupon_remark IS '备注 (coupon_remark)';
COMMENT ON COLUMN billiards.fact_coupon_usage.deal_id IS '团购/渠道 deal_id';
COMMENT ON COLUMN billiards.fact_coupon_usage.certificate_id IS '凭证号 (certificate_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.verify_id IS '核销流水号 (verify_id)';
COMMENT ON COLUMN billiards.fact_coupon_usage.is_delete IS '删除标记 (is_delete)';
COMMENT ON COLUMN billiards.fact_coupon_usage.raw_data IS '原始 JSON';
COMMENT ON COLUMN billiards.fact_coupon_usage.updated_at IS 'ETL 更新时间';
-- =========================
-- ETL admin tables
-- =========================
CREATE TYPE IF NOT EXISTS etl_admin.run_status_enum AS ENUM ('SUCC', 'FAIL', 'PARTIAL');
COMMENT ON TYPE etl_admin.run_status_enum IS 'ETL 运行状态枚举(成功/失败/部分成功)';
CREATE TABLE IF NOT EXISTS etl_admin.etl_task (
task_id bigserial PRIMARY KEY,
store_id bigint NOT NULL,
task_code varchar(50) NOT NULL,
description text,
enabled boolean NOT NULL DEFAULT true,
cursor_field varchar(100),
window_minutes_default integer DEFAULT 60,
overlap_seconds integer DEFAULT 120,
page_size integer DEFAULT 200,
retry_max integer DEFAULT 3,
params jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (store_id, task_code)
);
COMMENT ON TABLE etl_admin.etl_task IS 'ETL 任务配置(启停、窗口、分页参数等)';
COMMENT ON COLUMN etl_admin.etl_task.task_id IS '任务 ID自增主键';
COMMENT ON COLUMN etl_admin.etl_task.store_id IS '门店 ID任务所属门店';
COMMENT ON COLUMN etl_admin.etl_task.task_code IS '任务代码(如 PRODUCTS、ORDERS';
COMMENT ON COLUMN etl_admin.etl_task.description IS '任务描述';
COMMENT ON COLUMN etl_admin.etl_task.enabled IS '是否启用';
COMMENT ON COLUMN etl_admin.etl_task.cursor_field IS '游标使用的字段(如时间或 ID';
COMMENT ON COLUMN etl_admin.etl_task.window_minutes_default IS '默认抓取窗口(分钟)';
COMMENT ON COLUMN etl_admin.etl_task.overlap_seconds IS '窗口重叠秒数,用于防重';
COMMENT ON COLUMN etl_admin.etl_task.page_size IS 'API 分页大小';
COMMENT ON COLUMN etl_admin.etl_task.retry_max IS 'API 最大重试次数';
COMMENT ON COLUMN etl_admin.etl_task.params IS '额外参数 (JSON)';
COMMENT ON COLUMN etl_admin.etl_task.created_at IS '创建时间';
COMMENT ON COLUMN etl_admin.etl_task.updated_at IS '更新时间';
CREATE TABLE IF NOT EXISTS etl_admin.etl_cursor (
cursor_id bigserial PRIMARY KEY,
task_id bigint NOT NULL REFERENCES etl_admin.etl_task(task_id) ON DELETE CASCADE,
store_id bigint NOT NULL,
last_start timestamptz,
last_end timestamptz,
last_id bigint,
extra jsonb NOT NULL DEFAULT '{}'::jsonb,
last_run_id bigint,
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (task_id, store_id)
);
COMMENT ON TABLE etl_admin.etl_cursor IS 'ETL 游标存储(记录每个任务的上次窗口与 ID';
COMMENT ON COLUMN etl_admin.etl_cursor.cursor_id IS '游标主键';
COMMENT ON COLUMN etl_admin.etl_cursor.task_id IS '关联任务 ID';
COMMENT ON COLUMN etl_admin.etl_cursor.store_id IS '门店 ID';
COMMENT ON COLUMN etl_admin.etl_cursor.last_start IS '上次窗口起始时间';
COMMENT ON COLUMN etl_admin.etl_cursor.last_end IS '上次窗口结束时间';
COMMENT ON COLUMN etl_admin.etl_cursor.last_id IS '上次处理的 ID适用于基于 ID 的翻页)';
COMMENT ON COLUMN etl_admin.etl_cursor.extra IS '额外游标信息 (JSON)';
COMMENT ON COLUMN etl_admin.etl_cursor.last_run_id IS '最后一次运行 run_id';
COMMENT ON COLUMN etl_admin.etl_cursor.updated_at IS '更新时间';
CREATE TABLE IF NOT EXISTS etl_admin.etl_run (
run_id bigserial PRIMARY KEY,
run_uuid varchar(64) NOT NULL,
task_id bigint NOT NULL REFERENCES etl_admin.etl_task(task_id) ON DELETE CASCADE,
store_id bigint NOT NULL,
status etl_admin.run_status_enum NOT NULL DEFAULT 'SUCC',
started_at timestamptz NOT NULL DEFAULT now(),
ended_at timestamptz,
window_start timestamptz,
window_end timestamptz,
window_minutes integer,
overlap_seconds integer,
fetched_count integer DEFAULT 0,
loaded_count integer DEFAULT 0,
updated_count integer DEFAULT 0,
skipped_count integer DEFAULT 0,
error_count integer DEFAULT 0,
unknown_fields integer DEFAULT 0,
export_dir text,
log_path text,
request_params jsonb NOT NULL DEFAULT '{}'::jsonb,
manifest jsonb NOT NULL DEFAULT '{}'::jsonb,
error_message text,
extra jsonb NOT NULL DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_etl_run_task ON etl_admin.etl_run(task_id, started_at DESC);
CREATE INDEX IF NOT EXISTS idx_etl_run_status ON etl_admin.etl_run(status);
COMMENT ON TABLE etl_admin.etl_run IS 'ETL 运行记录(针对每次任务执行)';
COMMENT ON COLUMN etl_admin.etl_run.run_id IS '运行记录 ID';
COMMENT ON COLUMN etl_admin.etl_run.run_uuid IS '运行批次 UUID';
COMMENT ON COLUMN etl_admin.etl_run.task_id IS '任务 ID';
COMMENT ON COLUMN etl_admin.etl_run.store_id IS '门店 ID';
COMMENT ON COLUMN etl_admin.etl_run.status IS '运行状态 (SUCC/FAIL/PARTIAL)';
COMMENT ON COLUMN etl_admin.etl_run.started_at IS '开始时间';
COMMENT ON COLUMN etl_admin.etl_run.ended_at IS '结束时间';
COMMENT ON COLUMN etl_admin.etl_run.window_start IS '窗口起始时间';
COMMENT ON COLUMN etl_admin.etl_run.window_end IS '窗口结束时间';
COMMENT ON COLUMN etl_admin.etl_run.window_minutes IS '窗口长度(分钟)';
COMMENT ON COLUMN etl_admin.etl_run.overlap_seconds IS '重叠秒数';
COMMENT ON COLUMN etl_admin.etl_run.fetched_count IS '抓取条数';
COMMENT ON COLUMN etl_admin.etl_run.loaded_count IS '插入条数';
COMMENT ON COLUMN etl_admin.etl_run.updated_count IS '更新条数';
COMMENT ON COLUMN etl_admin.etl_run.skipped_count IS '跳过条数';
COMMENT ON COLUMN etl_admin.etl_run.error_count IS '错误条数';
COMMENT ON COLUMN etl_admin.etl_run.unknown_fields IS '未知字段次数';
COMMENT ON COLUMN etl_admin.etl_run.export_dir IS '导出目录';
COMMENT ON COLUMN etl_admin.etl_run.log_path IS '日志文件路径';
COMMENT ON COLUMN etl_admin.etl_run.request_params IS '本次请求参数 (JSON)';
COMMENT ON COLUMN etl_admin.etl_run.manifest IS '导出 manifest (JSON)';
COMMENT ON COLUMN etl_admin.etl_run.error_message IS '错误信息';
COMMENT ON COLUMN etl_admin.etl_run.extra IS '额外信息 (JSON)';