4.2 KiB
4.2 KiB
BD 手册:助教手动补录会员生日表(C2)
概述
为支持助教手动提交客户生日信息(上游 API 未提供时的补充渠道),在 zqyy_app / test_zqyy_app 业务库中新建 member_birthday_manual 表。该表通过 FDW 只读映射供 ETL DWS 任务读取,与 dim_member.birthday(API 来源)配合实现生日数据的双源合并。
变更说明
| 库 | Schema | 表 | 变更类型 | 说明 |
|---|---|---|---|---|
| zqyy_app / test_zqyy_app | public | member_birthday_manual | 新建表 | 助教手动补录的会员生日信息 |
表结构
| 列名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGSERIAL | PRIMARY KEY | 自增主键 |
| member_id | BIGINT | NOT NULL | 会员 ID |
| birthday_value | DATE | NOT NULL | 补录的生日值 |
| recorded_by_assistant_id | BIGINT | — | 提交助教 ID |
| recorded_by_name | VARCHAR(50) | — | 提交助教姓名 |
| recorded_at | TIMESTAMPTZ | NOT NULL DEFAULT NOW() | 提交时间 |
| source | VARCHAR(20) | DEFAULT 'assistant' | 数据来源标识 |
| site_id | BIGINT | NOT NULL | 门店 ID(多门店隔离,Requirements 13.1) |
约束与索引
| 名称 | 类型 | 列 | 说明 |
|---|---|---|---|
| member_birthday_manual_pkey | PRIMARY KEY | id | 主键 |
| uk_member_birthday_manual | UNIQUE | (member_id, recorded_by_assistant_id) | 同一助教对同一会员只保留一条记录,支持 UPSERT |
| idx_mbd_member | INDEX (btree) | member_id | 加速按会员 ID 查询 |
| idx_mbd_site_id | INDEX (btree) | site_id | 加速按门店 ID 查询 |
兼容性
- ETL Connector:后续通过 FDW 反向映射(
fdw_app.member_birthday_manual)在 ETL 库中只读访问,DWS 任务使用COALESCE(手动补录值, API 值)合并生日数据 - 后端 API:新增
POST /member-birthday接口执行 UPSERT 写入(任务 9.4) - 小程序:助教端调用后端 API 提交生日,无直接数据库访问
- 现有数据:新建表,无历史数据影响
回滚策略
BEGIN;
DROP TABLE IF EXISTS member_birthday_manual CASCADE;
COMMIT;
回滚无数据丢失风险:该表为新建表,回滚前的数据均为手动补录的生日信息,可由助教重新提交。若已建立 FDW 映射,需先在 ETL 库中删除外部表 fdw_app.member_birthday_manual。
验证步骤
-- 1. 确认表存在
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name = 'member_birthday_manual';
-- 预期:1 行
-- 2. 确认唯一约束 uk_member_birthday_manual 存在
SELECT conname, contype
FROM pg_constraint
WHERE conrelid = 'member_birthday_manual'::regclass
AND conname = 'uk_member_birthday_manual';
-- 预期:1 行,contype = 'u'
-- 3. 确认索引 idx_mbd_member 存在
SELECT indexname
FROM pg_indexes
WHERE tablename = 'member_birthday_manual'
AND indexname = 'idx_mbd_member';
-- 预期:1 行
-- 4. 确认表注释已设置
SELECT obj_description('member_birthday_manual'::regclass, 'pg_class');
-- 预期:'助教手动补录的会员生日信息'
-- 5. 确认列结构完整
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'member_birthday_manual'
ORDER BY ordinal_position;
-- 预期:8 列(id, member_id, birthday_value, recorded_by_assistant_id,
-- recorded_by_name, recorded_at, source, site_id)
-- 6. 确认 site_id 索引存在
SELECT indexname
FROM pg_indexes
WHERE tablename = 'member_birthday_manual'
AND indexname = 'idx_mbd_site_id';
-- 预期:1 行
关联文件
- 迁移脚本:
db/zqyy_app/migrations/2026-02-22__C2_member_birthday_manual.sql - FDW 反向映射(生产):
db/fdw/setup_fdw_reverse.sql— 在 etl_feiqiu 中创建fdw_app.member_birthday_manual外部表 - FDW 反向映射(测试):
db/fdw/setup_fdw_reverse_test.sql— 在 test_etl_feiqiu 中创建外部表 - FDW 反向映射文档:
docs/database/BD_Manual_fdw_reverse_member_birthday.md - 需求文档:
.kiro/specs/etl-aggregation-fix/requirements.md— 需求 5.1, 5.3 - 后续任务:9.3(DWS 任务生日读取优先级)、9.4(后端 API 接口)