Files
feiqiu-ETL/tmp/etl_billiards_misc/tmp & Delete/schema_v2.sql
2025-12-09 05:43:04 +08:00

1773 lines
120 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.
-- Data warehouse schema for the entertainment chain (ODS -> DWD -> DWS)
-- ASCII only to keep cross-platform friendly.
DROP SCHEMA IF EXISTS billiards_ods CASCADE;
CREATE SCHEMA IF NOT EXISTS billiards_ods;
CREATE SCHEMA IF NOT EXISTS billiards_dwd;
CREATE SCHEMA IF NOT EXISTS billiards_dws;
-- ---------- ODS (raw, lightly typed) ----------
-- Each ODS table keeps the source payload for replay/debug while exposing key fields.
CREATE TABLE IF NOT EXISTS billiards_ods.member_profiles (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
member_id BIGINT NOT NULL,
system_member_id BIGINT,
register_site_id BIGINT,
site_name TEXT,
member_name TEXT,
nickname TEXT,
mobile TEXT,
gender TEXT,
birthday DATE,
register_time TIMESTAMPTZ,
member_type_id BIGINT,
member_type_name TEXT,
member_card_grade_code TEXT,
status TEXT,
user_status TEXT,
balance NUMERIC(18,2),
points NUMERIC(18,2),
growth_value NUMERIC(18,2),
last_visit_time TIMESTAMPTZ,
wechat_id TEXT,
alipay_id TEXT,
member_card_no TEXT,
referrer_member_id BIGINT,
remarks TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, member_id)
);
COMMENT ON TABLE billiards_ods.member_profiles IS '鏉ユ簮锛氫細鍛樻。妗?json -> data.tenantMemberInfos锛涗竴鏉¤褰曚唬琛ㄢ€滅鎴峰唴涓€寮犱細鍛樺崱璐︽埛鈥?;
COMMENT ON COLUMN billiards_ods.member_profiles.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.member_profiles.site_id IS '?register_site_id D锛堟湰鎵逛负鍗曞簵锛?;
COMMENT ON COLUMN billiards_ods.member_profiles.member_id IS '婧愬瓧娈?id锛涚鎴峰唴浼氬憳璐︽埛涓婚敭锛堝搴斿崱璐︽埛/妗ID锛?;
COMMENT ON COLUMN billiards_ods.member_profiles.system_member_id IS '?system_member_id锛涘叏骞冲彴浼氬憳ID锛屽彲璺ㄥ簵鑱氬悎鍚屼竴浜?;
COMMENT ON COLUMN billiards_ods.member_profiles.register_site_id IS '婧愬瓧娈?register_site_id锛涘姙鍗?娉ㄥ唽闂ㄥ簵ID';
COMMENT ON COLUMN billiards_ods.member_profiles.site_name IS '婧愬瓧娈?site_name锛涘姙鍗¢棬搴楀悕绉板揩鐓?;
COMMENT ON COLUMN billiards_ods.member_profiles.member_name IS '?;
COMMENT ON COLUMN billiards_ods.member_profiles.nickname IS '婧愬瓧娈?nickname锛涗細鍛樻樉绀哄悕/鏄电О';
COMMENT ON COLUMN billiards_ods.member_profiles.mobile IS '婧愬瓧娈?mobile锛涗細鍛樻墜鏈哄彿';
COMMENT ON COLUMN billiards_ods.member_profiles.gender IS '婧愭暟鎹湭鎻愪緵锛涢鐣欐€у埆';
COMMENT ON COLUMN billiards_ods.member_profiles.birthday IS '婧愭暟鎹湭鎻愪緵锛涢鐣欑敓鏃?;
COMMENT ON COLUMN billiards_ods.member_profiles.register_time IS '?create_time锛涜处鎴峰垱寤烘椂闂?;
COMMENT ON COLUMN billiards_ods.member_profiles.member_type_id IS '婧愭暟鎹湭鎻愪緵锛涢鐣欎細鍛樼被鍨?绛夌骇ID';
COMMENT ON COLUMN billiards_ods.member_profiles.member_type_name IS '婧愭暟鎹湭鎻愪緵锛涢鐣欎細鍛樼被鍨?绛夌骇鍚嶇О';
COMMENT ON COLUMN billiards_ods.member_profiles.member_card_grade_code IS '婧愬瓧娈?member_card_grade_code锛涘崱绉?绛夌骇缂栫爜锛堝偍鍊煎崱/鍙拌垂鍗?鏈堝崱/娲诲姩鍒哥瓑锛?;
COMMENT ON COLUMN billiards_ods.member_profiles.status IS '?status锛涘崱璐1/?;
COMMENT ON COLUMN billiards_ods.member_profiles.user_status IS '婧愬瓧娈?user_status锛涚敤鎴峰眰鐘舵€侊紙1姝父锛?绂佺敤绛夛級';
COMMENT ON COLUMN billiards_ods.member_profiles.balance IS '婧愭暟鎹湭鎻愪緵锛涢鐣欎綑棰濆揩鐓э紙瀹為檯浣欓鍦ㄥ崱琛級';
COMMENT ON COLUMN billiards_ods.member_profiles.points IS '婧愬瓧娈?point锛涘綋鍓嶇Н鍒嗕綑棰濓紙鏈壒涓?锛?;
COMMENT ON COLUMN billiards_ods.member_profiles.growth_value IS '?growth_value锛涙垚闀垮???;
COMMENT ON COLUMN billiards_ods.member_profiles.last_visit_time IS '婧愭暟鎹湭鎻愪緵锛涢鐣欐渶杩戝埌搴楁椂闂?;
COMMENT ON COLUMN billiards_ods.member_profiles.wechat_id IS 'D';
COMMENT ON COLUMN billiards_ods.member_profiles.alipay_id IS 'ID';
COMMENT ON COLUMN billiards_ods.member_profiles.member_card_no IS '?;
COMMENT ON COLUMN billiards_ods.member_profiles.referrer_member_id IS '婧愬瓧娈?referrer_member_id锛涙帹鑽愪汉浼氬憳ID锛?琛ㄧず鏃狅級';
COMMENT ON COLUMN billiards_ods.member_profiles.remarks IS '婧愭暟鎹湭鎻愪緵锛涢鐣欏娉?;
COMMENT ON COLUMN billiards_ods.member_profiles.source_file IS '?;
COMMENT ON COLUMN billiards_ods.member_profiles.source_endpoint IS '閲囬泦鍏冩暟鎹細鏉ユ簮鎺ュ彛/绔偣';
COMMENT ON COLUMN billiards_ods.member_profiles.fetched_at IS '閲囬泦鍏冩暟鎹細鍏ユ箹鏃堕棿';
COMMENT ON COLUMN billiards_ods.member_profiles.payload IS '鍘熷JSON鍏ㄩ噺瀛樻。锛屼究浜庨噸鏀?瀹¤';
CREATE TABLE IF NOT EXISTS billiards_ods.member_stored_value_cards (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
card_id BIGINT NOT NULL,
member_id BIGINT,
tenant_member_id BIGINT,
card_type_id BIGINT,
card_type_name TEXT,
card_no TEXT,
card_physics_type TEXT,
card_balance NUMERIC(18,2),
denomination NUMERIC(18,2),
discount_rate NUMERIC(8,4),
table_discount NUMERIC(18,2),
goods_discount NUMERIC(18,2),
assistant_discount NUMERIC(18,2),
assistant_reward_discount NUMERIC(18,2),
valid_start_date DATE,
valid_end_date DATE,
disable_start_date DATE,
disable_end_date DATE,
last_consume_time TIMESTAMPTZ,
status TEXT,
is_delete BOOLEAN,
activate_time TIMESTAMPTZ,
deactivate_time TIMESTAMPTZ,
register_site_id BIGINT,
issuer_id BIGINT,
issuer_name TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, card_id)
);
COMMENT ON TABLE billiards_ods.member_stored_value_cards IS '鏉ユ簮锛氬偍鍊煎崱鍒楄〃.json -> data.tenantMemberCards锛涘寘鍚偍鍊煎崱/鍙拌垂鍗?鏈堝崱/娲诲姩鍒哥瓑浼氬憳鍗″畾涔変笌浣欓';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.tenant_id IS '婧愬瓧娈?tenant_id锛涚鎴?鍝佺墝ID';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.site_id IS '婧愬瓧娈?register_site_id锛涘紑鍗¢棬搴桰D';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_id IS '婧愬瓧娈?id锛涗細鍛樺崱璐︽埛ID';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.member_id IS '婧愬瓧娈?system_member_id锛涘钩鍙颁細鍛業D锛堟湭缁戝畾鏃朵负0锛?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.tenant_member_id IS '?tenant_member_id锛涚ID';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_type_id IS '?card_type_id锛涘崱绉岻D';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_type_name IS '?member_card_type_name锛涘崱绉嶅悕绉?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_no IS '婧愬瓧娈?card_no锛涘疄浣?铏氭嫙鍗″彿锛堟湰鎵逛负绌猴級';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_physics_type IS '婧愬瓧娈?card_physics_type锛涚墿鐞嗗崱绫诲瀷鏋氫妇锛堟湰鎵逛负1锛?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.card_balance IS '?balance锛涘綋鍓嶅崱鍐呬綑棰?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.denomination IS '婧愬瓧娈?denomination锛涢潰棰?鍒濆鍌ㄥ€奸搴?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.discount_rate IS '?table/goods/assistant ';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.table_discount IS '?table_discount锛涘彴璐规姌鎵紝10琛ㄧず涓嶆墦鎶?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.goods_discount IS '婧愬瓧娈?goods_discount锛涘晢鍝佹姌鎵?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.assistant_discount IS '?assistant_discount锛涘姪鏁欐湇鍔?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.assistant_reward_discount IS '婧愬瓧娈?assistant_reward_discount锛涘姪鏁欏鍔遍噾鎶樻墸';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.valid_start_date IS '婧愬瓧娈?start_time锛涘崱鏈夋晥鏈熻捣';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.valid_end_date IS '婧愬瓧娈?end_time锛涘崱鏈夋晥鏈熸';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.disable_start_date IS '婧愬瓧娈?disable_start_time锛涘仠鐢ㄥ紑濮嬫椂闂达紙鏈壒榛樿0001-01-01锛?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.disable_end_date IS '?disable_end_time锛涘仠鐢ㄧ粨鏉熸椂闂?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.last_consume_time IS '婧愬瓧娈?last_consume_time锛涙渶杩戞秷璐规椂闂?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.status IS '?status锛涘崱鐘舵1?/';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.is_delete IS '?is_delete锛涢';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.activate_time IS '?create_time锛涘紑鍗?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.deactivate_time IS '婧愭暟鎹湭鎻愪緵锛涢鐣欐敞閿€/鍋滅敤鏃堕棿';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.register_site_id IS '婧愬瓧娈?register_site_id锛涘紑鍗¢棬搴桰D';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.issuer_id IS '婧愭暟鎹湭鎻愪緵锛涢鐣欏紑鍗℃搷浣滀汉ID';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.issuer_name IS '婧愭暟鎹湭鎻愪緵锛涢鐣欏紑鍗℃搷浣滀汉鍚嶇О';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.member_stored_value_cards.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.member_balance_changes (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
change_id BIGINT NOT NULL,
member_id BIGINT,
tenant_member_id BIGINT,
tenant_member_card_id BIGINT,
member_name TEXT,
member_mobile TEXT,
change_amount NUMERIC(18,2),
balance_before NUMERIC(18,2),
balance_after NUMERIC(18,2),
change_type INT,
payment_method INT,
refund_amount NUMERIC(18,2),
relate_id BIGINT,
register_site_id BIGINT,
register_site_name TEXT,
pay_site_name TEXT,
remark TEXT,
operator_id BIGINT,
operator_name TEXT,
change_time TIMESTAMPTZ,
is_deleted BOOLEAN DEFAULT FALSE,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, change_id)
);
COMMENT ON TABLE billiards_ods.goods_stock_movements IS 'Source: 1.json -> data.queryDeliveryRecordsList';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.tenant_id IS 'source: queryDeliveryRecordsList.tenantId; tenant/brand id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.site_id IS 'source: queryDeliveryRecordsList.siteId; store id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.change_id IS 'source: queryDeliveryRecordsList.siteGoodsStockId; stock change record id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.site_goods_id IS 'source: queryDeliveryRecordsList.siteGoodsId; site goods id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.goods_id IS 'not present in export; reserved for tenant goods id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.stock_type IS 'source: queryDeliveryRecordsList.stockType; stock change type';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.change_amount IS 'source: queryDeliveryRecordsList.changeNum; change amount (primary unit)';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.before_stock IS 'source: queryDeliveryRecordsList.startNum; stock before change';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.after_stock IS 'source: queryDeliveryRecordsList.endNum; stock after change';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.change_amount_alt IS 'source: queryDeliveryRecordsList.changeNumA; alt unit change amount';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.before_stock_alt IS 'source: queryDeliveryRecordsList.startNumA; alt unit stock before';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.after_stock_alt IS 'source: queryDeliveryRecordsList.endNumA; alt unit stock after';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.change_type IS 'source: queryDeliveryRecordsList.stockType; stock change type enum';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.relate_id IS 'not present in export; reserved for related business id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.unit IS 'source: queryDeliveryRecordsList.unit; unit name';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.price IS 'source: queryDeliveryRecordsList.price; unit price';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.goods_category_id IS 'source: queryDeliveryRecordsList.goodsCategoryId; category id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.goods_second_category_id IS 'source: queryDeliveryRecordsList.goodsSecondCategoryId; second category id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.remark IS 'source: queryDeliveryRecordsList.remark; remark';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.operator_id IS 'not present in export; reserved for operator id';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.operator_name IS 'source: queryDeliveryRecordsList.operatorName; operator name';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.change_time IS 'source: queryDeliveryRecordsList.createTime; change time';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.goods_stock_movements.payload IS 'raw JSON payload for replay/debug';
COMMENT ON TABLE billiards_ods.member_balance_changes IS '?json -> data.tenantMemberCardLogs锛涜';
COMMENT ON COLUMN billiards_ods.member_balance_changes.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.member_balance_changes.site_id IS '?site_id锛涘彂鐢熷彉鍔ㄧ殑闂ㄥ簵ID锛?/?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.change_id IS '婧愬瓧娈?id锛涗綑棰濆彉鏇磋褰曚富閿?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.member_id IS '?system_member_id锛涘钩鍙颁細鍛業D';
COMMENT ON COLUMN billiards_ods.member_balance_changes.tenant_member_id IS '?tenant_member_id锛涚ID';
COMMENT ON COLUMN billiards_ods.member_balance_changes.tenant_member_card_id IS '?tenant_member_card_id锛涗細鍛樺崱璐ID';
COMMENT ON COLUMN billiards_ods.member_balance_changes.member_name IS '?memberName锛涗細鍛樺?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.member_mobile IS '婧愬瓧娈?memberMobile锛涗細鍛樻墜鏈哄彿蹇収';
COMMENT ON COLUMN billiards_ods.member_balance_changes.change_amount IS '婧愬瓧娈?account_data锛涙湰娆″彉鍔ㄩ噾棰濓紝姝姞璐熷噺';
COMMENT ON COLUMN billiards_ods.member_balance_changes.balance_before IS '婧愬瓧娈?before锛涘彉鍔ㄥ墠浣欓';
COMMENT ON COLUMN billiards_ods.member_balance_changes.balance_after IS '婧愬瓧娈?after锛涘彉鍔ㄥ悗浣欓';
COMMENT ON COLUMN billiards_ods.member_balance_changes.change_type IS '婧愬瓧娈?from_type锛涘彉鍔ㄦ潵婧愮被鍨嬫灇涓?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.payment_method IS '?payment_method锛涙敮浠樻柟寮忔灇涓?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.refund_amount IS '婧愬瓧娈?refund_amount锛涢€€娆鹃噾棰濓紙鏍锋湰涓?锛?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.relate_id IS '?relate_id锛涘叧鑱斾笟鍔D锛堝厖鍊?/';
COMMENT ON COLUMN billiards_ods.member_balance_changes.register_site_id IS '?register_site_id锛涘姙鍗D';
COMMENT ON COLUMN billiards_ods.member_balance_changes.register_site_name IS '?registerSiteName锛涘姙鍗?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.pay_site_name IS '婧愬瓧娈?paySiteName锛涙湰娆″彂鐢熼棬搴楀悕绉?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.remark IS '?remark锛涘?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.operator_id IS '婧愬瓧娈?operator_id锛涙搷浣滃憳ID';
COMMENT ON COLUMN billiards_ods.member_balance_changes.operator_name IS '婧愬瓧娈?operator_name锛涙搷浣滃憳鍚嶇О';
COMMENT ON COLUMN billiards_ods.member_balance_changes.change_time IS '婧愬瓧娈?create_time锛涘彉鍔ㄦ椂闂?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.is_deleted IS '?is_delete锛涢';
COMMENT ON COLUMN billiards_ods.member_balance_changes.source_file IS '?;
COMMENT ON COLUMN billiards_ods.member_balance_changes.source_endpoint IS '閲囬泦鍏冩暟鎹細鏉ユ簮鎺ュ彛/绔偣';
COMMENT ON COLUMN billiards_ods.member_balance_changes.fetched_at IS '閲囬泦鍏冩暟鎹細鍏ユ箹鏃堕棿';
COMMENT ON COLUMN billiards_ods.member_balance_changes.payload IS '鍘熷JSON鍏ㄩ噺瀛樻。锛屼究浜庨噸鏀?瀹¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_recharge_record (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
recharge_id BIGINT NOT NULL,
member_id BIGINT,
recharge_amount NUMERIC(18,2),
gift_amount NUMERIC(18,2),
pay_method INT,
pay_trade_no TEXT,
order_trade_no TEXT,
recharge_time TIMESTAMPTZ,
status TEXT,
operator_id BIGINT,
operator_name TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, recharge_id)
);
COMMENT ON TABLE billiards_ods.ods_recharge_record IS '鏉ユ簮锛氬厖鍊艰褰?json -> data.settleList[].settleList锛涙部鐢ㄧ粨绠楀崟妯″瀷鐨勫厖鍊兼祦姘?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.tenant_id IS '?tenantId锛涚?ID';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.site_id IS '?siteId锛涘厖鍊煎彂鐢熼棬搴?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.recharge_id IS '婧愬瓧娈?id锛涘厖鍊艰褰旾D';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.member_id IS '婧愬瓧娈?memberId锛涗細鍛業D锛堝彲涓?琛ㄧず鏈粦浼氬憳锛?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.recharge_amount IS '?payAmount锛涙湰娆?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.gift_amount IS '婧愬瓧娈?giftCardAmount锛涜禒閫侀噾棰濓紙鏍锋湰涓?锛?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.pay_method IS '?paymentMethod锛涙敮浠樻柟寮忔灇涓?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.pay_trade_no IS '婧愭暟鎹湭缁欙紱棰勭暀澶栭儴浜ゆ槗鍙?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.order_trade_no IS '?settleRelateId 彿';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.recharge_time IS '?payTime锛涙敮浠樻椂闂?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.status IS '婧愬瓧娈?settleStatus锛涘厖鍊肩姸鎬侊紙2鎴愬姛绛夛級';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.operator_id IS '婧愬瓧娈?operatorId锛涙搷浣滃憳ID';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.operator_name IS '婧愬瓧娈?operatorName锛涙搷浣滃憳鍚嶇О';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_recharge_record.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_recharge_record.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_product (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_code TEXT,
category_id BIGINT,
category_name TEXT,
goods_second_category_id BIGINT,
unit TEXT,
price NUMERIC(18,2),
cost_price NUMERIC(18,2),
market_price NUMERIC(18,2),
goods_state TEXT,
goods_cover TEXT,
goods_bar_code TEXT,
able_discount BOOLEAN,
is_delete BOOLEAN,
status TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, goods_id)
);
COMMENT ON TABLE billiards_ods.ods_product IS '?json -> data.tenantGoodsList锛涚';
COMMENT ON COLUMN billiards_ods.ods_product.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.ods_product.site_id IS '?;
COMMENT ON COLUMN billiards_ods.ods_product.goods_id IS '婧愬瓧娈?id锛涚鎴峰晢鍝両D';
COMMENT ON COLUMN billiards_ods.ods_product.goods_name IS '婧愬瓧娈?goods_name锛涘晢鍝佸悕绉?;
COMMENT ON COLUMN billiards_ods.ods_product.goods_code IS '?commodityCode/commodity_code锛涘唴閮ㄧ紪鐮?';
COMMENT ON COLUMN billiards_ods.ods_product.category_id IS '?goods_category_id锛涗竴绾у垎绫籌D';
COMMENT ON COLUMN billiards_ods.ods_product.category_name IS '?categoryName锛涗竴绾у垎绫诲悕绉?;
COMMENT ON COLUMN billiards_ods.ods_product.goods_second_category_id IS '婧愬瓧娈?goods_second_category_id锛涗簩绾у垎绫籌D';
COMMENT ON COLUMN billiards_ods.ods_product.unit IS '婧愬瓧娈?unit锛涜閲忓崟浣?;
COMMENT ON COLUMN billiards_ods.ods_product.price IS ' market_price/min_discount_price ';
COMMENT ON COLUMN billiards_ods.ods_product.cost_price IS '?cost_price锛涙垚鏈';
COMMENT ON COLUMN billiards_ods.ods_product.market_price IS '?market_price锛涘競鍦?';
COMMENT ON COLUMN billiards_ods.ods_product.goods_state IS '?goods_state锛涗笂鏋剁姸鎬?;
COMMENT ON COLUMN billiards_ods.ods_product.goods_cover IS '婧愬瓧娈?goods_cover锛涘晢鍝佸浘鐗嘦RL';
COMMENT ON COLUMN billiards_ods.ods_product.goods_bar_code IS '婧愬瓧娈?goods_bar_code锛涙潯鐮?;
COMMENT ON COLUMN billiards_ods.ods_product.able_discount IS '?able_discount锛涙槸鍚';
COMMENT ON COLUMN billiards_ods.ods_product.is_delete IS '?is_delete锛涢';
COMMENT ON COLUMN billiards_ods.ods_product.status IS '?goods_state ?;
COMMENT ON COLUMN billiards_ods.ods_product.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_product.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_product.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_product.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_store_product (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_id BIGINT,
goods_name TEXT,
category_id BIGINT,
category_name TEXT,
unit TEXT,
sale_price NUMERIC(18,2),
cost_price NUMERIC(18,2),
sale_num NUMERIC(18,2),
stock_a NUMERIC(18,2),
stock NUMERIC(18,2),
provisional_total_cost NUMERIC(18,2),
total_purchase_cost NUMERIC(18,2),
batch_stock_quantity NUMERIC(18,2),
goods_state TEXT,
status TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, site_goods_id)
);
COMMENT ON TABLE billiards_ods.ods_store_product IS '?.json -> data.orderGoodsList锛涢棬搴楃淮搴?;
COMMENT ON COLUMN billiards_ods.ods_store_product.tenant_id IS '婧愬瓧娈?tenant_id锛涚鎴?鍝佺墝ID';
COMMENT ON COLUMN billiards_ods.ods_store_product.site_id IS '婧愬瓧娈?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.ods_store_product.site_goods_id IS '婧愬瓧娈?id锛涢棬搴楀晢鍝両D';
COMMENT ON COLUMN billiards_ods.ods_store_product.goods_id IS '婧愬瓧娈?tenant_goods_id锛涚鎴风骇鍟嗗搧ID';
COMMENT ON COLUMN billiards_ods.ods_store_product.goods_name IS '婧愬瓧娈?goods_name锛涘晢鍝佸悕绉?;
COMMENT ON COLUMN billiards_ods.ods_store_product.category_id IS '?goods_category_id锛涘垎绫籌D';
COMMENT ON COLUMN billiards_ods.ods_store_product.category_name IS '?twoCategoryName/oneCategoryName锛涘垎绫诲悕绉板揩鐓?;
COMMENT ON COLUMN billiards_ods.ods_store_product.unit IS '婧愬瓧娈?unit锛涜閲忓崟浣?;
COMMENT ON COLUMN billiards_ods.ods_store_product.sale_price IS '?sale_price锛涢攢鍞';
COMMENT ON COLUMN billiards_ods.ods_store_product.cost_price IS '?cost_price锛涙垚鏈';
COMMENT ON COLUMN billiards_ods.ods_store_product.sale_num IS '?sale_num锛涚疮璁?;
COMMENT ON COLUMN billiards_ods.ods_store_product.stock_a IS '婧愬瓧娈?stock_A锛涘鐢ㄥ簱瀛樻暟閲?;
COMMENT ON COLUMN billiards_ods.ods_store_product.stock IS '?stock锛涘綋鍓嶅簱瀛?;
COMMENT ON COLUMN billiards_ods.ods_store_product.provisional_total_cost IS '婧愬瓧娈?provisional_total_cost锛涙殏浼板簱瀛樻垚鏈?;
COMMENT ON COLUMN billiards_ods.ods_store_product.total_purchase_cost IS '?total_purchase_cost锛涜繘璐ф?;
COMMENT ON COLUMN billiards_ods.ods_store_product.batch_stock_quantity IS '婧愬瓧娈?batch_stock_quantity锛涙壒娆″簱瀛樻暟閲?;
COMMENT ON COLUMN billiards_ods.ods_store_product.goods_state IS '?goods_state锛涘晢鍝佺姸鎬?;
COMMENT ON COLUMN billiards_ods.ods_store_product.status IS '婧愬瓧娈?enable_status锛涗笂涓嬫灦鐘舵€?;
COMMENT ON COLUMN billiards_ods.ods_store_product.source_file IS '?;
COMMENT ON COLUMN billiards_ods.ods_store_product.source_endpoint IS '閲囬泦鍏冩暟鎹細鏉ユ簮鎺ュ彛/绔偣';
COMMENT ON COLUMN billiards_ods.ods_store_product.fetched_at IS '閲囬泦鍏冩暟鎹細鍏ユ箹鏃堕棿';
COMMENT ON COLUMN billiards_ods.ods_store_product.payload IS '鍘熷JSON鍏ㄩ噺瀛樻。锛屼究浜庨噸鏀?瀹¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_store_sale_item (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
sale_item_id BIGINT NOT NULL,
order_goods_id BIGINT,
order_trade_no TEXT,
order_settle_id BIGINT,
site_goods_id BIGINT,
goods_id BIGINT,
goods_name TEXT,
category_id BIGINT,
quantity NUMERIC(18,4),
unit_price NUMERIC(18,2),
original_amount NUMERIC(18,2),
discount_amount NUMERIC(18,2),
final_amount NUMERIC(18,2),
is_gift BOOLEAN DEFAULT FALSE,
sale_time TIMESTAMPTZ,
member_id BIGINT,
salesman_id BIGINT,
operator_id BIGINT,
is_refunded BOOLEAN DEFAULT FALSE,
discount_price NUMERIC(18,2),
cost_money NUMERIC(18,2),
coupon_deduct_amount NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
point_discount_money NUMERIC(18,2),
point_discount_cost NUMERIC(18,2),
sales_type TEXT,
goods_remark TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, sale_item_id)
);
COMMENT ON TABLE billiards_ods.ods_store_sale_item IS '鏉ユ簮锛氶棬搴楀晢鍝侀攢鍞褰?json -> data.orderGoodsLedgers锛涘晢鍝佹槑缁嗘祦姘?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.site_id IS '?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.sale_item_id IS '?id锛涘晢鍝佹槑缁嗘祦姘碔D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.order_goods_id IS '?order_goods_id锛涗笂娓歌D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.order_trade_no IS '?order_trade_no锛涗笟鍔¤彿';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.order_settle_id IS '?order_settle_id锛涚粨绠楀崟ID';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.site_goods_id IS '?site_goods_id锛涢棬搴楀晢鍝両D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.goods_id IS '?tenant_goods_id锛涚ID';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.goods_name IS '?ledger_name锛涘晢鍝佸悕绉板揩鐓?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.category_id IS '婧愬瓧娈?tenant_goods_category_id锛涘晢鍝佸垎绫籌D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.quantity IS '婧愬瓧娈?ledger_count锛涢攢鍞暟閲?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.unit_price IS '?ledger_unit_price锛涚粨绠楀崟浠?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.original_amount IS '婧愬瓧娈?ledger_amount锛涘師濮嬮噾棰濓紙鏈墸鍑忥級';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.discount_amount IS '婧愬瓧娈?discount_money锛涙姌鎵噾棰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.final_amount IS '?real_goods_money锛涙姌鍚庡疄鏀堕噾棰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.is_gift IS '鐢?sales_type/ledger_status 鎺ㄥ锛涜禒閫?閫€璐у満鏅爣璁?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.sale_time IS '?create_time锛涢攢鍞?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.member_id IS '婧愭暟鎹湭缁欙紱棰勭暀浼氬憳ID';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.salesman_id IS '婧愬瓧娈?salesman_user_id锛涢攢鍞憳ID';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.operator_id IS '婧愬瓧娈?operator_id锛涙敹閾?鎿嶄綔鍛業D';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.is_refunded IS '鐢?returns_number>0 鎴?ledger_status 鍒ゆ柇锛涢€€璐ф爣璁?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.discount_price IS '?discount_price锛涙姌鍚庡崟浠凤紙濡傛湁锛?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.cost_money IS '婧愬瓧娈?cost_money锛涙垚鏈噾棰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.coupon_deduct_amount IS '?coupon_deduct_money + option_coupon_deduct_money锛涘埜鎶垫墸閲戦';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.member_discount_amount IS '?member_discount_amount锛涗細鍛樻姌鎵噾棰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.point_discount_money IS '婧愬瓧娈?point_discount_money锛涚Н鍒嗘姷鎵噾棰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.point_discount_cost IS '?point_discount_money_cost锛涚Н鍒嗘姷鎵垚鏈?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.sales_type IS '婧愬瓧娈?sales_type锛涢攢鍞被鍨嬫灇涓?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.goods_remark IS '?goods_remark锛涘晢鍝佸?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_store_sale_item.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_table_info (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
table_id BIGINT NOT NULL,
table_code TEXT,
table_name TEXT,
table_type TEXT,
area_name TEXT,
site_table_area_id BIGINT,
tenant_table_area_id BIGINT,
table_price NUMERIC(18,2),
table_status TEXT,
audit_status INT,
show_status INT,
light_status INT,
virtual_table BOOLEAN,
is_rest_area BOOLEAN,
charge_free BOOLEAN,
table_cloth_use_time INT,
table_cloth_use_cycle INT,
status TEXT,
created_time TIMESTAMPTZ,
updated_time TIMESTAMPTZ,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, table_id)
);
COMMENT ON TABLE billiards_ods.ods_table_info IS '?json -> data.siteTables锛涢棬搴楃悆妗?';
COMMENT ON COLUMN billiards_ods.ods_table_info.tenant_id IS '';
COMMENT ON COLUMN billiards_ods.ods_table_info.site_id IS '?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_id IS '?id锛涚悆妗?ID';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_code IS '彿';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_name IS '?table_name锛涙?О';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_type IS '';
COMMENT ON COLUMN billiards_ods.ods_table_info.area_name IS '?areaName锛涙墍灞炲尯鍩熷悕绉?;
COMMENT ON COLUMN billiards_ods.ods_table_info.site_table_area_id IS '婧愬瓧娈?site_table_area_id锛涢棬搴楀尯鍩烮D';
COMMENT ON COLUMN billiards_ods.ods_table_info.tenant_table_area_id IS '婧愭暟鎹湭缁欙紱棰勭暀绉熸埛绾у尯鍩烮D';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_price IS '婧愬瓧娈?table_price锛涘熀纭€鍙拌垂鍗曚环';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_status IS '婧愬瓧娈?table_status锛涘綋鍓嶆鐘舵€?;
COMMENT ON COLUMN billiards_ods.ods_table_info.audit_status IS '?audit_status锛涘?;
COMMENT ON COLUMN billiards_ods.ods_table_info.show_status IS '婧愬瓧娈?show_status锛涙樉绀虹姸鎬?;
COMMENT ON COLUMN billiards_ods.ods_table_info.light_status IS '?light_status锛涚伅鎺х姸鎬?;
COMMENT ON COLUMN billiards_ods.ods_table_info.virtual_table IS '婧愬瓧娈?virtual_table锛涙槸鍚﹁櫄鎷熸';
COMMENT ON COLUMN billiards_ods.ods_table_info.is_rest_area IS '婧愬瓧娈?is_rest_area锛涙槸鍚︿紤鎭尯';
COMMENT ON COLUMN billiards_ods.ods_table_info.charge_free IS '婧愬瓧娈?charge_free锛涙槸鍚﹀厤璐?;
COMMENT ON COLUMN billiards_ods.ods_table_info.table_cloth_use_time IS '?table_cloth_use_time锛涘彴鍛';
COMMENT ON COLUMN billiards_ods.ods_table_info.table_cloth_use_cycle IS '?table_cloth_use_Cycle锛涘彴鍛洿';
COMMENT ON COLUMN billiards_ods.ods_table_info.status IS '?table_status/show_status ';
COMMENT ON COLUMN billiards_ods.ods_table_info.created_time IS '?create_time锛涘垱寤烘椂闂?;
COMMENT ON COLUMN billiards_ods.ods_table_info.updated_time IS '婧愭暟鎹湭缁欙紱棰勭暀鏇存柊鏃堕棿';
COMMENT ON COLUMN billiards_ods.ods_table_info.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_table_info.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_table_info.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_table_info.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.table_fee_transactions_log (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
ledger_id BIGINT NOT NULL,
table_id BIGINT,
table_name TEXT,
order_trade_no TEXT,
order_settle_id BIGINT,
start_time TIMESTAMPTZ,
end_time TIMESTAMPTZ,
duration_seconds INT,
billing_unit_price NUMERIC(18,4),
billing_count NUMERIC(18,4),
original_table_fee NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
coupon_discount_amount NUMERIC(18,2),
manual_discount_amount NUMERIC(18,2),
service_fee NUMERIC(18,2),
final_table_fee NUMERIC(18,2),
member_id BIGINT,
operator_id BIGINT,
salesman_id BIGINT,
is_canceled BOOLEAN DEFAULT FALSE,
cancel_time TIMESTAMPTZ,
site_table_area_id BIGINT,
tenant_table_area_id BIGINT,
site_table_area_name TEXT,
is_single_order BOOLEAN,
used_card_amount NUMERIC(18,2),
adjust_amount NUMERIC(18,2),
coupon_promotion_amount NUMERIC(18,2),
service_money NUMERIC(18,2),
mgmt_fee NUMERIC(18,2),
fee_total NUMERIC(18,2),
real_table_use_seconds INT,
last_use_time TIMESTAMPTZ,
ledger_start_time TIMESTAMPTZ,
ledger_end_time TIMESTAMPTZ,
ledger_status INT,
start_use_time TIMESTAMPTZ,
add_clock_seconds INT,
status TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, ledger_id)
);
COMMENT ON TABLE billiards_ods.ods_assistant_service_log IS 'Source: .json -> data.orderAssistantDetails';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.tenant_id IS 'source: orderAssistantDetails.tenant_id; tenant/brand id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.site_id IS 'source: orderAssistantDetails.site_id; store id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.ledger_id IS 'source: orderAssistantDetails.id; assistant service ledger id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.assistant_id IS 'source: orderAssistantDetails.site_assistant_id; assistant id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.assistant_name IS 'source: orderAssistantDetails.assistantName; assistant name';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.service_type IS 'source: orderAssistantDetails.order_assistant_type; service type code';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.order_trade_no IS 'source: orderAssistantDetails.order_trade_no; business order number';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.order_settle_id IS 'source: orderAssistantDetails.order_settle_id; settlement id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.start_time IS 'source: orderAssistantDetails.start_use_time; service start time';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.end_time IS 'source: orderAssistantDetails.ledger_end_time; service end time';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.duration_seconds IS 'source: orderAssistantDetails.real_use_seconds; actual service seconds';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.original_fee IS 'source: orderAssistantDetails.ledger_amount; amount before discounts';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.member_discount_amount IS 'source: orderAssistantDetails.member_discount_amount; member discount amount';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.manual_discount_amount IS 'source: orderAssistantDetails.manual_discount_amount; manual discount';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.coupon_discount_amount IS 'source: orderAssistantDetails.coupon_deduct_money; coupon deduction';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.final_fee IS 'source: orderAssistantDetails.service_money; final assistant fee';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.member_id IS 'source: orderAssistantDetails.system_member_id; member id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.operator_id IS 'source: orderAssistantDetails.operator_id; operator id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.salesman_id IS 'source: orderAssistantDetails.salesman_user_id; salesperson id';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.is_canceled IS 'derived; set when is_delete/is_trash indicates cancellation';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.cancel_time IS 'not present in export; reserved for cancel time';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.skill_grade IS 'source: orderAssistantDetails.skill_grade; skill grade score';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.service_grade IS 'source: orderAssistantDetails.service_grade; service grade score';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.composite_grade IS 'source: orderAssistantDetails.composite_grade; composite score';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.overall_score IS 'source: orderAssistantDetails.sum_grade; overall score sum';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.status IS 'source: orderAssistantDetails.ledger_status/grade_status; status flag';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.ods_assistant_service_log.payload IS 'raw JSON payload for replay/debug';
COMMENT ON TABLE billiards_ods.table_fee_transactions_log IS '?json -> data.siteTableUseDetailsList锛涘彴璐硅?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.tenant_id IS '婧愬瓧娈?tenant_id锛涚鎴?鍝佺墝ID';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.site_id IS '婧愬瓧娈?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.ledger_id IS '婧愬瓧娈?id锛涘彴璐硅处鍗旾D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.table_id IS '婧愬瓧娈?site_table_id锛涚悆妗孖D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.table_name IS '婧愬瓧娈?ledger_name锛涙鍚嶅揩鐓?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.order_trade_no IS '?order_trade_no锛涗笟鍔¤彿';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.order_settle_id IS '?order_settle_id锛涚粨绠楀崟ID';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.start_time IS '?ledger_start_time锛涜?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.end_time IS '婧愬瓧娈?ledger_end_time锛涜璐圭粨鏉熸椂闂?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.duration_seconds IS '?ledger_count锛涜??;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.billing_unit_price IS '婧愬瓧娈?ledger_unit_price锛涜璐瑰崟浠?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.billing_count IS '?ledger_count锛涜?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.original_table_fee IS '婧愬瓧娈?ledger_amount锛涙姌鎵墠閲戦';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.member_discount_amount IS '婧愬瓧娈?member_discount_amount锛涗細鍛樻姌鎵?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.coupon_discount_amount IS '?coupon_promotion_amount锛涘埜鎶垫墸';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.manual_discount_amount IS '?adjust_amount锛涙墜宸ヤ紭鎯?';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.service_fee IS '?service_money锛涙湇鍔¤';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.final_table_fee IS '?real_table_charge_money锛涙渶缁堝彴璐?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.member_id IS '婧愬瓧娈?member_id锛涗細鍛業D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.operator_id IS '婧愬瓧娈?operator_id锛涙搷浣滃憳ID';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.salesman_id IS '婧愬瓧娈?salesman_user_id锛涢攢鍞憳ID';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.is_canceled IS '鐢?ledger_status/is_delete 鎺ㄥ锛涙槸鍚﹀彇娑?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.cancel_time IS '';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.site_table_area_id IS '?site_table_area_id锛涢棬搴楀尯鍩烮D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.tenant_table_area_id IS '?tenant_table_area_id锛涚D';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.site_table_area_name IS '?site_table_area_name锛涘尯鍩熷悕绉?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.is_single_order IS '婧愬瓧娈?is_single_order锛涘崟鍙?骞跺崟鏍囪';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.used_card_amount IS '婧愬瓧娈?used_card_amount锛涘崱鏀粯閲戦';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.adjust_amount IS '婧愬瓧娈?adjust_amount锛涜皟鏁撮噾棰?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.coupon_promotion_amount IS '?coupon_promotion_amount锛涗紭鎯犲埜淇冮攢閲戦';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.service_money IS '?service_money锛涙湇鍔¤';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.mgmt_fee IS '?mgmt_fee锛涚';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.fee_total IS '?fee_total锛涙';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.real_table_use_seconds IS '?real_table_use_seconds锛涘疄闄呬娇鐢ㄧ?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.last_use_time IS '婧愬瓧娈?last_use_time锛涙渶杩戜娇鐢ㄧ粨鏉熸椂闂?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.ledger_start_time IS '?ledger_start_time锛涜?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.ledger_end_time IS '婧愬瓧娈?ledger_end_time锛涜璐圭粨鏉?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.ledger_status IS '?ledger_status锛涜处鍗曠姸鎬?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.start_use_time IS '婧愬瓧娈?start_use_time锛涘疄闄呭紑濮嬬敤鍙版椂闂?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.add_clock_seconds IS '?add_clock_seconds锛涢?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.status IS '閫氱敤鐘舵€侊紱缁撳悎 ledger_status/is_delete 鍒ゅ畾';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.table_fee_transactions_log.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_table_fee_adjust (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
adjust_id BIGINT NOT NULL,
ledger_id BIGINT,
order_trade_no TEXT,
discount_amount NUMERIC(18,2),
reason TEXT,
operator_id BIGINT,
operator_name TEXT,
created_at TIMESTAMPTZ,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, adjust_id)
);
COMMENT ON TABLE billiards_ods.ods_table_fee_adjust IS '?json -> data.taiFeeAdjustInfos锛涘彴璐规墜宸ユ姌鎵?';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.site_id IS '?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.adjust_id IS '?id锛涘彴璐规姌鎵D';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.ledger_id IS '?order_settle_id锛涘叧鑱斿彴璐硅处鍗?ID';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.order_trade_no IS '?order_trade_no锛涗笟鍔¤彿';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.discount_amount IS '?ledger_amount锛涙姌鎵噾棰?;
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.reason IS '婧愬瓧娈?adjust_type/applicant_* 缁勫悎锛涜皟鏁村師鍥狅紙鏄庣粏闇€缁撳悎 payload锛?;
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.operator_id IS '?operator_id锛涙搷浣滃憳ID';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.operator_name IS '?operator_name锛涙搷浣滃憳鍚嶇О';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.created_at IS '?create_time锛涘垱寤烘椂闂?;
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_table_fee_adjust.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.assistant_accounts_master (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
assistant_id BIGINT NOT NULL,
assistant_name TEXT,
mobile TEXT,
assistant_no INT,
team_id BIGINT,
team_name TEXT,
group_id BIGINT,
group_name TEXT,
job_num TEXT,
entry_type TEXT,
leave_status TEXT,
assistant_status TEXT,
allow_cx BOOLEAN,
status TEXT,
hired_date DATE,
left_date DATE,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, assistant_id)
);
COMMENT ON TABLE billiards_ods.assistant_accounts_master IS 'Source: 彿.json -> data.assistantInfos';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.tenant_id IS 'source: assistantInfos.tenant_id; tenant/brand id';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.site_id IS 'source: assistantInfos.site_id; store id';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.assistant_id IS 'source: assistantInfos.id; assistant account id';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.assistant_name IS 'source: assistantInfos.real_name; assistant real name';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.mobile IS 'source: assistantInfos.mobile; phone number';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.assistant_no IS 'source: assistantInfos.assistant_no; assistant code';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.team_id IS 'source: assistantInfos.team_id; team id';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.team_name IS 'source: assistantInfos.team_name; team name';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.group_id IS 'source: assistantInfos.group_id; group id';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.group_name IS 'source: assistantInfos.group_name; group name';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.job_num IS 'source: assistantInfos.job_num; job number';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.entry_type IS 'source: assistantInfos.entry_type; entry type enum';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.leave_status IS 'source: assistantInfos.leave_status; on-duty/off-duty status';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.assistant_status IS 'source: assistantInfos.assistant_status; account enable flag';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.allow_cx IS 'source: assistantInfos.allow_cx; allow promotion/discount flag';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.status IS 'source: assistantInfos.show_status/work_status; general status flag';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.hired_date IS 'source: assistantInfos.entry_time; hire date';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.left_date IS 'source: assistantInfos.resign_time; resign date';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.assistant_accounts_master.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_assistant_service_log (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
ledger_id BIGINT NOT NULL,
assistant_id BIGINT,
assistant_name TEXT,
service_type TEXT,
order_trade_no TEXT,
order_settle_id BIGINT,
start_time TIMESTAMPTZ,
end_time TIMESTAMPTZ,
duration_seconds INT,
original_fee NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
manual_discount_amount NUMERIC(18,2),
coupon_discount_amount NUMERIC(18,2),
final_fee NUMERIC(18,2),
member_id BIGINT,
operator_id BIGINT,
salesman_id BIGINT,
is_canceled BOOLEAN DEFAULT FALSE,
cancel_time TIMESTAMPTZ,
skill_grade NUMERIC(10,2),
service_grade NUMERIC(10,2),
composite_grade NUMERIC(10,2),
overall_score NUMERIC(10,2),
status TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, ledger_id)
);
CREATE TABLE IF NOT EXISTS billiards_ods.ods_assistant_cancel_log (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
cancel_id BIGINT NOT NULL,
ledger_id BIGINT,
assistant_id BIGINT,
order_trade_no TEXT,
table_id BIGINT,
table_area_id BIGINT,
table_area_name TEXT,
table_name TEXT,
assistant_on INT,
pd_charge_minutes INT,
assistant_abolish_amount NUMERIC(18,2),
reason TEXT,
cancel_time TIMESTAMPTZ,
operator_id BIGINT,
operator_name TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, cancel_id)
);
COMMENT ON TABLE billiards_ods.ods_assistant_cancel_log IS 'Source: .json -> data.abolitionAssistants';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.tenant_id IS 'ingest context; tenant id not explicitly exported in abolitionAssistants';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.site_id IS 'source: abolitionAssistants.siteId; store id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.cancel_id IS 'source: abolitionAssistants.id; abolish record id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.ledger_id IS 'not present; reserved for related ledger id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.assistant_id IS 'not present in export; assistant name only in payload';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.order_trade_no IS 'not present in export; reserved for order number';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.table_id IS 'source: abolitionAssistants.tableId; table id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.table_area_id IS 'source: abolitionAssistants.tableAreaId; table area id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.table_area_name IS 'source: abolitionAssistants.tableArea; table area name';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.table_name IS 'source: abolitionAssistants.tableName; table name';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.assistant_on IS 'source: abolitionAssistants.assistantOn; number of assistants on duty';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.pd_charge_minutes IS 'source: abolitionAssistants.pdChargeMinutes; charged minutes';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.assistant_abolish_amount IS 'source: abolitionAssistants.assistantAbolishAmount; abolish amount';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.reason IS 'source: abolitionAssistants.trashReason; abolish reason';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.cancel_time IS 'source: abolitionAssistants.createTime; abolish time';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.operator_id IS 'not present in export; reserved for operator id';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.operator_name IS 'not present in export; reserved for operator name';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.ods_assistant_cancel_log.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.group_buy_packages (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
package_name TEXT,
table_area_id BIGINT,
table_area_name TEXT,
platform_code TEXT,
status TEXT,
face_price NUMERIC(18,2),
settle_price NUMERIC(18,2),
selling_price NUMERIC(18,2),
duration INT,
valid_from DATE,
valid_to DATE,
start_time TIMESTAMPTZ,
end_time TIMESTAMPTZ,
is_enabled BOOLEAN,
is_delete BOOLEAN,
package_type TEXT,
usable_count INT,
creator_name TEXT,
tenant_table_area_id BIGINT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, package_id)
);
COMMENT ON TABLE billiards_ods.group_buy_packages IS '?json -> data.packageCouponList锛涘洟璐?稿?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.tenant_id IS '婧愬瓧娈?tenant_id锛涚鎴?鍝佺墝ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages.site_id IS '婧愬瓧娈?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.group_buy_packages.package_id IS '婧愬瓧娈?id/package_id锛涘椁愬畾涔塈D';
COMMENT ON COLUMN billiards_ods.group_buy_packages.package_name IS '婧愬瓧娈?package_name锛涘椁愬悕绉?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.table_area_id IS '?table_area_id锛涢ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages.table_area_name IS '?table_area_name锛涢О';
COMMENT ON COLUMN billiards_ods.group_buy_packages.platform_code IS '?groupon_type/system_group_type锛涘钩鍙?';
COMMENT ON COLUMN billiards_ods.group_buy_packages.status IS '?effective_status锛涚敓鏁堢姸鎬?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.face_price IS '婧愬瓧娈?coupon_money锛涘埜闈㈤';
COMMENT ON COLUMN billiards_ods.group_buy_packages.settle_price IS '婧愭暟鎹湭鍗曞垪锛涢鐣欑粨绠椾环';
COMMENT ON COLUMN billiards_ods.group_buy_packages.selling_price IS '婧愬瓧娈?selling_price锛涘敭鍗栦环';
COMMENT ON COLUMN billiards_ods.group_buy_packages.duration IS '婧愬瓧娈?duration锛涙椂闀匡紙绉掞級';
COMMENT ON COLUMN billiards_ods.group_buy_packages.valid_from IS '婧愬瓧娈?start_time锛涙湁鏁堟湡寮€濮?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.valid_to IS '?end_time锛涙湁鏁堟湡缁撴潫';
COMMENT ON COLUMN billiards_ods.group_buy_packages.start_time IS '?start_clock/add_start_clock锛涙瘡鏃ョ敓鏁堣捣鐐?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.end_time IS '婧愬瓧娈?end_clock/add_end_clock锛涙瘡鏃ュけ鏁堢粓鐐?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.is_enabled IS '?is_enabled锛涙槸鍚?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.is_delete IS '婧愬瓧娈?is_delete锛涢€昏緫鍒犻櫎鏍囪';
COMMENT ON COLUMN billiards_ods.group_buy_packages.package_type IS '婧愬瓧娈?type/system_group_type/group_type锛涘椁愮被鍨?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.usable_count IS '?usable_count锛涘彲鐢ㄦ?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.creator_name IS '婧愬瓧娈?creator_name锛涘垱寤轰汉';
COMMENT ON COLUMN billiards_ods.group_buy_packages.tenant_table_area_id IS '婧愬瓧娈?tenant_table_area_id锛涚鎴风骇鍖哄煙ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.group_buy_packages.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.group_buy_packages.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.group_buy_packages.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.group_buy_packages_log (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
usage_id BIGINT NOT NULL,
package_id BIGINT,
coupon_id BIGINT,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
status TEXT,
used_time TIMESTAMPTZ,
deduct_amount NUMERIC(18,2),
settle_price NUMERIC(18,2),
coupon_code TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, usage_id)
);
COMMENT ON TABLE billiards_ods.group_buy_packages_log IS '?json -> data.siteTableUseDetailsList锛涘洟璐';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.site_id IS '?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.usage_id IS '?id锛涙牳閿ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.package_id IS '?promotion_coupon_id锛涘?D';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.coupon_id IS '?order_coupon_id/coupon_origin_id锛涘埜瀹炰緥ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.order_trade_no IS '?order_trade_no锛涗笟鍔¤彿';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.order_settle_id IS '?order_settle_id锛涚粨绠楀崟ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.member_id IS 'ID';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.status IS '?ledger_status锛涙祦姘寸姸鎬?;
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.used_time IS '婧愬瓧娈?create_time锛涙牳閿€鏃堕棿';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.deduct_amount IS '婧愬瓧娈?coupon_money锛涘埜鎶垫墸閲戦';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.settle_price IS '婧愬瓧娈?ledger_amount锛涙湰鏉℃槑缁嗙粨绠楅噾棰?;
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.coupon_code IS '?coupon_code锛涘埜鐮?;
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.group_buy_packages_log.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_platform_coupon_log (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
coupon_id BIGINT NOT NULL,
platform_code TEXT,
verify_code TEXT,
coupon_code TEXT,
coupon_channel TEXT,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
status TEXT,
used_time TIMESTAMPTZ,
deduct_amount NUMERIC(18,2),
settle_price NUMERIC(18,2),
coupon_money NUMERIC(18,2),
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, coupon_id)
);
COMMENT ON TABLE billiards_ods.ods_platform_coupon_log IS '?json锛涘钩鍙板埜鏍搁攢璁板綍';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.tenant_id IS '?tenant_id锛涚?ID';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.site_id IS '?site_id锛涢棬搴桰D';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.coupon_id IS '?id锛涙牳閿ID';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.platform_code IS '?groupon_type锛涘埜骞冲彴/';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.verify_code IS '?verify_id锛涙牳閿?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.coupon_code IS '婧愬瓧娈?coupon_code锛涘埜鐮?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.coupon_channel IS '?coupon_channel锛涢攢鍞?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.order_trade_no IS '婧愬瓧娈?site_order_id锛涘叧鑱旇鍗曞彿';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.order_settle_id IS '婧愭暟鎹湭缁欙紱棰勭暀缁撶畻ID';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.member_id IS '婧愭暟鎹湭缁欙紱棰勭暀浼氬憳ID';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.status IS '婧愬瓧娈?use_status锛涙牳閿€鐘舵€?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.used_time IS '?consume_time锛涙牳閿';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.deduct_amount IS '?coupon_money锛涙姷鎵噾棰?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.settle_price IS '婧愬瓧娈?sale_price锛涚粨绠?閿€鍞环';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.coupon_money IS '婧愬瓧娈?coupon_money锛涘埜闈㈤';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.source_file IS '閲囬泦鍏冩暟鎹細婧愭枃浠惰矾寰?;
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.source_endpoint IS '/';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.fetched_at IS '';
COMMENT ON COLUMN billiards_ods.ods_platform_coupon_log.payload IS 'JSON鍏ㄩ噺瀛樻?¤';
CREATE TABLE IF NOT EXISTS billiards_ods.goods_stock_movements (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
change_id BIGINT NOT NULL,
site_goods_id BIGINT,
goods_id BIGINT,
stock_type TEXT,
change_amount NUMERIC(18,2),
before_stock NUMERIC(18,2),
after_stock NUMERIC(18,2),
change_amount_alt NUMERIC(18,2),
before_stock_alt NUMERIC(18,2),
after_stock_alt NUMERIC(18,2),
change_type TEXT,
relate_id BIGINT,
unit TEXT,
price NUMERIC(18,2),
goods_category_id BIGINT,
goods_second_category_id BIGINT,
remark TEXT,
operator_id BIGINT,
operator_name TEXT,
change_time TIMESTAMPTZ,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, change_id)
);
CREATE TABLE IF NOT EXISTS billiards_ods.ods_inventory_stock (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_id BIGINT,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_second_category_id BIGINT,
range_start_stock NUMERIC(18,2),
range_end_stock NUMERIC(18,2),
range_in NUMERIC(18,2),
range_out NUMERIC(18,2),
range_inventory NUMERIC(18,2),
range_sale NUMERIC(18,2),
range_sale_money NUMERIC(18,2),
current_stock NUMERIC(18,2),
cost_price NUMERIC(18,2),
category_name TEXT,
snapshot_key TEXT NOT NULL DEFAULT 'default',
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, site_goods_id, snapshot_key)
);
COMMENT ON TABLE billiards_ods.ods_inventory_stock IS 'Source: ?json';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.tenant_id IS 'ingest context; tenant id not explicitly exported';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.site_id IS 'ingest context; site id not explicitly exported';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.site_goods_id IS 'source: ?siteGoodsId; site goods id';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.goods_id IS 'not present in export; reserved for tenant goods id';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.goods_name IS 'source: ?goodsName; goods name';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.goods_unit IS 'source: ?goodsUnit; unit';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.goods_category_id IS 'source: ?goodsCategoryId; category id';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.goods_second_category_id IS 'source: ?goodsCategorySecondId; second category id';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_start_stock IS 'source: ?rangeStartStock; period opening stock';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_end_stock IS 'source: ?rangeEndStock; period closing stock';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_in IS 'source: ?rangeIn; inbound qty during period';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_out IS 'source: ?rangeOut; outbound qty during period';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_inventory IS 'source: ?rangeInventory; inventory adjustments during period';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_sale IS 'source: ?rangeSale; sales qty during period';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.range_sale_money IS 'source: ?rangeSaleMoney; sales amount during period';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.current_stock IS 'source: ?currentStock; current stock';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.cost_price IS 'not present in export; reserved for cost price';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.category_name IS 'source: ?categoryName; category name';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.snapshot_key IS 'snapshot label (default ''default'') for periodic loads';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.ods_inventory_stock.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.settlement_records (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
order_settle_id BIGINT NOT NULL,
settle_relate_id BIGINT,
settle_name TEXT,
settle_type INT,
settle_status INT,
member_id BIGINT,
member_name TEXT,
member_phone TEXT,
table_id BIGINT,
consume_money NUMERIC(18,2),
table_charge_money NUMERIC(18,2),
goods_money NUMERIC(18,2),
service_money NUMERIC(18,2),
assistant_pd_money NUMERIC(18,2),
assistant_cx_money NUMERIC(18,2),
pay_amount NUMERIC(18,2),
cash_amount NUMERIC(18,2),
online_amount NUMERIC(18,2),
point_amount NUMERIC(18,2),
coupon_amount NUMERIC(18,2),
card_amount NUMERIC(18,2),
balance_amount NUMERIC(18,2),
refund_amount NUMERIC(18,2),
prepay_money NUMERIC(18,2),
adjust_amount NUMERIC(18,2),
rounding_amount NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
coupon_sale_amount NUMERIC(18,2),
goods_promotion_money NUMERIC(18,2),
assistant_promotion_money NUMERIC(18,2),
point_discount_price NUMERIC(18,2),
point_discount_cost NUMERIC(18,2),
real_goods_money NUMERIC(18,2),
assistant_manual_discount NUMERIC(18,2),
all_coupon_discount NUMERIC(18,2),
is_use_coupon BOOLEAN,
is_use_discount BOOLEAN,
is_activity BOOLEAN,
is_bind_member BOOLEAN,
is_first BOOLEAN,
recharge_card_amount NUMERIC(18,2),
gift_card_amount NUMERIC(18,2),
payment_method INT,
create_time TIMESTAMPTZ,
pay_time TIMESTAMPTZ,
revoke_order_id BIGINT,
revoke_order_name TEXT,
revoke_time TIMESTAMPTZ,
can_be_revoked BOOLEAN,
serial_number TEXT,
sales_man_name TEXT,
sales_man_user_id BIGINT,
order_remark TEXT,
operator_id BIGINT,
operator_name TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, order_settle_id)
);
COMMENT ON TABLE billiards_ods.settlement_records IS 'Source: .json -> data.settleList[].settleList';
COMMENT ON COLUMN billiards_ods.settlement_records.tenant_id IS 'source: settleList.tenantId; tenant/brand id';
COMMENT ON COLUMN billiards_ods.settlement_records.site_id IS 'source: settleList.siteId; store id';
COMMENT ON COLUMN billiards_ods.settlement_records.order_settle_id IS 'source: settleList.id; settlement record id';
COMMENT ON COLUMN billiards_ods.settlement_records.settle_relate_id IS 'source: settleList.settleRelateId; related business/order id';
COMMENT ON COLUMN billiards_ods.settlement_records.settle_name IS 'source: settleList.settleName; settlement name';
COMMENT ON COLUMN billiards_ods.settlement_records.settle_type IS 'source: settleList.settleType; settlement type enum';
COMMENT ON COLUMN billiards_ods.settlement_records.settle_status IS 'source: settleList.settleStatus; settlement status';
COMMENT ON COLUMN billiards_ods.settlement_records.member_id IS 'source: settleList.memberId; member id';
COMMENT ON COLUMN billiards_ods.settlement_records.member_name IS 'source: settleList.memberName; member name';
COMMENT ON COLUMN billiards_ods.settlement_records.member_phone IS 'source: settleList.memberPhone; member phone';
COMMENT ON COLUMN billiards_ods.settlement_records.table_id IS 'source: settleList.tableId; table id';
COMMENT ON COLUMN billiards_ods.settlement_records.consume_money IS 'source: settleList.consumeMoney; total consumption amount';
COMMENT ON COLUMN billiards_ods.settlement_records.table_charge_money IS 'source: settleList.tableChargeMoney; table fee amount';
COMMENT ON COLUMN billiards_ods.settlement_records.goods_money IS 'source: settleList.goodsMoney; goods amount';
COMMENT ON COLUMN billiards_ods.settlement_records.service_money IS 'source: settleList.serviceMoney; service amount';
COMMENT ON COLUMN billiards_ods.settlement_records.assistant_pd_money IS 'source: settleList.assistantPdMoney; assistant accompany amount';
COMMENT ON COLUMN billiards_ods.settlement_records.assistant_cx_money IS 'source: settleList.assistantCxMoney; assistant promotion amount';
COMMENT ON COLUMN billiards_ods.settlement_records.pay_amount IS 'source: settleList.payAmount; payment amount (settled)';
COMMENT ON COLUMN billiards_ods.settlement_records.cash_amount IS 'source: settleList.cashAmount; cash payment amount';
COMMENT ON COLUMN billiards_ods.settlement_records.online_amount IS 'source: settleList.onlineAmount; online payment amount';
COMMENT ON COLUMN billiards_ods.settlement_records.point_amount IS 'source: settleList.pointAmount; amount credited to card/points';
COMMENT ON COLUMN billiards_ods.settlement_records.coupon_amount IS 'source: settleList.couponAmount; coupon deduction';
COMMENT ON COLUMN billiards_ods.settlement_records.card_amount IS 'source: settleList.cardAmount; member card amount';
COMMENT ON COLUMN billiards_ods.settlement_records.balance_amount IS 'source: settleList.balanceAmount; balance payment amount';
COMMENT ON COLUMN billiards_ods.settlement_records.refund_amount IS 'source: settleList.refundAmount; refund amount on this settlement';
COMMENT ON COLUMN billiards_ods.settlement_records.prepay_money IS 'source: settleList.prepayMoney; prepayment amount';
COMMENT ON COLUMN billiards_ods.settlement_records.adjust_amount IS 'source: settleList.adjustAmount; adjustment amount';
COMMENT ON COLUMN billiards_ods.settlement_records.rounding_amount IS 'source: settleList.roundingAmount; rounding write-off amount';
COMMENT ON COLUMN billiards_ods.settlement_records.member_discount_amount IS 'source: settleList.memberDiscountAmount; member discount amount';
COMMENT ON COLUMN billiards_ods.settlement_records.coupon_sale_amount IS 'source: settleList.couponSaleAmount; coupon sale amount';
COMMENT ON COLUMN billiards_ods.settlement_records.goods_promotion_money IS 'source: settleList.goodsPromotionMoney; goods promotion deduction';
COMMENT ON COLUMN billiards_ods.settlement_records.assistant_promotion_money IS 'source: settleList.assistantPromotionMoney; assistant promotion deduction';
COMMENT ON COLUMN billiards_ods.settlement_records.point_discount_price IS 'source: settleList.pointDiscountPrice; points discount amount';
COMMENT ON COLUMN billiards_ods.settlement_records.point_discount_cost IS 'source: settleList.pointDiscountCost; cost of points discount';
COMMENT ON COLUMN billiards_ods.settlement_records.real_goods_money IS 'source: settleList.realGoodsMoney; real goods amount after discount';
COMMENT ON COLUMN billiards_ods.settlement_records.assistant_manual_discount IS 'source: settleList.assistantManualDiscount; manual assistant discount';
COMMENT ON COLUMN billiards_ods.settlement_records.all_coupon_discount IS 'source: settleList.allCouponDiscount; total coupon discount';
COMMENT ON COLUMN billiards_ods.settlement_records.is_use_coupon IS 'source: settleList.isUseCoupon; whether coupon used';
COMMENT ON COLUMN billiards_ods.settlement_records.is_use_discount IS 'source: settleList.isUseDiscount; whether discount used';
COMMENT ON COLUMN billiards_ods.settlement_records.is_activity IS 'source: settleList.isActivity; whether activity applied';
COMMENT ON COLUMN billiards_ods.settlement_records.is_bind_member IS 'source: settleList.isBindMember; whether member bound';
COMMENT ON COLUMN billiards_ods.settlement_records.is_first IS 'source: settleList.isFirst; whether first order flag';
COMMENT ON COLUMN billiards_ods.settlement_records.recharge_card_amount IS 'source: settleList.rechargeCardAmount; recharge card amount';
COMMENT ON COLUMN billiards_ods.settlement_records.gift_card_amount IS 'source: settleList.giftCardAmount; gift card amount';
COMMENT ON COLUMN billiards_ods.settlement_records.payment_method IS 'source: settleList.paymentMethod; payment method code';
COMMENT ON COLUMN billiards_ods.settlement_records.create_time IS 'source: settleList.createTime; creation time';
COMMENT ON COLUMN billiards_ods.settlement_records.pay_time IS 'source: settleList.payTime; pay time';
COMMENT ON COLUMN billiards_ods.settlement_records.revoke_order_id IS 'source: settleList.revokeOrderId; revoke order id';
COMMENT ON COLUMN billiards_ods.settlement_records.revoke_order_name IS 'source: settleList.revokeOrderName; revoke order name';
COMMENT ON COLUMN billiards_ods.settlement_records.revoke_time IS 'source: settleList.revokeTime; revoke time';
COMMENT ON COLUMN billiards_ods.settlement_records.can_be_revoked IS 'source: settleList.canBeRevoked; flag whether revocable';
COMMENT ON COLUMN billiards_ods.settlement_records.serial_number IS 'source: settleList.serialNumber; receipt serial number';
COMMENT ON COLUMN billiards_ods.settlement_records.sales_man_name IS 'source: settleList.salesManName; sales person name';
COMMENT ON COLUMN billiards_ods.settlement_records.sales_man_user_id IS 'source: settleList.salesManUserId; sales person user id';
COMMENT ON COLUMN billiards_ods.settlement_records.order_remark IS 'source: settleList.orderRemark; order remark';
COMMENT ON COLUMN billiards_ods.settlement_records.operator_id IS 'source: settleList.operatorId; operator id';
COMMENT ON COLUMN billiards_ods.settlement_records.operator_name IS 'source: settleList.operatorName; operator name';
COMMENT ON COLUMN billiards_ods.settlement_records.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.settlement_records.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.settlement_records.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.settlement_records.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_goods_category (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
category_id BIGINT NOT NULL,
category_name TEXT,
parent_id BIGINT,
level_no INT,
status TEXT,
remark TEXT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, category_id)
);
COMMENT ON TABLE billiards_ods.ods_goods_category IS 'Source: 2.json -> data.goodsCategoryList';
COMMENT ON COLUMN billiards_ods.ods_goods_category.tenant_id IS 'source: goodsCategoryList.tenant_id; tenant/brand id';
COMMENT ON COLUMN billiards_ods.ods_goods_category.site_id IS 'ingest context; site id not explicitly exported';
COMMENT ON COLUMN billiards_ods.ods_goods_category.category_id IS 'source: goodsCategoryList.id; category id';
COMMENT ON COLUMN billiards_ods.ods_goods_category.category_name IS 'source: goodsCategoryList.category_name; category name';
COMMENT ON COLUMN billiards_ods.ods_goods_category.parent_id IS 'source: goodsCategoryList.pid; parent category id';
COMMENT ON COLUMN billiards_ods.ods_goods_category.level_no IS 'not present; reserved for category level';
COMMENT ON COLUMN billiards_ods.ods_goods_category.status IS 'source: goodsCategoryList.is_warehousing/open_salesman; category status flags';
COMMENT ON COLUMN billiards_ods.ods_goods_category.remark IS 'source: goodsCategoryList.alias_name/business_name; remark/alias';
COMMENT ON COLUMN billiards_ods.ods_goods_category.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.ods_goods_category.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.ods_goods_category.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.ods_goods_category.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.payment_transactions (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
pay_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
pay_method_code TEXT,
pay_method_name TEXT,
pay_status INT,
pay_amount NUMERIC(18,2),
pay_time TIMESTAMPTZ,
online_pay_channel TEXT,
transaction_id TEXT,
operator_id BIGINT,
remark TEXT,
relate_type TEXT,
relate_id BIGINT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, pay_id)
);
COMMENT ON TABLE billiards_ods.payment_transactions IS 'Source: .json';
COMMENT ON COLUMN billiards_ods.payment_transactions.tenant_id IS 'ingest context; tenant id not explicitly exported';
COMMENT ON COLUMN billiards_ods.payment_transactions.site_id IS 'source: .site_id; store id';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_id IS 'source: .id; payment record id';
COMMENT ON COLUMN billiards_ods.payment_transactions.order_trade_no IS 'not present in export; reserved for business order number';
COMMENT ON COLUMN billiards_ods.payment_transactions.order_settle_id IS 'not present; reserved for settlement id';
COMMENT ON COLUMN billiards_ods.payment_transactions.member_id IS 'not present; reserved for member id';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_method_code IS 'source: .payment_method; payment method enum';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_method_name IS 'not present; reserved for payment method name';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_status IS 'source: .pay_status; payment status';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_amount IS 'source: .pay_amount; paid amount';
COMMENT ON COLUMN billiards_ods.payment_transactions.pay_time IS 'source: .pay_time; payment time';
COMMENT ON COLUMN billiards_ods.payment_transactions.online_pay_channel IS 'source: .online_pay_channel; online channel code';
COMMENT ON COLUMN billiards_ods.payment_transactions.transaction_id IS 'not present in export; reserved for channel transaction id';
COMMENT ON COLUMN billiards_ods.payment_transactions.operator_id IS 'not present; reserved for operator id';
COMMENT ON COLUMN billiards_ods.payment_transactions.remark IS 'not present; reserved for remark';
COMMENT ON COLUMN billiards_ods.payment_transactions.relate_type IS 'source: .relate_type; related business type';
COMMENT ON COLUMN billiards_ods.payment_transactions.relate_id IS 'source: .relate_id; related business id';
COMMENT ON COLUMN billiards_ods.payment_transactions.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.payment_transactions.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.payment_transactions.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.payment_transactions.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.refund_transactions (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
refund_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
pay_sn TEXT,
pay_amount NUMERIC(18,2),
pay_status INT,
is_revoke BOOLEAN,
is_delete BOOLEAN,
online_pay_channel TEXT,
pay_method_code TEXT,
refund_amount NUMERIC(18,2),
refund_time TIMESTAMPTZ,
action_type INT,
pay_terminal INT,
pay_config_id BIGINT,
cashier_point_id BIGINT,
operator_id BIGINT,
member_card_id BIGINT,
balance_frozen_amount NUMERIC(18,2),
card_frozen_amount NUMERIC(18,2),
round_amount NUMERIC(18,2),
online_pay_type INT,
channel_payer_id TEXT,
channel_pay_no TEXT,
check_status INT,
channel_fee NUMERIC(18,2),
relate_type TEXT,
relate_id BIGINT,
status TEXT,
reason TEXT,
related_payment_id BIGINT,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, refund_id)
);
COMMENT ON TABLE billiards_ods.refund_transactions IS 'Source: ?json';
COMMENT ON COLUMN billiards_ods.refund_transactions.tenant_id IS 'source: ?tenant_id; tenant/brand id';
COMMENT ON COLUMN billiards_ods.refund_transactions.site_id IS 'source: ?site_id; store id';
COMMENT ON COLUMN billiards_ods.refund_transactions.refund_id IS 'source: ?id; refund record id';
COMMENT ON COLUMN billiards_ods.refund_transactions.order_trade_no IS 'not present in export; reserved for order number';
COMMENT ON COLUMN billiards_ods.refund_transactions.order_settle_id IS 'not present; reserved for settlement id';
COMMENT ON COLUMN billiards_ods.refund_transactions.member_id IS 'source: ?member_id; member id';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_sn IS 'source: ?pay_sn; payment serial number';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_amount IS 'source: ?pay_amount; paid amount';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_status IS 'source: ?pay_status; status code';
COMMENT ON COLUMN billiards_ods.refund_transactions.is_revoke IS 'source: ?is_revoke; revoke flag';
COMMENT ON COLUMN billiards_ods.refund_transactions.is_delete IS 'source: ?is_delete; logical delete flag';
COMMENT ON COLUMN billiards_ods.refund_transactions.online_pay_channel IS 'source: ?online_pay_channel; online pay channel';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_method_code IS 'source: ?payment_method; payment method enum';
COMMENT ON COLUMN billiards_ods.refund_transactions.refund_amount IS 'source: ?refund_amount; refund amount';
COMMENT ON COLUMN billiards_ods.refund_transactions.refund_time IS 'source: ?pay_time; refund time';
COMMENT ON COLUMN billiards_ods.refund_transactions.action_type IS 'source: ?action_type; action type';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_terminal IS 'source: ?pay_terminal; pay terminal';
COMMENT ON COLUMN billiards_ods.refund_transactions.pay_config_id IS 'source: ?pay_config_id; pay config id';
COMMENT ON COLUMN billiards_ods.refund_transactions.cashier_point_id IS 'source: ?cashier_point_id; cashier point id';
COMMENT ON COLUMN billiards_ods.refund_transactions.operator_id IS 'source: ?operator_id; operator id';
COMMENT ON COLUMN billiards_ods.refund_transactions.member_card_id IS 'source: ?member_card_id; member card id';
COMMENT ON COLUMN billiards_ods.refund_transactions.balance_frozen_amount IS 'source: ?balance_frozen_amount; frozen balance amount';
COMMENT ON COLUMN billiards_ods.refund_transactions.card_frozen_amount IS 'source: ?card_frozen_amount; frozen card amount';
COMMENT ON COLUMN billiards_ods.refund_transactions.round_amount IS 'source: ?round_amount; rounding/write-off amount';
COMMENT ON COLUMN billiards_ods.refund_transactions.online_pay_type IS 'source: ?online_pay_type; online refund type';
COMMENT ON COLUMN billiards_ods.refund_transactions.channel_payer_id IS 'source: ?channel_payer_id; channel payer id';
COMMENT ON COLUMN billiards_ods.refund_transactions.channel_pay_no IS 'source: ?channel_pay_no; channel transaction id';
COMMENT ON COLUMN billiards_ods.refund_transactions.check_status IS 'source: ?check_status; audit status';
COMMENT ON COLUMN billiards_ods.refund_transactions.channel_fee IS 'source: ?channel_fee; channel fee';
COMMENT ON COLUMN billiards_ods.refund_transactions.relate_type IS 'source: ?relate_type; related business type';
COMMENT ON COLUMN billiards_ods.refund_transactions.relate_id IS 'source: ?relate_id; related business id';
COMMENT ON COLUMN billiards_ods.refund_transactions.status IS 'alias for pay_status/is_delete to track row status';
COMMENT ON COLUMN billiards_ods.refund_transactions.reason IS 'not present in export; reserved for refund reason';
COMMENT ON COLUMN billiards_ods.refund_transactions.related_payment_id IS 'not present; reserved for linking to original payment';
COMMENT ON COLUMN billiards_ods.refund_transactions.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.refund_transactions.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.refund_transactions.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.refund_transactions.payload IS 'raw JSON payload for replay/debug';
CREATE TABLE IF NOT EXISTS billiards_ods.ods_order_receipt_detail (
tenant_id BIGINT,
site_id BIGINT NOT NULL,
order_settle_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_number TEXT,
settle_type INT,
receipt_no TEXT,
receipt_time TIMESTAMPTZ,
total_amount NUMERIC(18,2),
discount_amount NUMERIC(18,2),
final_amount NUMERIC(18,2),
actual_payment NUMERIC(18,2),
ledger_amount NUMERIC(18,2),
member_offer_amount NUMERIC(18,2),
delivery_fee NUMERIC(18,2),
adjust_amount NUMERIC(18,2),
payment_method INT,
pay_time TIMESTAMPTZ,
member_id BIGINT,
order_remark TEXT,
cashier_name TEXT,
ticket_remark TEXT,
ticket_custom_content TEXT,
voucher_money NUMERIC(18,2),
reward_name TEXT,
consume_money NUMERIC(18,2),
refund_amount NUMERIC(18,2),
balance_amount NUMERIC(18,2),
coupon_amount NUMERIC(18,2),
member_deduct_amount NUMERIC(18,2),
prepay_money NUMERIC(18,2),
delivery_address TEXT,
snapshot_raw JSONB,
member_snapshot JSONB,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (site_id, order_settle_id)
);
COMMENT ON TABLE billiards_ods.ods_order_receipt_detail IS 'Source: .json -> data.data (order detail)';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.order_settle_id IS 'source: orderSettleId; settlement id';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.order_trade_no IS 'not present in export; reserved for order number';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.order_settle_number IS 'source: orderSettleNumber; ticket/settlement number';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.settle_type IS 'source: settleType; settlement type enum';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.receipt_no IS 'not present in export; reserved for printed receipt number';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.receipt_time IS 'source: payTime; receipt/pay time';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.total_amount IS 'source: ledgerAmount; total amount before discounts';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.discount_amount IS 'derived from couponAmount/memberOfferAmount/pointDiscountPrice in payload; total discounts';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.final_amount IS 'source: consumeMoney; amount after discounts before payment';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.actual_payment IS 'source: actualPayment; amount actually paid';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.ledger_amount IS 'source: ledgerAmount; aggregated ledger amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.member_offer_amount IS 'source: memberOfferAmount; member discount amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.delivery_fee IS 'source: deliveryFee; delivery fee';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.adjust_amount IS 'source: adjustAmount; manual adjustment';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.payment_method IS 'source: paymentMethod; payment method code';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.pay_time IS 'source: payTime; payment time';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.member_id IS 'not present; memberProfile lacks id (only name/phone/point)';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.order_remark IS 'source: orderRemark; order remark';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.cashier_name IS 'source: cashierName; cashier name';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.ticket_remark IS 'source: ticketRemark; ticket remark';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.ticket_custom_content IS 'source: ticketCustomContent; custom print content';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.voucher_money IS 'source: voucherMoney; voucher amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.reward_name IS 'source: rewardName; reward description';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.consume_money IS 'source: consumeMoney; consumption amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.refund_amount IS 'source: refundAmount; refund amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.balance_amount IS 'source: balanceAmount or payMemberBalance; balance payment amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.coupon_amount IS 'source: couponAmount; coupon deduction amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.member_deduct_amount IS 'source: memberDeductAmount; member deduction amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.prepay_money IS 'source: prepayMoney; prepaid amount';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.delivery_address IS 'source: deliveryAddress; delivery address';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.snapshot_raw IS 'source: orderItem (table/goods/coupon ledgers); full nested detail JSON';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.member_snapshot IS 'source: memberProfile; member snapshot JSON';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.source_file IS 'ingest metadata: source file path';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.source_endpoint IS 'ingest metadata: API or endpoint name';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.fetched_at IS 'ingest metadata: load timestamp';
COMMENT ON COLUMN billiards_ods.ods_order_receipt_detail.payload IS 'raw JSON payload for replay/debug';
-- ---------- DWD Dimensions ----------
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_tenant (
tenant_id BIGINT PRIMARY KEY,
tenant_name TEXT,
short_name TEXT,
status TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_site (
site_id BIGINT PRIMARY KEY,
tenant_id BIGINT,
site_code TEXT,
site_name TEXT,
city TEXT,
region TEXT,
status TEXT,
open_date DATE,
close_date DATE,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_member_card_type (
card_type_id BIGINT PRIMARY KEY,
card_type_name TEXT,
discount_rate NUMERIC(8,4),
description TEXT,
remark TEXT
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_product_category (
category_id BIGINT PRIMARY KEY,
category_name TEXT,
parent_id BIGINT,
level_no INT,
status TEXT,
remark TEXT
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_product (
goods_id BIGINT PRIMARY KEY,
goods_name TEXT,
goods_code TEXT,
category_id BIGINT REFERENCES billiards_dwd.dim_product_category (category_id),
category_name TEXT,
unit TEXT,
default_price NUMERIC(18,2),
status TEXT,
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_table (
table_id BIGINT PRIMARY KEY,
site_id BIGINT,
table_code TEXT,
table_name TEXT,
table_type TEXT,
area_name TEXT,
status TEXT,
created_time TIMESTAMPTZ,
updated_time TIMESTAMPTZ
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_assistant_team (
team_id BIGINT PRIMARY KEY,
team_name TEXT,
remark TEXT,
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_assistant (
assistant_id BIGINT PRIMARY KEY,
assistant_name TEXT,
mobile TEXT,
team_id BIGINT REFERENCES billiards_dwd.dim_assistant_team (team_id),
status TEXT,
hired_date DATE,
left_date DATE,
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_pay_method (
pay_method_code TEXT PRIMARY KEY,
pay_method_name TEXT,
is_stored_value BOOLEAN DEFAULT FALSE,
status TEXT,
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_order_assist_type (
assist_type_code TEXT PRIMARY KEY,
assist_type_name TEXT,
description TEXT
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_coupon_platform (
platform_code TEXT PRIMARY KEY,
platform_name TEXT,
description TEXT
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_date (
date_key DATE PRIMARY KEY,
year_no INT,
month_no INT,
day_no INT,
week_no INT,
day_of_week INT,
month_name TEXT
);
CREATE TABLE IF NOT EXISTS billiards_dwd.dim_member (
site_id BIGINT,
member_id BIGINT,
tenant_id BIGINT,
member_name TEXT,
nickname TEXT,
gender TEXT,
birthday DATE,
mobile TEXT,
member_type_id BIGINT REFERENCES billiards_dwd.dim_member_card_type (card_type_id),
member_type_name TEXT,
status TEXT,
register_time TIMESTAMPTZ,
valid_from DATE,
valid_to DATE,
last_visit_time TIMESTAMPTZ,
balance NUMERIC(18,2),
total_recharge_amount NUMERIC(18,2),
total_consumed_amount NUMERIC(18,2),
wechat_id TEXT,
alipay_id TEXT,
remark TEXT,
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, member_id)
);
-- ---------- DWD Facts ----------
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_sale_item (
site_id BIGINT NOT NULL,
sale_item_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
goods_id BIGINT REFERENCES billiards_dwd.dim_product (goods_id),
category_id BIGINT REFERENCES billiards_dwd.dim_product_category (category_id),
quantity NUMERIC(18,4),
original_amount NUMERIC(18,2),
discount_amount NUMERIC(18,2),
final_amount NUMERIC(18,2),
is_gift BOOLEAN DEFAULT FALSE,
sale_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, sale_item_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_table_usage (
site_id BIGINT NOT NULL,
ledger_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
table_id BIGINT REFERENCES billiards_dwd.dim_table (table_id),
member_id BIGINT,
start_time TIMESTAMPTZ,
end_time TIMESTAMPTZ,
duration_minutes INT,
original_table_fee NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
manual_discount_amount NUMERIC(18,2),
final_table_fee NUMERIC(18,2),
is_canceled BOOLEAN DEFAULT FALSE,
cancel_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, ledger_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_assistant_service (
site_id BIGINT NOT NULL,
ledger_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
assistant_id BIGINT REFERENCES billiards_dwd.dim_assistant (assistant_id),
assist_type_code TEXT REFERENCES billiards_dwd.dim_order_assist_type (assist_type_code),
member_id BIGINT,
start_time TIMESTAMPTZ,
end_time TIMESTAMPTZ,
duration_minutes INT,
original_fee NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
manual_discount_amount NUMERIC(18,2),
final_fee NUMERIC(18,2),
is_canceled BOOLEAN DEFAULT FALSE,
cancel_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, ledger_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_coupon_usage (
site_id BIGINT NOT NULL,
coupon_id BIGINT NOT NULL,
package_id BIGINT,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
platform_code TEXT REFERENCES billiards_dwd.dim_coupon_platform (platform_code),
status TEXT,
deduct_amount NUMERIC(18,2),
settle_price NUMERIC(18,2),
used_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, coupon_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_payment (
site_id BIGINT NOT NULL,
pay_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
pay_method_code TEXT REFERENCES billiards_dwd.dim_pay_method (pay_method_code),
pay_amount NUMERIC(18,2),
pay_time TIMESTAMPTZ,
relate_type TEXT,
relate_id BIGINT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, pay_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_refund (
site_id BIGINT NOT NULL,
refund_id BIGINT NOT NULL,
order_trade_no TEXT,
order_settle_id BIGINT,
member_id BIGINT,
pay_method_code TEXT REFERENCES billiards_dwd.dim_pay_method (pay_method_code),
refund_amount NUMERIC(18,2),
refund_time TIMESTAMPTZ,
status TEXT,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, refund_id)
);
CREATE TABLE IF NOT EXISTS billiards_dwd.fact_balance_change (
site_id BIGINT NOT NULL,
change_id BIGINT NOT NULL,
member_id BIGINT,
change_type INT,
relate_type TEXT,
relate_id BIGINT,
pay_method_code TEXT REFERENCES billiards_dwd.dim_pay_method (pay_method_code),
change_amount NUMERIC(18,2),
balance_before NUMERIC(18,2),
balance_after NUMERIC(18,2),
change_time TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, change_id)
);
-- ---------- DWS (serving layers) ----------
CREATE TABLE IF NOT EXISTS billiards_dws.dws_order_summary (
site_id BIGINT NOT NULL,
order_settle_id BIGINT NOT NULL,
order_trade_no TEXT,
order_date DATE,
tenant_id BIGINT,
member_id BIGINT,
member_flag BOOLEAN DEFAULT FALSE,
recharge_order_flag BOOLEAN DEFAULT FALSE,
item_count INT,
total_item_quantity NUMERIC(18,4),
table_fee_amount NUMERIC(18,2),
assistant_service_amount NUMERIC(18,2),
goods_amount NUMERIC(18,2),
group_amount NUMERIC(18,2),
total_coupon_deduction NUMERIC(18,2),
member_discount_amount NUMERIC(18,2),
manual_discount_amount NUMERIC(18,2),
order_original_amount NUMERIC(18,2),
order_final_amount NUMERIC(18,2),
stored_card_deduct NUMERIC(18,2),
external_paid_amount NUMERIC(18,2),
total_paid_amount NUMERIC(18,2),
book_table_flow NUMERIC(18,2),
book_assistant_flow NUMERIC(18,2),
book_goods_flow NUMERIC(18,2),
book_group_flow NUMERIC(18,2),
book_order_flow NUMERIC(18,2),
order_effective_consume_cash NUMERIC(18,2),
order_effective_recharge_cash NUMERIC(18,2),
order_effective_flow NUMERIC(18,2),
refund_amount NUMERIC(18,2),
net_income NUMERIC(18,2),
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (site_id, order_settle_id)
);
-- ---------- etl_admin (scheduler, cursor, run tracking) ----------
CREATE SCHEMA IF NOT EXISTS etl_admin;
CREATE TABLE IF NOT EXISTS etl_admin.etl_task (
task_id BIGSERIAL PRIMARY KEY,
task_code TEXT NOT NULL,
store_id BIGINT NOT NULL,
enabled BOOLEAN DEFAULT TRUE,
cursor_field TEXT,
window_minutes_default INT DEFAULT 30,
overlap_seconds INT DEFAULT 120,
page_size INT DEFAULT 200,
retry_max INT DEFAULT 3,
params JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (task_code, store_id)
);
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,
last_run_id BIGINT,
extra JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (task_id, store_id)
);
CREATE TABLE IF NOT EXISTS etl_admin.etl_run (
run_id BIGSERIAL PRIMARY KEY,
run_uuid TEXT NOT NULL,
task_id BIGINT NOT NULL REFERENCES etl_admin.etl_task(task_id) ON DELETE CASCADE,
store_id BIGINT NOT NULL,
status TEXT NOT NULL,
started_at TIMESTAMPTZ DEFAULT now(),
ended_at TIMESTAMPTZ,
window_start TIMESTAMPTZ,
window_end TIMESTAMPTZ,
window_minutes INT,
overlap_seconds INT,
fetched_count INT DEFAULT 0,
loaded_count INT DEFAULT 0,
updated_count INT DEFAULT 0,
skipped_count INT DEFAULT 0,
error_count INT DEFAULT 0,
unknown_fields INT DEFAULT 0,
export_dir TEXT,
log_path TEXT,
request_params JSONB DEFAULT '{}'::jsonb,
manifest JSONB DEFAULT '{}'::jsonb,
error_message TEXT,
extra JSONB DEFAULT '{}'::jsonb
);
-- Default task registry seed (idempotent)
INSERT INTO etl_admin.etl_task (task_code, store_id, enabled)
VALUES
('PRODUCTS', 2790685415443269, TRUE),
('TABLES', 2790685415443269, TRUE),
('MEMBERS', 2790685415443269, TRUE),
('ASSISTANTS', 2790685415443269, TRUE),
('PACKAGES_DEF', 2790685415443269, TRUE),
('ORDERS', 2790685415443269, TRUE),
('PAYMENTS', 2790685415443269, TRUE),
('REFUNDS', 2790685415443269, TRUE),
('COUPON_USAGE', 2790685415443269, TRUE),
('INVENTORY_CHANGE', 2790685415443269, TRUE),
('TOPUPS', 2790685415443269, TRUE),
('TABLE_DISCOUNT', 2790685415443269, TRUE),
('ASSISTANT_ABOLISH', 2790685415443269, TRUE),
('LEDGER', 2790685415443269, TRUE),
('TICKET_DWD', 2790685415443269, TRUE),
('PAYMENTS_DWD', 2790685415443269, TRUE),
('MEMBERS_DWD', 2790685415443269, TRUE),
('MANUAL_INGEST', 2790685415443269, TRUE),
('settlement_records', 2790685415443269, TRUE),
('table_fee_transactions', 2790685415443269, TRUE),
('assistant_service_records', 2790685415443269, TRUE),
('assistant_cancellation_records', 2790685415443269, TRUE),
('ODS_GOODS_LEDGER', 2790685415443269, TRUE),
('ODS_PAYMENT', 2790685415443269, TRUE),
('ODS_REFUND', 2790685415443269, TRUE),
('platform_coupon_redemption_records', 2790685415443269, TRUE),
('ODS_MEMBER', 2790685415443269, TRUE),
('member_stored_value_cards', 2790685415443269, TRUE),
('ODS_PACKAGE', 2790685415443269, TRUE),
('ODS_INVENTORY_STOCK', 2790685415443269, TRUE),
('goods_stock_movements', 2790685415443269, TRUE)
ON CONFLICT (task_code, store_id) DO NOTHING;