2026-09-11 09:07:41 +08:00
|
|
|
|
DROP ALL OBJECTS;
|
|
|
|
|
|
|
|
|
|
|
|
CREATE TABLE users (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, wechat_openid VARCHAR(128) NOT NULL UNIQUE,
|
|
|
|
|
|
wechat_unionid VARCHAR(128), phone VARCHAR(32), account_status VARCHAR(32),
|
|
|
|
|
|
relationship_status VARCHAR(32), recommendation_enabled BOOLEAN,
|
|
|
|
|
|
last_login_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE user_relations (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), target_user_id VARCHAR(36), relation_type VARCHAR(32),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
UNIQUE (user_id, target_user_id, relation_type)
|
|
|
|
|
|
);
|
2026-09-16 15:11:38 +08:00
|
|
|
|
-- 与 V002__add_user_and_verification_tables.sql 的 user_profiles 对齐(列名/语义一致),
|
|
|
|
|
|
-- 供 DiscoverService 搜索(INV-004 搜索不可见)等需要真实资料的用例使用。
|
|
|
|
|
|
CREATE TABLE user_profiles (
|
|
|
|
|
|
user_id VARCHAR(36) PRIMARY KEY, display_name VARCHAR(64), gender VARCHAR(16),
|
|
|
|
|
|
birth_date DATE, height_cm INT, region_code VARCHAR(32), region_name VARCHAR(128),
|
|
|
|
|
|
marital_status VARCHAR(32), children_status VARCHAR(32), education_code VARCHAR(32),
|
|
|
|
|
|
occupation_code VARCHAR(32), work_region_code VARCHAR(32), smoking_status VARCHAR(32),
|
|
|
|
|
|
drinking_status VARCHAR(32), long_term_danyang VARCHAR(32), future_danyang VARCHAR(32),
|
|
|
|
|
|
relationship_goal VARCHAR(64), marriage_plan VARCHAR(32), self_intro CLOB,
|
|
|
|
|
|
profile_completion INT DEFAULT 0, profile_status VARCHAR(32) DEFAULT 'in_progress',
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
2026-09-11 09:07:41 +08:00
|
|
|
|
CREATE TABLE matches (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_a_id VARCHAR(36), user_b_id VARCHAR(36), status VARCHAR(32), source VARCHAR(32),
|
2026-09-15 22:29:26 +08:00
|
|
|
|
source_id VARCHAR(64), last_activity_at TIMESTAMP WITH TIME ZONE, unmatched_by VARCHAR(36), episode INT,
|
2026-09-11 09:07:41 +08:00
|
|
|
|
matched_at TIMESTAMP WITH TIME ZONE, unmatched_at TIMESTAMP WITH TIME ZONE, successful_at TIMESTAMP WITH TIME ZONE,
|
2026-09-16 15:11:38 +08:00
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
-- 与 V003__add_review_and_relation_tables.sql:91 的生产约束保持一致。
|
|
|
|
|
|
-- 测试库若缺此约束,形如 source='liked' 的非法取值会被静默放过,只在 PostgreSQL 上炸。
|
|
|
|
|
|
CONSTRAINT chk_match_source CHECK (source IN ('user_like', 'activity_mutual', 'matchmaker'))
|
2026-09-11 09:07:41 +08:00
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE relationship_success_requests (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, match_id VARCHAR(36), initiated_by VARCHAR(36), status VARCHAR(32), confirmed_by VARCHAR(36),
|
|
|
|
|
|
resolved_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE conversations (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, match_id VARCHAR(36) UNIQUE, status VARCHAR(32), last_message_id VARCHAR(36),
|
|
|
|
|
|
last_message_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
2026-09-15 22:29:26 +08:00
|
|
|
|
-- 复合主键 (conversation_id, user_id),与 V004/V008 真实表结构一致,无 id 列
|
2026-09-11 09:07:41 +08:00
|
|
|
|
CREATE TABLE conversation_members (
|
2026-09-15 22:29:26 +08:00
|
|
|
|
conversation_id VARCHAR(36), user_id VARCHAR(36), last_read_message_id VARCHAR(36),
|
|
|
|
|
|
unread_count INT, can_send BOOLEAN, joined_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
PRIMARY KEY (conversation_id, user_id)
|
2026-09-11 09:07:41 +08:00
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE messages (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, conversation_id VARCHAR(36), sender_id VARCHAR(36), client_message_id VARCHAR(128),
|
|
|
|
|
|
message_type VARCHAR(32), content CLOB, file_id VARCHAR(36), status VARCHAR(32), risk_level VARCHAR(16),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
2026-09-16 16:42:48 +08:00
|
|
|
|
-- 与 V004__add_messaging_and_recommendation_tables.sql:71 的生产唯一索引对齐:
|
|
|
|
|
|
-- CREATE UNIQUE INDEX uk_message_client_id ON messages(sender_id, client_message_id)
|
|
|
|
|
|
-- WHERE client_message_id IS NOT NULL;
|
|
|
|
|
|
-- 生产带 WHERE(部分索引),H2 不支持过滤索引;但 H2 的唯一索引对 NULL 采取
|
|
|
|
|
|
-- SQL 标准语义(多个 NULL 互不冲突),因此省略 WHERE 后语义等价,
|
|
|
|
|
|
-- 保证「未带幂等键的消息」(如系统 RiskNotice)仍可多条存在。
|
|
|
|
|
|
-- 这条索引是"正常会话不重复投递"在并发下的真正保障:service 侧的
|
|
|
|
|
|
-- SELECT-then-INSERT 在并发重放时会有竞态,只有 DB 唯一索引能兜住。
|
|
|
|
|
|
CREATE UNIQUE INDEX uk_message_client_id ON messages(sender_id, client_message_id);
|
2026-09-11 09:07:41 +08:00
|
|
|
|
CREATE TABLE audit_logs (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, operator_id VARCHAR(36), organization_id VARCHAR(36), action VARCHAR(128),
|
|
|
|
|
|
resource_type VARCHAR(64), resource_id VARCHAR(128), before_data CLOB, after_data CLOB, ip VARCHAR(64),
|
|
|
|
|
|
user_agent VARCHAR(500), created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE notifications (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), type VARCHAR(32), title VARCHAR(200), content VARCHAR(2000),
|
|
|
|
|
|
business_type VARCHAR(32), business_id VARCHAR(128), read_status VARCHAR(16), read_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
2026-09-16 21:50:56 +08:00
|
|
|
|
-- 对齐生产 V036 uk_notification_business:NOT NULL 业务行去重;H2 不支持 partial index,
|
|
|
|
|
|
-- 但标准 UNIQUE 对 NULL 的语义(多行 NULL 允许共存)与生产 partial index 等价。
|
|
|
|
|
|
CREATE UNIQUE INDEX uk_notification_business ON notifications(user_id, type, business_type, business_id, content);
|
|
|
|
|
|
-- 对齐生产 V004/V020 chk_notification_type:缺少此约束会导致写入非法 type 时测试静默通过,
|
|
|
|
|
|
-- 而真实 PostgreSQL 直接拒绝 —— Phase 11 十种通知曾因此长期带病运行(D3)。
|
|
|
|
|
|
ALTER TABLE notifications ADD CONSTRAINT chk_notification_type CHECK (
|
|
|
|
|
|
type IN ('review', 'match', 'matchmaker', 'activity', 'risk', 'account', 'system',
|
|
|
|
|
|
'appointment', 'counseling', 'premarital', 'local_eligibility', 'service_location')
|
|
|
|
|
|
);
|
2026-09-11 09:07:41 +08:00
|
|
|
|
CREATE TABLE recommendation_records (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), target_user_id VARCHAR(36), source VARCHAR(32), score NUMERIC(5,2),
|
|
|
|
|
|
level VARCHAR(16), reasons CLOB, shown_at TIMESTAMP WITH TIME ZONE, action VARCHAR(32), action_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
rule_version INT, created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE activity_registrations (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, activity_id VARCHAR(36), user_id VARCHAR(36), status VARCHAR(32),
|
|
|
|
|
|
registered_at TIMESTAMP WITH TIME ZONE, reviewed_by VARCHAR(36), reviewed_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
reject_reason VARCHAR(500), checkin_status VARCHAR(32), checkin_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
emergency_contact_name VARCHAR(100), emergency_contact_phone_enc VARCHAR(500), source VARCHAR(64),
|
|
|
|
|
|
request_source VARCHAR(64), created_by_operator_id VARCHAR(36), user_confirmed_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE service_appointments (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), service_location_id VARCHAR(36), service_type VARCHAR(64),
|
|
|
|
|
|
preferred_date DATE, preferred_time_slot VARCHAR(32), user_note CLOB, status VARCHAR(32),
|
|
|
|
|
|
assigned_operator_id VARCHAR(36), confirmed_start_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
confirmed_end_at TIMESTAMP WITH TIME ZONE, cancelled_by VARCHAR(36), cancel_reason VARCHAR(500),
|
|
|
|
|
|
source VARCHAR(64), request_source VARCHAR(64), created_by_operator_id VARCHAR(36),
|
|
|
|
|
|
user_confirmed_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE counseling_services (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), service_type VARCHAR(64), request_source VARCHAR(64),
|
|
|
|
|
|
user_request_summary CLOB, organization_id VARCHAR(36), assigned_operator_id VARCHAR(36), status VARCHAR(32),
|
|
|
|
|
|
preferred_service_mode VARCHAR(32), preferred_time VARCHAR(128), scheduled_start_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
scheduled_end_at TIMESTAMP WITH TIME ZONE, consent_version VARCHAR(32), consented_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
completed_at TIMESTAMP WITH TIME ZONE, closed_reason VARCHAR(500), companion_user_id VARCHAR(36),
|
|
|
|
|
|
created_by_operator_id VARCHAR(36), user_confirmed_at TIMESTAMP WITH TIME ZONE,
|
2026-09-17 01:25:12 +08:00
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
idempotency_key VARCHAR(128),
|
|
|
|
|
|
-- 生产约束(V022 + V039):此前测试库完全没有 CHECK → 约束漂移盲区(Phase 11/13 同族根因)
|
|
|
|
|
|
CONSTRAINT chk_counseling_service_type CHECK (service_type IN (
|
|
|
|
|
|
'relationship_guidance', 'emotional_support', 'premarital_guidance', 'anti_fraud_guidance'
|
|
|
|
|
|
)),
|
|
|
|
|
|
CONSTRAINT chk_counseling_status CHECK (status IN (
|
|
|
|
|
|
'pending', 'assigned', 'scheduled', 'in_progress', 'completed', 'cancelled', 'closed'
|
|
|
|
|
|
)),
|
|
|
|
|
|
CONSTRAINT chk_request_source CHECK (request_source IN (
|
|
|
|
|
|
'user_self', 'matchmaker_referral', 'activity_followup', 'service_station', 'operator_assisted'
|
|
|
|
|
|
)),
|
|
|
|
|
|
-- V039 幂等索引:H2 无 partial index,用标准 UNIQUE 表达(PG/H2 均允许多行 NULL 共存,语义等价)
|
|
|
|
|
|
CONSTRAINT uk_counseling_idem UNIQUE (user_id, idempotency_key)
|
|
|
|
|
|
);
|
|
|
|
|
|
-- V022 / V039: counseling_followups 表(跟进正文属 INV-013 敏感数据)
|
|
|
|
|
|
CREATE TABLE counseling_followups (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, counseling_id VARCHAR(36) NOT NULL, operator_id VARCHAR(36) NOT NULL,
|
|
|
|
|
|
followup_type VARCHAR(32), content CLOB NOT NULL, result_code VARCHAR(64),
|
|
|
|
|
|
next_followup_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE
|
2026-09-11 09:07:41 +08:00
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE service_program_members (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, program_id VARCHAR(36), user_id VARCHAR(36), status VARCHAR(32),
|
|
|
|
|
|
applied_at TIMESTAMP WITH TIME ZONE, approved_at TIMESTAMP WITH TIME ZONE, approved_by VARCHAR(36),
|
|
|
|
|
|
rejected_reason VARCHAR(500), created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
CREATE TABLE user_local_eligibilities (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) UNIQUE, eligibility_type VARCHAR(32),
|
|
|
|
|
|
declared_region_code VARCHAR(32), verification_status VARCHAR(32), review_task_id VARCHAR(36),
|
|
|
|
|
|
verified_at TIMESTAMP WITH TIME ZONE, verified_by VARCHAR(36), created_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
2026-09-16 23:01:13 +08:00
|
|
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
-- 以下表为 Phase 12 复验补齐(测试保真度盲区):
|
|
|
|
|
|
-- 生产迁移里存在、而测试库此前**完全没有**,导致相关端到端路径无法测试。
|
|
|
|
|
|
-- 例:GET /api/v1/home 的 getHome() 会调用 UserIdentityMapper.findByUserId,
|
|
|
|
|
|
-- 测试库缺 user_identities → BadSqlGrammar("Table USER_IDENTITIES not found")
|
|
|
|
|
|
-- 整个首页接口在测试环境下不可用,任何首页回归都无法验证。
|
|
|
|
|
|
-- 列定义对齐对应迁移,仅保留实体实际读写的列。
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
-- V002: user_identities 实名认证表
|
|
|
|
|
|
CREATE TABLE user_identities (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), real_name_enc CLOB, id_number_enc CLOB,
|
|
|
|
|
|
id_number_hash VARCHAR(128), gender VARCHAR(16), birth_date DATE,
|
|
|
|
|
|
verification_status VARCHAR(32), provider VARCHAR(64), provider_request_id VARCHAR(128),
|
|
|
|
|
|
verified_at TIMESTAMP WITH TIME ZONE, failed_reason_code VARCHAR(64),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V003: review_tasks 审核任务(首页 buildUserState 需查询审核状态)
|
|
|
|
|
|
CREATE TABLE review_tasks (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36), review_type VARCHAR(32), status VARCHAR(32),
|
|
|
|
|
|
assigned_operator_id VARCHAR(36), submitted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
started_at TIMESTAMP WITH TIME ZONE, completed_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
final_comment VARCHAR(1000), version INT,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V017: local_eligibility_evidences 本地资格佐证材料
|
|
|
|
|
|
CREATE TABLE local_eligibility_evidences (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, local_eligibility_id VARCHAR(36), file_key VARCHAR(256),
|
|
|
|
|
|
file_id VARCHAR(36), evidence_type VARCHAR(64), status VARCHAR(32),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V019: home_banners 首页 Banner
|
|
|
|
|
|
CREATE TABLE home_banners (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, title VARCHAR(200), subtitle VARCHAR(300), image_file_id VARCHAR(36),
|
|
|
|
|
|
button_text VARCHAR(64), target_type VARCHAR(64), target_value VARCHAR(200),
|
|
|
|
|
|
audience_scope VARCHAR(64), sort_order INT, start_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
end_at TIMESTAMP WITH TIME ZONE, status VARCHAR(32), created_by VARCHAR(36), updated_by VARCHAR(36),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V019: service_locations 善缘服务站
|
|
|
|
|
|
CREATE TABLE service_locations (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, name VARCHAR(128), short_name VARCHAR(64), address CLOB,
|
|
|
|
|
|
latitude DECIMAL(10, 7), longitude DECIMAL(10, 7), contact_phone_enc CLOB,
|
|
|
|
|
|
contact_phone_display VARCHAR(32), opening_hours_text CLOB, service_description CLOB,
|
|
|
|
|
|
cover_file_id VARCHAR(36), primary_organization_id VARCHAR(36), notice_text CLOB,
|
|
|
|
|
|
status VARCHAR(32), created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V026: content_articles 婚恋课堂文章
|
|
|
|
|
|
CREATE TABLE content_articles (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, category_id VARCHAR(36), title VARCHAR(200), summary VARCHAR(500),
|
|
|
|
|
|
content CLOB, cover_file_id VARCHAR(36), author_operator_id VARCHAR(36), status VARCHAR(32),
|
|
|
|
|
|
publish_at TIMESTAMP WITH TIME ZONE, view_count INT, sort_order INT,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V010: activities 公益活动(首页近期活动预览)
|
|
|
|
|
|
CREATE TABLE activities (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, title VARCHAR(200), cover_file_id VARCHAR(36), description CLOB,
|
|
|
|
|
|
organizer_org_id VARCHAR(36), coorganizer_text VARCHAR(500), start_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
end_at TIMESTAMP WITH TIME ZONE, location_name VARCHAR(200), location_address VARCHAR(500),
|
|
|
|
|
|
male_limit INT, female_limit INT, total_limit INT, min_age SMALLINT, max_age SMALLINT,
|
|
|
|
|
|
registration_start_at TIMESTAMP WITH TIME ZONE, registration_end_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
need_review BOOLEAN, status VARCHAR(32), created_by VARCHAR(36),
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE, deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2026-09-17 00:01:53 +08:00
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
-- Phase 13(V009 + V021 + V037 + V038):红娘服务三表
|
|
|
|
|
|
-- 此前测试库完全缺失,导致 matchmaker 模块零真实行为覆盖、只能写假测试。
|
|
|
|
|
|
-- 约束与生产 V038 对齐(status 白名单已含 liked/passed/confirmed_mutual)。
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
-- V009: matchmaker_services 红娘服务表
|
|
|
|
|
|
CREATE TABLE matchmaker_services (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, user_id VARCHAR(36) NOT NULL, service_type VARCHAR(32) NOT NULL,
|
|
|
|
|
|
description VARCHAR(1000), status VARCHAR(32) NOT NULL DEFAULT 'submitted',
|
|
|
|
|
|
organization_id VARCHAR(36), assigned_operator_id VARCHAR(36),
|
|
|
|
|
|
assigned_at TIMESTAMP WITH TIME ZONE, completed_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
referral_target_type VARCHAR(32), referral_target_id VARCHAR(36),
|
|
|
|
|
|
referral_source_type VARCHAR(32) NOT NULL DEFAULT 'manual',
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
|
|
deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
CONSTRAINT chk_matchmaker_service_type CHECK (service_type IN (
|
|
|
|
|
|
'recommend_partner', 'review_preference', 'contact_intention',
|
|
|
|
|
|
'join_activity', 'no_match_help', 'chat_help', 'other',
|
|
|
|
|
|
'recommendation',
|
|
|
|
|
|
'referral_counseling', 'referral_activity', 'referral_station'
|
|
|
|
|
|
)),
|
|
|
|
|
|
CONSTRAINT chk_matchmaker_status CHECK (status IN (
|
|
|
|
|
|
'submitted', 'assigned', 'in_service', 'waiting_user', 'completed', 'cancelled'
|
|
|
|
|
|
))
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V009: matchmaker_recommendations 红娘推荐表
|
|
|
|
|
|
CREATE TABLE matchmaker_recommendations (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, service_id VARCHAR(36) NOT NULL, user_id VARCHAR(36) NOT NULL,
|
|
|
|
|
|
target_user_id VARCHAR(36) NOT NULL, operator_id VARCHAR(36) NOT NULL, reason VARCHAR(1000),
|
|
|
|
|
|
status VARCHAR(32) NOT NULL DEFAULT 'pending_view',
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
|
|
viewed_at TIMESTAMP WITH TIME ZONE, responded_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
|
|
deleted_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
CONSTRAINT chk_rec_status CHECK (status IN (
|
|
|
|
|
|
'pending_view', 'viewed', 'responded',
|
|
|
|
|
|
'liked', 'passed', 'confirmed_mutual'
|
|
|
|
|
|
))
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
-- V009: matchmaker_followups 红娘跟进表
|
|
|
|
|
|
CREATE TABLE matchmaker_followups (
|
|
|
|
|
|
id VARCHAR(36) PRIMARY KEY, service_id VARCHAR(36) NOT NULL, operator_id VARCHAR(36) NOT NULL,
|
|
|
|
|
|
followup_type VARCHAR(32), content VARCHAR(2000) NOT NULL, result_code VARCHAR(64),
|
|
|
|
|
|
next_followup_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
|
|
|
|
updated_at TIMESTAMP WITH TIME ZONE,
|
|
|
|
|
|
deleted_at TIMESTAMP WITH TIME ZONE
|
|
|
|
|
|
);
|
|
|
|
|
|
|