Files
danyang-match/后端总体架构与核心业务服务设计.md
T

3488 lines
43 KiB
Markdown
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.
# 丹阳公益婚恋服务平台
# V1.0 后端总体架构与核心业务服务设计
版本:V1.0
适用范围:微信小程序用户端、公益红娘工作台、运营管理后台
设计目标:低复杂度、易维护、易部署、可扩展、安全可靠、支持后续平滑升级
---
# 第一章 设计目标
V1.0后端设计必须解决以下核心问题:
- 用户登录与账号管理
- 手机号绑定
- 实名认证
- 用户婚恋资料
- 人工审核
- 择偶条件
- 系统推荐
- 喜欢与双向匹配
- 聊天消息
- 公益红娘服务
- 线下相亲活动
- 举报与风控
- 婚恋状态
- 组织与工作人员
- 角色与权限
- 系统通知
- 数据统计
- 操作日志
- 隐私与敏感数据保护
V1.0的技术原则不是追求复杂架构,而是:
> **先用清晰、稳定、可维护的方式完成完整业务闭环。**
---
# 第二章 总体技术架构原则
V1.0建议采用:
> **模块化单体架构 + 独立实时消息服务能力 + Redis + 关系型数据库 + 对象存储**
而不是一开始就建设:
- 大规模微服务
- 服务网格
- Kubernetes集群
- 分布式事件总线
- 多数据中心
- 复杂CQRS
- 复杂搜索集群
原因:
当前产品首先服务丹阳本地。
即使前期达到:
- 1万用户
- 5万用户
- 10万用户
模块化单体依然完全可以支撑。
---
# 第三章 推荐总体架构
```text id="arch001"
┌──────────────────────────────────────────┐
│ 客户端 │
├──────────────────────────────────────────┤
│ 微信小程序 │ 公益红娘Web │ 运营管理后台Web │
└───────────────┬──────────────────────────┘
│ HTTPS / WebSocket
↓
┌──────────────────────────────────────────┐
│ API Gateway / BFF │
│ 认证 / 限流 / 日志 / 错误码 / 权限上下文 │
└────────────────┬─────────────────────────┘
↓
┌──────────────────────────────────────────┐
│ 核心业务应用 │
│ │
│ Auth │
│ User │
│ Profile │
│ Verification │
│ Review │
│ Match │
│ Relationship │
│ Message │
│ Activity │
│ Matchmaker │
│ Risk │
│ Notification │
│ Organization │
│ Permission │
│ Analytics │
└───────────────┬──────────────────────────┘
│
┌───────┼──────────┐
↓ ↓ ↓
PostgreSQL Redis Object Storage
图片/附件
```
---
# 第四章 架构模式
V1.0采用:
> Modular Monolith
即:
一个后端应用。
内部按照业务领域严格拆模块。
例如:
```text id="arch002"
modules/
auth/
user/
profile/
verification/
review/
match/
relationship/
messaging/
activity/
matchmaker/
risk/
notification/
organization/
permission/
analytics/
```
模块之间:
> 通过明确Service接口调用。
禁止:
> 任意跨模块直接修改数据库表。
---
# 第五章 为什么不建议V1.0直接微服务
婚恋平台确实可能未来扩大。
但V1.0如果直接拆:
- 用户服务
- 匹配服务
- 聊天服务
- 红娘服务
- 活动服务
- 风控服务
会额外增加:
- 服务发现
- RPC
- 配置中心
- 链路追踪
- 部署数量
- 数据一致性
- 分布式事务
- 运维复杂度
这些对于当前项目没有直接用户价值。
因此原则:
> **逻辑模块化,物理先单体化。**
未来业务量上升时再拆。
---
# 第六章 推荐技术栈
后端建议优先采用成熟主流技术。
推荐方案之一:
```text id="tech001"
Java 21
Spring Boot 3.x
Spring Security
MyBatis-Plus 或 Spring Data JPA
PostgreSQL
Redis
WebSocket
S3兼容对象存储
Docker
Nginx
```
如果研发团队更熟悉Node.js,也可使用:
```text id="tech002"
Node.js
NestJS
PostgreSQL
Redis
WebSocket
S3兼容对象存储
Docker
Nginx
```
但V1.0只选择其中一种技术路线。
不要双后端技术栈并存。
---
# 第七章 数据库选择
推荐:
> PostgreSQL
原因:
- 成熟稳定
- 事务能力强
- JSON支持良好
- 索引能力成熟
- 数据一致性好
- 后续扩展空间大
- 开源无授权成本
---
# 第八章 Redis用途
Redis用于:
- Session
- Token辅助状态
- 登录验证码
- API限流
- 短期缓存
- 推荐缓存
- 未读消息计数
- 在线状态
- 防重复提交
- 分布式锁
- 临时幂等Key
Redis不能作为核心永久业务数据唯一存储。
---
# 第九章 对象存储
用于保存:
- 用户头像
- 用户生活照片
- 活动封面
- 举报证据
- 意见反馈图片
建议统一使用:
> S3兼容接口。
实际部署可以:
- MinIO
- 国内对象存储服务
根据部署环境选择。
---
# 第十章 文件访问原则
用户上传文件:
```text id="file001"
客户端
↓
获取上传凭证
↓
上传对象存储
↓
返回fileKey
↓
业务接口保存fileKey
```
不要让大文件全部经过业务服务器中转。
---
# 第十一章 图片访问安全
用户隐私图片不建议永久公开URL。
建议采用:
> 私有Bucket + 临时签名URL。
例如:
```text id="file002"
GET /media/{fileId}/url
```
服务端判断当前用户是否有权限访问。
再返回:
> 短时有效签名URL。
---
# 第十二章 核心业务模块
V1.0后端拆为:
```text id="modules001"
01 Auth认证模块
02 User用户模块
03 Verification实名认证模块
04 Profile婚恋资料模块
05 Review人工审核模块
06 Match匹配推荐模块
07 Relationship关系模块
08 Messaging聊天模块
09 Activity活动模块
10 Matchmaker公益红娘模块
11 Risk举报风控模块
12 Notification通知模块
13 Organization组织模块
14 Permission权限模块
15 Analytics统计模块
16 Audit操作审计模块
17 Config业务配置模块
```
---
# 第十三章 Auth认证模块
模块职责:
- 微信登录
- Session建立
- 手机号绑定
- Token签发
- Token刷新
- 登出
- Session失效
- 后台工作人员登录
---
# 第十四章 微信用户登录流程
```text id="auth001"
微信小程序
↓
wx.login()
↓
获取code
↓
POST /auth/wechat/login
↓
后端调用微信接口
↓
获取openid / unionid
↓
查找用户
↓
新用户创建基础账号
↓
签发Access Token
↓
返回用户当前状态
```
---
# 第十五章 用户登录响应
建议返回:
```json id="auth002"
{
"accessToken": "...",
"expiresIn": 7200,
"user": {
"id": "u_xxx",
"phoneBound": true,
"verified": true,
"profileStatus": "completed",
"reviewStatus": "approved",
"accountStatus": "normal",
"relationshipStatus": "searching"
}
}
```
前端据此进入对应页面。
---
# 第十六章 Token策略
建议:
> Access Token + Refresh Token
或:
> 服务端Session + 短Token
根据技术栈决定。
核心原则:
- 可撤销
- 可过期
- 可识别设备
- 封禁后立即失效
---
# 第十七章 工作人员登录
红娘端和管理后台使用独立认证入口。
例如:
```text id="auth003"
POST /operator/auth/login
```
不要和普通用户登录完全混合。
工作人员账号必须包含:
- operatorId
- organizationId
- roles
- permissions
- accountStatus
---
# 第十八章 User用户模块
User只负责账号层数据。
例如:
```text id="user001"
user_id
wechat_openid
unionid
phone
account_status
relationship_status
created_at
updated_at
last_login_at
```
不要把所有婚恋资料全部塞进users表。
---
# 第十九章 User与Profile分离
建议:
```text id="user002"
users
```
存:
> 账号身份。
```text id="user003"
user_profiles
```
存:
> 婚恋公开资料。
```text id="user004"
user_private_profiles
```
存:
> 更敏感的数据。
分离可以减少敏感数据误访问风险。
---
# 第二十章 Verification实名认证模块
职责:
- 接收实名认证请求
- 对接实名认证服务
- 判断成年人
- 保存认证结果
- 处理认证失败
- 管理认证状态
---
# 第二十一章 实名数据原则
实名信息属于高度敏感信息。
必须:
- 加密存储
- 严格权限
- 默认脱敏
- 查询留痕
- 不能进入普通业务DTO
- 不进入普通日志
---
# 第二十二章 实名认证状态
```text id="verify001"
not_verified
verifying
verified
failed
manual_review
```
---
# 第二十三章 实名成功流程
```text id="verify002"
用户提交姓名+身份证
↓
调用实名认证提供方
↓
一致
↓
校验年龄 >= 18
↓
保存实名结果
↓
更新用户verified
↓
进入资料完善
```
---
# 第二十四章 未成年人处理
如果未满18周岁:
> 不允许使用婚恋匹配服务。
服务端必须硬限制。
不能只依靠前端年龄判断。
---
# 第二十五章 Profile婚恋资料模块
职责:
- 个人资料
- 生活资料
- 兴趣标签
- 个人介绍
- 婚恋态度
- 照片
- 择偶条件
- 资料完整度
- 隐私设置
---
# 第二十六章 Profile拆分建议
建议主要数据表:
```text id="profile001"
user_profiles
user_preferences
user_interests
user_photos
user_privacy_settings
```
---
# 第二十七章 user_profiles
包含:
```text id="profile002"
user_id
display_name
gender
birth_date
height
region_code
marital_status
children_status
education
occupation_category
work_region
smoking_status
drinking_status
long_term_danyang
future_danyang
relationship_goal
marriage_plan
self_intro
profile_completion
```
---
# 第二十八章 用户前台称呼
display_name建议系统生成。
例如:
实名:
> 王晓丽
前台:
> 王女士
不直接展示完整姓名。
可以保存:
```text id="profile003"
display_name = 王女士
```
或动态计算。
---
# 第二十九章 user_preferences
存择偶条件。
例如:
```text id="profile004"
min_age
max_age
age_priority
min_height
max_height
height_priority
region_scope
region_priority
marital_statuses
marital_priority
min_education
education_priority
children_acceptance
children_priority
smoking_preference
drinking_preference
settlement_preference
marriage_plan_preference
```
---
# 第三十章 Priority枚举
```text id="profile005"
required
preferred
```
前端:
> 必须符合
> 最好符合
---
# 第三十一章 user_photos
字段:
```text id="profile006"
id
user_id
file_key
photo_type
sort_order
review_status
created_at
```
photo_type:
```text id="profile007"
avatar
lifestyle
```
---
# 第三十二章 用户照片审核
图片状态:
```text id="profile008"
pending
approved
need_edit
rejected
```
未审核照片:
> 不能进入其他用户可见范围。
---
# 第三十三章 user_interests
不要为每个兴趣增加一列。
建议:
```text id="profile009"
user_id
interest_code
```
兴趣定义:
```text id="profile010"
interest_dictionary
```
后台可维护启用状态。
---
# 第三十四章 Review人工审核模块
职责:
- 用户首次资料审核
- 修改资料重新审核
- 审核任务领取
- 审核结果
- 退回原因
- 审核历史
- 审核员操作记录
---
# 第三十五章 审核任务模型
建议:
```text id="review001"
review_tasks
```
字段:
```text id="review002"
id
user_id
review_type
status
assigned_operator_id
submitted_at
started_at
completed_at
```
---
# 第三十六章 review_type
支持:
```text id="review003"
initial_profile
profile_change
photo_change
marital_status_change
risk_recheck
```
---
# 第三十七章 审核状态
```text id="review004"
pending
processing
approved
need_edit
rejected
```
---
# 第三十八章 审核明细
建议:
```text id="review005"
review_items
```
例如:
```text id="review006"
avatar
lifestyle_photos
basic_profile
self_intro
relationship_profile
```
每项:
```text id="review007"
approved
need_edit
abnormal
```
---
# 第三十九章 资料审核流程
```text id="review008"
用户提交
↓
创建review_task
↓
进入待审核
↓
审核员领取
↓
逐项审核
↓
全部通过?
├─ 是 → Profile Review = approved
└─ 否
├─ 可修改 → need_edit
└─ 严重问题 → rejected / risk
```
---
# 第四十章 审核并发控制
两个审核员不能同时处理同一个任务。
领取时:
> 数据库乐观锁 / Redis锁。
保证:
```text id="review009"
pending → processing
```
原子更新。
---
# 第四十一章 Match匹配推荐模块
职责:
- 候选池生成
- 双向硬条件过滤
- 综合评分
- 每日推荐
- 找对象搜索
- 推荐理由
- 排除规则
- 推荐历史
---
# 第四十二章 匹配流程总览
```text id="match001"
用户A
↓
获取可见用户池
↓
排除不可推荐用户
↓
A条件检查B
↓
B条件检查A
↓
必须条件均通过
↓
计算Preferred得分
↓
业务权重评分
↓
排序
↓
生成推荐理由
↓
返回候选人
```
---
# 第四十三章 第一层候选过滤
必须排除:
- 自己
- 封禁用户
- 风险审核中的用户
- 审核未通过用户
- 暂停推荐用户
- 成功牵手用户
- 已退出服务用户
- 双方拉黑关系
- 明确不喜欢关系
- 重复推荐冷却期用户
---
# 第四十四章 双向硬条件
必须同时满足:
```text id="match002"
A required conditions accept B
AND
B required conditions accept A
```
否则:
> 不进入候选池。
---
# 第四十五章 推荐评分
V1可以100分。
配置来自:
```text id="match003"
match_rule_config
```
示例:
```text id="match004"
age 15
region 15
marital 10
children 10
education 5
height 5
marriage_plan 15
settlement 10
lifestyle 10
interest 5
```
---
# 第四十六章 推荐等级
后端可返回:
```text id="match005"
high
medium
normal
```
前端映射:
```text id="match006"
high → 很合适
medium → 比较合适
normal → 值得了解
```
---
# 第四十七章 推荐理由
后端直接生成结构化理由。
例如:
```json id="match007"
[
{
"code": "AGE_MUTUAL_MATCH",
"text": "年龄符合双方要求"
},
{
"code": "SAME_CITY",
"text": "都希望长期在丹阳生活"
}
]
```
不要让前端自己分析条件生成理由。
---
# 第四十八章 推荐历史
建议:
```text id="match008"
recommendation_records
```
字段:
```text id="match009"
user_id
target_user_id
source
score
shown_at
action
```
source:
```text id="match010"
daily
discover
matchmaker
activity
```
---
# 第四十九章 Relationship关系模块
这是核心模块之一。
负责:
- 喜欢
- 不合适
- 双向喜欢
- 解除匹配
- 拉黑
- 正在了解
- 成功牵手关系
---
# 第五十章 用户关系表
建议:
```text id="relation001"
user_relations
```
按方向存储。
例如:
```text id="relation002"
user_id
target_user_id
relation_type
created_at
```
relation_type:
```text id="relation003"
liked
passed
blocked
```
---
# 第五十一章 双向匹配表
独立:
```text id="relation004"
matches
```
字段:
```text id="relation005"
id
user_a_id
user_b_id
status
matched_at
unmatched_at
```
---
# 第五十二章 Match status
```text id="relation006"
active
getting_to_know
unmatched
successful
```
---
# 第五十三章 喜欢流程
```text id="relation007"
A喜欢B
↓
写入liked
↓
检查 B是否已like A
↓
没有
→ 返回 liked
有
↓
创建matches
↓
触发双向匹配通知
↓
允许建立聊天
```
---
# 第五十四章 双向匹配创建幂等
必须保证:
> A和B只能存在一个有效match。
使用:
- 标准化user_a/user_b顺序
- 唯一索引
例如:
```text id="relation008"
user_a_id = min(A,B)
user_b_id = max(A,B)
```
---
# 第五十五章 不合适
pass后:
记录:
```text id="relation009"
user_id → target_id = passed
```
推荐模块自动排除。
冷却期:
由配置决定。
---
# 第五十六章 拉黑
block是强关系。
拉黑后:
- 关闭聊天
- 不再推荐
- 不再搜索可见
- 不再红娘推荐
- 不再活动匹配
---
# 第五十七章 解除匹配
解除:
```text id="relation010"
match.status = unmatched
```
同时:
```text id="relation011"
conversation.can_send = false
```
不删除历史数据。
---
# 第五十八章 成功牵手
如果一方发起:
创建:
```text id="relation012"
relationship_success_requests
```
状态:
```text id="relation013"
pending
confirmed
declined
```
双方确认后:
```text id="relation014"
match.status = successful
```
并更新双方:
```text id="relation015"
relationship_status = matched_successfully
```
---
# 第五十九章 Messaging聊天模块
职责:
- 会话创建
- 消息发送
- 消息历史
- 图片消息
- 未读数
- 已读状态
- 风险关键词检测
- WebSocket推送
---
# 第六十章 会话创建
双向match生成时:
可以:
> 延迟创建conversation。
用户第一次点击聊天时创建。
或:
> match成功立即创建。
V1推荐:
> match成功即创建conversation。
逻辑更简单。
---
# 第六十一章 conversation表
```text id="msg001"
conversations
```
字段:
```text id="msg002"
id
match_id
status
last_message_id
last_message_at
created_at
```
---
# 第六十二章 conversation_members
即使当前只有两人,也建议:
```text id="msg003"
conversation_members
```
字段:
```text id="msg004"
conversation_id
user_id
last_read_message_id
unread_count
can_send
```
便于后续扩展。
---
# 第六十三章 messages表
```text id="msg005"
id
conversation_id
sender_id
message_type
content
file_id
status
created_at
```
message_type:
```text id="msg006"
text
image
system
risk_notice
```
---
# 第六十四章 消息发送流程
```text id="msg007"
客户端发送
↓
校验conversation
↓
校验双方match有效
↓
校验双方未拉黑
↓
校验账号状态
↓
风险检测
↓
保存message
↓
更新conversation
↓
更新未读数
↓
WebSocket推送
```
---
# 第六十五章 WebSocket认证
建立连接:
> 必须带有效身份凭证。
不能只传:
> userId
否则容易冒充用户。
---
# 第六十六章 消息幂等
客户端发送:
```text id="msg008"
clientMessageId
```
服务端:
> user_id + clientMessageId 唯一。
弱网重试时防止重复发送。
---
# 第六十七章 聊天风险检测
V1采用:
> 关键词规则 + 简单频率规则 + 举报联动。
例如:
- 转账
- 借钱
- 投资
- 赌博
- 银行卡
- 高收益
命中:
> 插入RiskNotice。
不默认阻断正常消息。
---
# 第六十八章 严重风控
明确高风险规则可:
- 提高risk score
- 标记会话
- 进入人工风控列表
但:
> 默认不允许工作人员随意查看完整聊天。
---
# 第六十九章 Activity活动模块
职责:
- 创建活动
- 发布
- 报名
- 报名审核
- 人数限制
- 签到
- 活动反馈
- 活动后意向匹配
---
# 第七十章 activities表
核心字段:
```text id="activity001"
id
title
cover_file_id
description
organizer_org_id
coorganizer_text
start_at
end_at
location_name
location_address
male_limit
female_limit
total_limit
min_age
max_age
registration_start_at
registration_end_at
need_review
status
```
---
# 第七十一章 活动状态
```text id="activity002"
draft
registration_open
registration_closed
ongoing
ended
cancelled
```
---
# 第七十二章 registrations
```text id="activity003"
activity_registrations
```
字段:
```text id="activity004"
activity_id
user_id
status
registered_at
reviewed_by
reviewed_at
reject_reason
checkin_status
checkin_at
```
唯一索引:
```text id="activity005"
activity_id + user_id
```
防重复报名。
---
# 第七十三章 报名人数并发控制
报名时必须防超卖。
推荐:
> 数据库事务 + 行锁/原子更新。
不能:
先查86/100。
再INSERT。
否则并发时会超人数。
---
# 第七十四章 男女名额
如果设置:
```text id="activity006"
male_limit
female_limit
```
报名/审核时必须分别检查。
---
# 第七十五章 活动签到
签到使用:
> 短时有效二维码Token。
不要二维码直接暴露userId。
二维码内容:
```text id="activity007"
signedCheckinToken
```
服务端解析后:
- 校验活动
- 校验用户
- 校验报名状态
- 防重复签到
---
# 第七十六章 活动反馈
建议:
```text id="activity008"
activity_feedback
```
包含:
- satisfaction
- join_again
- interested_user_id
- comment
interested_user_id:
> 只能从本活动参加且符合可见条件用户中选择。
---
# 第七十七章 活动后意向
如果:
A选择B。
B也选择A。
系统可以:
> 生成活动来源的match建议。
但仍需要遵守:
> 双方同意后才能聊天。
---
# 第七十八章 Matchmaker公益红娘模块
职责:
- 用户申请
- 服务分配
- 红娘接单
- 跟进
- 系统候选
- 人工推荐
- 服务完成
---
# 第七十九章 matchmaker_services
字段:
```text id="mm001"
id
user_id
service_type
description
status
organization_id
assigned_operator_id
created_at
assigned_at
completed_at
```
---
# 第八十章 红娘服务类型
```text id="mm002"
recommend_partner
review_preference
contact_intention
join_activity
no_match_help
chat_help
other
```
---
# 第八十一章 红娘状态
```text id="mm003"
submitted
assigned
in_service
waiting_user
completed
cancelled
```
---
# 第八十二章 红娘候选查询
调用:
> Match模块。
而不是红娘模块自己重新写一套匹配算法。
例如:
```text id="mm004"
MatchService.findCandidatesForMatchmaker(userId)
```
---
# 第八十三章 红娘推荐
建议表:
```text id="mm005"
matchmaker_recommendations
```
字段:
```text id="mm006"
service_id
user_id
target_user_id
operator_id
reason
status
created_at
```
---
# 第八十四章 红娘权限边界
红娘可以:
- 查看必要婚恋资料
- 查看择偶条件
- 查看服务记录
- 推荐候选人
红娘不能默认:
- 查看身份证完整号码
- 查看用户完整聊天
- 修改用户喜欢关系
- 替用户点击喜欢
- 强行建立match
---
# 第八十五章 Risk举报风控模块
职责:
- 举报
- 风险规则
- 风险评分
- 风险账户
- 处置
- 申诉
- 操作留痕
---
# 第八十六章 reports举报表
```text id="risk001"
reports
```
字段:
```text id="risk002"
id
reporter_user_id
target_user_id
report_type
description
status
risk_level
created_at
processed_by
processed_at
result
```
---
# 第八十七章 举报证据
独立:
```text id="risk003"
report_evidences
```
保存:
> fileId。
访问严格权限控制。
---
# 第八十八章 举报类型
```text id="risk004"
fake_profile
marital_status_suspected
harassment
sexual_content
advertising
fraud
money_inducement
impersonation
other
```
---
# 第八十九章 风险评分
建议:
```text id="risk005"
user_risk_profiles
```
字段:
```text id="risk006"
user_id
score
level
last_calculated_at
```
---
# 第九十章 风险事件
```text id="risk007"
risk_events
```
例如:
```text id="risk008"
report_fraud
multiple_blocks
high_frequency_likes
contact_spam
money_keyword
manual_flag
```
---
# 第九十一章 风险等级
```text id="risk009"
normal
watch
high
critical
```
前台通常只关心:
> 是否受限。
后台显示详细等级。
---
# 第九十二章 风控处置
支持:
```text id="risk010"
warning
feature_limit
temporary_suspend
ban
manual_investigation
```
---
# 第九十三章 风控处置原则
自动规则可以:
> 标记、提醒、限制高风险行为。
永久封禁尽量:
> 人工确认。
明确机器攻击、恶意注册等例外。
---
# 第九十四章 Notification通知模块
负责统一发送:
- 系统通知
- 审核结果
- 双向匹配
- 红娘推荐
- 活动报名结果
- 活动提醒
- 风险通知
- 账号状态通知
---
# 第九十五章 notifications表
字段:
```text id="notify001"
id
user_id
type
title
content
business_type
business_id
read_status
created_at
```
---
# 第九十六章 通知类型
```text id="notify002"
review
match
matchmaker
activity
risk
account
system
```
---
# 第九十七章 微信订阅消息
如果后续使用微信订阅消息:
Notification模块统一封装。
业务模块只调用:
```text id="notify003"
NotificationService.send()
```
不要每个模块自己对接微信API。
---
# 第九十八章 Organization组织模块
职责:
- 妇联
- 工会
- 公益服务中心
- 志愿者团队
- 其他合作机构
---
# 第九十九章 organizations表
```text id="org001"
id
name
type
contact_name
contact_phone
status
created_at
```
---
# 第一百章 operators工作人员
字段:
```text id="org002"
id
organization_id
name
phone
username
password_hash
status
last_login_at
```
---
# 第一百零一章 Permission权限模块
建议采用:
> RBAC
包含:
```text id="perm001"
roles
permissions
role_permissions
operator_roles
```
---
# 第一百零二章 权限粒度
例如:
```text id="perm002"
user.view
user.sensitive.view
user.status.change
review.view
review.process
activity.view
activity.create
activity.review_registration
matchmaker.view
matchmaker.assign
matchmaker.service
risk.report.view
risk.report.process
risk.user.ban
organization.manage
permission.manage
analytics.view
```
---
# 第一百零三章 后端权限校验
每个敏感接口都必须:
> 服务端校验权限。
前端隐藏菜单不能替代权限。
---
# 第一百零四章 敏感数据访问审计
只要访问:
- 完整身份证
- 实名原始数据
- 举报证据
- 特殊敏感记录
必须生成:
```text id="audit001"
sensitive_access_logs
```
---
# 第一百零五章 Audit操作审计模块
需要记录:
- 审核
- 用户封禁
- 用户解封
- 权限修改
- 红娘分配
- 活动删除
- 举报处理
- 敏感资料查看
- 系统规则修改
---
# 第一百零六章 audit_logs
字段建议:
```text id="audit002"
id
operator_id
organization_id
action
resource_type
resource_id
before_data
after_data
ip
user_agent
created_at
```
before/after注意:
> 敏感字段必须脱敏。
---
# 第一百零七章 Config配置模块
V1只做简单业务配置。
例如:
```text id="config001"
daily_recommendation_limit
max_profile_photos
max_interest_tags
recommendation_cooldown_days
match_score_threshold
activity_enabled
matchmaker_enabled
chat_image_enabled
```
---
# 第一百零八章 Match规则配置
匹配权重建议独立表:
```text id="config002"
match_rule_configs
```
每次修改:
> 必须记录审计日志。
---
# 第一百零九章 Analytics统计模块
不要V1就建设复杂数据仓库。
先做:
> 业务聚合统计。
---
# 第一百一十章 核心统计
用户:
```text id="analytics001"
注册
实名
审核通过
活跃
男女比例
年龄分布
```
匹配:
```text id="analytics002"
推荐曝光
详情查看
喜欢
双向匹配
聊天
正在了解
成功牵手
```
公益服务:
```text id="analytics003"
红娘申请
人工推荐
活动次数
报名人数
签到人数
```
安全:
```text id="analytics004"
举报
高风险账户
封禁
```
---
# 第一百一十一章 数据统计实现
初期可采用:
- SQL聚合
- 定时汇总表
- Redis短缓存
不要:
> 每次打开后台都实时全表COUNT数百万数据。
---
# 第一百一十二章 API统一设计
建议:
```text id="api001"
/api/v1/
```
用户:
```text id="api002"
/api/v1/auth
/api/v1/me
/api/v1/profile
/api/v1/matches
/api/v1/messages
/api/v1/activities
/api/v1/matchmaker
/api/v1/reports
```
后台:
```text id="api003"
/api/v1/operator/
/api/v1/admin/
```
---
# 第一百一十三章 API响应格式
建议统一:
```json id="api004"
{
"success": true,
"code": "OK",
"message": "success",
"data": {}
}
```
错误:
```json id="api005"
{
"success": false,
"code": "PROFILE_NOT_APPROVED",
"message": "当前资料尚未通过审核",
"data": null
}
```
---
# 第一百一十四章 分页规范
推荐Cursor分页用于:
- 聊天
- 推荐列表
- 动态变化较多列表
普通后台:
> page + pageSize
例如:
```text id="api006"
?page=1&pageSize=20
```
---
# 第一百一十五章 幂等接口
以下必须幂等:
- 喜欢
- 不合适
- 报名
- 举报提交
- 资料提交审核
- 红娘申请
- 消息发送
- 签到
---
# 第一百一十六章 防重复提交
推荐Header:
```text id="api007"
Idempotency-Key
```
或业务唯一Key。
例如活动:
```text id="api008"
activity_id + user_id
```
数据库唯一约束兜底。
---
# 第一百一十七章 事务边界
例如双向匹配:
必须一个事务内:
```text id="tx001"
写liked
检查对方liked
创建match
创建conversation
```
如果通知失败:
> 不回滚match。
通知采用事务后发送或异步处理。
---
# 第一百一十八章 内部事件机制
虽然V1是单体,也建议使用:
> Domain Event / Application Event
例如:
```text id="event001"
ProfileApproved
MutualMatchCreated
ActivityRegistrationApproved
UserBanned
RelationshipSucceeded
```
---
# 第一百一十九章 事件用途
例如:
```text id="event002"
MutualMatchCreated
├→ 创建系统通知
├→ 更新统计
└→ 推送WebSocket
```
业务主流程不要直接塞所有副作用。
---
# 第一百二十章 是否需要MQ
V1可以:
> 暂不强制引入MQ。
先使用:
- 本地事务
- 应用事件
- 定时补偿任务
如果后期:
> 通知、聊天、风控、统计量明显提升
再引入RabbitMQ/Kafka。
---
# 第一百二十一章 定时任务
V1需要:
- 活动状态更新
- 活动提醒
- 推荐每日重置
- 风险规则重算
- 过期Token/临时数据清理
- 统计汇总
- 红娘超时跟进提醒
- 审核任务超时提醒
---
# 第一百二十二章 定时任务原则
必须支持:
> 幂等。
同一个任务重复执行不能产生重复:
- 通知
- 匹配
- 报名
- 数据
---
# 第一百二十三章 日志体系
至少分:
```text id="log001"
application log
security log
audit log
access log
error log
```
---
# 第一百二十四章 日志禁止记录
禁止:
- 完整身份证
- 完整手机号
- 密码
- Token
- 用户聊天全文
- 举报证据原始URL
---
# 第一百二十五章 数据脱敏
手机号:
```text id="privacy001"
138****1234
```
身份证:
```text id="privacy002"
320***********1234
```
姓名:
后台非必要场景可:
```text id="privacy003"
王**
```
---
# 第一百二十六章 数据加密
敏感字段建议:
> 应用层加密或数据库透明加密能力。
至少包括:
- 身份证号码
- 认证原始响应敏感字段
- 部分联系方式
密码:
> Argon2 / bcrypt等强哈希。
绝不能可逆存密码。
---
# 第一百二十七章 数据访问原则
采用:
> 最小权限。
例如红娘查询用户时:
返回:
```text id="privacy004"
MatchmakerUserDTO
```
而不是:
> UserEntity全部字段。
---
# 第一百二十八章 DTO分离
建议:
```text id="dto001"
PublicUserProfileDTO
SelfUserProfileDTO
MatchmakerUserProfileDTO
AdminUserDTO
SensitiveUserDTO
```
不同场景不同DTO。
这是防止敏感数据泄漏的重要手段。
---
# 第一百二十九章 数据库索引原则
重点建立索引:
```text id="db001"
users.phone
users.wechat_openid
user_profiles.gender
user_profiles.region_code
user_profiles.age/birth_date
user_profiles.review_status
user_relations(user_id,target_user_id)
matches(user_a_id,user_b_id)
messages(conversation_id,created_at)
activity_registrations(activity_id,user_id)
reports(target_user_id,status)
review_tasks(status,submitted_at)
```
---
# 第一百三十章 匹配查询优化
不要每次:
> 全库扫描所有用户。
初期可:
1. SQL初步条件过滤
2. 拉出小候选池
3. 应用层评分排序
例如:
```text id="match011"
性别
年龄大范围
地区
审核状态
婚恋状态
```
先在数据库过滤。
---
# 第一百三十一章 推荐缓存
每日推荐可缓存:
```text id="cache001"
recommendations:{userId}:{date}
```
但用户状态变化时:
例如拉黑/封禁:
> 读取时仍要二次校验有效性。
缓存不能覆盖安全规则。
---
# 第一百三十二章 数据一致性原则
核心状态:
> PostgreSQL为唯一真相。
Redis:
> 加速。
前端:
> 展示缓存。
---
# 第一百三十三章 备份策略
至少:
- 每日数据库自动备份
- 定期完整备份
- 对象存储版本/备份策略
- 备份文件加密
- 定期恢复测试
备份不能只是:
> 有备份文件。
必须确认:
> 能恢复。
---
# 第一百三十四章 Docker部署结构
V1建议:
```text id="deploy001"
nginx
backend
postgresql
redis
object-storage/minio
```
如果使用云对象存储:
> 不部署MinIO。
---
# 第一百三十五章 开发环境
推荐:
```text id="deploy002"
docker compose
```
一键启动:
- DB
- Redis
- MinIO
- Backend
前端单独开发。
---
# 第一百三十六章 测试环境
与生产结构尽量一致。
但:
- 独立数据库
- 独立Redis
- 独立对象存储Bucket
- 独立微信配置
禁止:
> 测试环境连接生产数据库。
---
# 第一百三十七章 生产环境
初期可以:
```text id="deploy003"
1台应用服务器
+
托管数据库/独立数据库
+
Redis
+
对象存储
```
根据用户量再扩容。
---
# 第一百三十八章 后端无状态化
业务Backend尽量:
> 无状态。
Session和临时状态放Redis/数据库。
这样后期可以:
> 从1实例扩到2实例。
---
# 第一百三十九章 健康检查
提供:
```text id="ops001"
/health
/ready
```
检查:
- 应用
- 数据库
- Redis
对象存储异常可降级说明。
---
# 第一百四十章 基础限流
以下接口必须限流:
- 登录
- 验证码
- 实名认证
- 喜欢
- 消息发送
- 举报
- 图片上传凭证
- 后台登录
---
# 第一百四十一章 防刷喜欢
例如:
> 短时间异常大量喜欢
触发:
- 限速
- risk event
- 人工关注
但正常用户不要设置过低限制。
---
# 第一百四十二章 防刷消息
同一用户:
> 极高频连续消息
可临时限速。
防止:
- 广告机器人
- 骚扰
- 脚本攻击
---
# 第一百四十三章 CSRF/XSS/SQL注入
Web后台必须:
- 防CSRF
- 输入输出转义
- ORM/参数化SQL
- CSP等基础Web安全
小程序也必须验证:
> 所有用户输入都是不可信数据。
---
# 第一百四十四章 图片安全
上传:
- MIME校验
- 文件头校验
- 大小限制
- 分辨率限制
- 病毒/恶意文件检查能力预留
不能只信扩展名。
---
# 第一百四十五章 个人介绍内容处理
建议:
> 文本内容过滤 + 人工审核。
不要直接支持:
> HTML。
只保存纯文本。
避免XSS和联系方式嵌入。
---
# 第一百四十六章 删除策略
业务数据不要直接物理删除。
建议:
> soft delete + 状态变更。
特别是:
- 用户
- 举报
- 审核
- 匹配
- 活动
- 红娘服务
保留审计能力。
---
# 第一百四十七章 用户注销
注销后:
- 账号关闭
- 停止公开展示
- 停止推荐
- 关闭聊天能力
- 按隐私和法律要求处理个人数据
不是:
> DELETE users WHERE id=...
---
# 第一百四十八章 业务状态不可前端决定
例如:
前端提交:
```text id="state001"
relationshipStatus = matched_successfully
```
服务端不能直接相信。
必须验证:
- 请求合法
- 对方确认
- 当前match有效
---
# 第一百四十九章 后端统一状态机思想
V1无需引入复杂状态机框架。
但关键业务必须明确允许迁移。
例如审核:
```text id="state002"
pending
→ processing
→ approved
pending
→ processing
→ need_edit
```
不能:
```text id="state003"
approved
→ pending
```
随意变化。
---
# 第一百五十章 活动状态迁移
```text id="state004"
draft
→ registration_open
→ registration_closed
→ ongoing
→ ended
```
取消:
```text id="state005"
draft / registration_open
→ cancelled
```
---
# 第一百五十一章 红娘状态迁移
```text id="state006"
submitted
→ assigned
→ in_service
→ completed
```
允许:
```text id="state007"
in_service
→ waiting_user
→ in_service
```
---
# 第一百五十二章 Match状态迁移
```text id="state008"
active
→ getting_to_know
→ successful
```
或者:
```text id="state009"
active
→ unmatched
```
---
# 第一百五十三章 风控状态迁移
```text id="state010"
normal
→ reviewing_risk
→ normal
```
或:
```text id="state011"
reviewing_risk
→ limited
→ suspended
→ banned
```
根据处置决定。
---
# 第一百五十四章 核心数据流:用户注册
```text id="flow001"
微信登录
↓
Auth
↓
User创建
↓
手机号
↓
Verification实名
↓
Profile完善
↓
Review
↓
审核通过
↓
进入Match候选池
```
---
# 第一百五十五章 核心数据流:匹配
```text id="flow002"
Match候选计算
↓
返回推荐
↓
A喜欢B
↓
Relationship写like
↓
检测B→A
↓
Mutual Match
↓
创建Conversation
↓
Notification
↓
允许Messaging
```
---
# 第一百五十六章 核心数据流:红娘
```text id="flow003"
用户申请
↓
Matchmaker Service
↓
分配红娘
↓
调用Match候选
↓
红娘人工筛选
↓
Recommendation
↓
Notification用户
↓
用户自行Like/Pass
```
---
# 第一百五十七章 核心数据流:活动
```text id="flow004"
后台创建活动
↓
Activity发布
↓
用户报名
↓
Registration
↓
审核
↓
通知
↓
现场签到
↓
Feedback
↓
双方意向
↓
Relationship
```
---
# 第一百五十八章 核心数据流:举报
```text id="flow005"
用户举报
↓
Risk Report
↓
生成Risk Event
↓
更新风险评分
↓
人工处理
↓
处置用户
↓
User Account Status变化
↓
Match / Messaging立即失效
```
---
# 第一百五十九章 关键业务验收标准
## 用户
审核未通过:
> 绝不能进入推荐池。
## 匹配
硬条件:
> 必须双向满足。
## 聊天
没有Mutual Match:
> 绝不能创建有效聊天。
## 拉黑
双方:
> 立即不可联系。
## 红娘
> 不能替用户建立喜欢关系。
## 活动
> 不能超人数报名。
## 风控
账号受限:
> 所有敏感业务实时受影响。
---
# 第一百六十章 V1.0不建议建设的后端能力
暂不建设:
- AI大模型匹配
- 知识图谱婚恋匹配
- ElasticSearch集群
- Kafka集群
- Kubernetes
- 微服务注册中心
- 服务网格
- 大数据平台
- 数据湖
- 推荐机器学习平台
- 实时特征平台
- 视频RTC服务
- 直播服务
- 礼物支付系统
- 会员计费系统
这些都不属于当前公益婚恋V1.0的核心目标。
---
# 第一百六十一章 后端研发优先级
## P0
必须首先完成:
```text id="priority001"
Auth
User
Verification
Profile
Review
Match
Relationship
Messaging
Permission
Audit
```
---
## P1
随后完成:
```text id="priority002"
Activity
Matchmaker
Notification
Risk
Organization
```
---
## P2
最后完善:
```text id="priority003"
Analytics
Config
运营统计
自动化提醒
```
---
# 第一百六十二章 后端接口开发顺序
建议按完整用户闭环:
```text id="priority004"
登录
↓
实名
↓
资料
↓
审核
↓
推荐
↓
喜欢
↓
双向匹配
↓
聊天
```
先跑通。
然后:
```text id="priority005"
红娘
↓
活动
↓
举报风控
↓
统计
```
---
# 第一百六十三章 测试策略
至少包括:
- 单元测试
- Service业务测试
- API集成测试
- 数据库事务测试
- 权限测试
- 状态机测试
- 并发测试
- 风控测试
---
# 第一百六十四章 必须重点测试的并发场景
1. A、B同时互相点赞
2. 同一用户重复点击喜欢
3. 多人抢最后一个活动名额
4. 两个审核员同时领取任务
5. 两个管理员同时处理同一举报
6. 同一消息弱网重复发送
7. 同一签到码重复扫码
---
# 第一百六十五章 必须重点测试的权限场景
- 红娘查看身份证
- 活动志愿者查看婚恋资料
- 审核员封禁用户
- 普通管理员修改权限
- 无权限用户手工请求敏感API
- 非会话用户读取聊天记录
必须全部拒绝。
---
# 第一百六十六章 性能目标建议
V1.0不追求夸张指标。
合理目标:
普通API:
> P95 < 500ms
推荐接口:
> P95 < 1.5s
后台列表:
> P95 < 1s
消息发送:
> 正常网络下接近实时。
---
# 第一百六十七章 可扩展策略
未来用户量提升后,优先拆出的模块:
第一:
> Messaging
第二:
> Match
第三:
> Notification
第四:
> Analytics
而:
- User
- Profile
- Organization
可以更长时间留在核心业务应用中。
---
# 第一百六十八章 从单体升级到服务化原则
模块今天就必须:
- 数据职责清晰
- Service接口清晰
- 不跨模块乱SQL
- Domain状态清晰
这样未来才能:
> 低成本拆服务。
否则今天省一点代码,未来会付更高成本。
---
# 第一百六十九章 V1.0最终后端架构
建议正式采用:
```text id="final001"
微信小程序
公益红娘Web
管理后台Web
↓
Nginx
↓
Spring Boot / NestJS 模块化单体
│
├── Auth
├── User
├── Verification
├── Profile
├── Review
├── Match
├── Relationship
├── Messaging
├── Activity
├── Matchmaker
├── Risk
├── Notification
├── Organization
├── Permission
├── Analytics
└── Audit
↓
PostgreSQL + Redis + Object Storage
```
---
# 第一百七十章 最终设计原则
整个后端必须遵守以下原则:
> **账号、实名、婚恋资料分层。**
> **匹配必须双向。**
> **聊天必须建立在双向喜欢基础上。**
> **人工红娘只能辅助,不能替用户做决定。**
> **敏感信息默认不可见。**
> **后台任何高风险操作必须有权限和审计。**
> **核心业务数据以数据库为唯一真相。**
> **Redis只做加速,不做业务真相。**
> **先模块化单体,后按业务量拆服务。**
> **V1.0以稳定、简单、可维护为第一优先级。**
最终后端架构不是为了展示技术复杂度,而是为了保证:
> **一个真实用户能够安全完成“注册—审核—匹配—聊天—红娘/活动—成功牵手”的完整闭环,并且平台工作人员能够低成本、可追溯地完成运营和服务。**