依据《善缘丹阳 V1.1 红娘角色权限正式决策与开发规则》DEC-MATCHMAKER-005 最小必要原则 与 §5.2 字段级隐私,ZC-MM-005 范围=「读接口行级数据范围统一接入判定器 + 字段白名单 + 组长团队脱敏统计」。承接 ZC-MM-002 落地的 matchmaker_assignments 事实源与 ServiceAssignmentPolicy 判定器。 E1 双轨切纯判定器(不留回退): - assertServiceAccess 纯化(删 assigned_operator_id 回退分支),判定器成唯一事实源 - getServiceDetail 删 viewerIsOwner 双态与「非负责人脱敏详情」整段 E2 非负责人防探测 404: - ServiceAssignmentPolicy.assertActiveAssignmentOrNotFound:无生效分配→先落 DATA_SCOPE_DENIED 审计再抛 NOT_FOUND(响应 404),存在性不可枚举, 与「查无此单」响应体逐字段一致(MM-PRIVACY-001) E3 字段白名单显式化 + 用户隐私开关: - 抽取 assembleMatchmakerUserProfile:仅 7 键(displayName/gender/age 派生/regionName/ educationCode/occupationCode/maritalStatus),无 birthDate 原值/详细地址/手机号/微信/ 身份证;接 UserPrivacySettings.showOccupation(缺省全放行) E4 死端点清理: - 删除 GET /operator/matchmaker/my-services(operatorId 误当 user_id、恒空、前后端零调用), 替代路径 /operator/matchmaker/assignments/my;C 端 /matchmaker/services 与 counseling myServices 保留 P1 残留收口(读/写路径仍信任废弃 assigned_operator_id 残留列,与 E1 同类洞): - P1-1 运营端推荐列表:MatchmakerRecommendationMapper.findByOperatorId 改 join 生效分配(active+expires),撤/结后不再可见 - P1-2 dashboard 三计数:count*ByOperator 改 join 生效分配 + COUNT(DISTINCT) 防重, end/revoke 后不再计入(DEC-002 规则7) - P1-3 转介授权:ReferralService.assertMatchmakerServesUser 切 serviceAssignmentPolicy.assertActiveAssignment(DATA_SCOPE_DENIED 审计 + 403), 删残留列查询 findActiveByOperatorAndUser 新端点(组长团队脱敏统计): - GET /operator/matchmaker/team/statistics(@PreAuthorize matchmaker.team.assign): 本组织 active 分配数/按红娘分组/在岗红娘数,纯计数无用户 PII;org 边界 IS NOT DISTINCT FROM(NULL=NULL 平台直属) P2-4 operatorName 脱敏决策:保留不脱敏(§5.2 字段分类:红娘姓名=团队范围内 工作人员标识非用户 PII;组长统计本团队工作量属管理职责),依据登记 docs/governance/open-questions.md OQ-MATCHMAKER-002(RESOLVED) 死代码清理:getOperatorServices(零调用)+ MatchmakerServiceMapper.findByOperatorId (残留列查询,调用清零)删除;C 端 MatchmakerService 遗留信任残留列按豁免未动(006/007 退役) 测试: - MatchmakerDataScope005Test(13 用例):MM-PRIVACY-001/002、MM-AUTH-001/003 读侧、 MM-LIFECYCLE-001 读侧、P1-1/2/3 残留收口负向(撤/结后推荐不可见/计数归零/转介 403)、 防探测逐字段一致、showOccupation 三态 - MatchmakerFieldPrivacyGuardTest(3 用例):字段白名单源码扫描 + 无导出端点锁定 - MatchmakerReferralPhase13Test 转介口径收紧(IllegalStateException→AccessDeniedException) - 负向注入自证(P1-3 残留列变异→判红→恢复复绿) 验证:定向 73/73;全量 851/851(3 预存 skip);UI 契约 24/24。
善缘丹阳公益婚恋服务平台 V1.1 增量恢复中
面向丹阳市成年单身人士,由公益组织参与运营的实名制公益婚恋服务平台。
真实 · 公益 · 本地 · 安全 · 高效
当前基线: V1.0.0-RC.2 + V1.1 客户需求增量 · 状态:INCREMENTAL RECOVERY / NO-GO
当前代码包含 V1.1 部分实现,但尚未通过 Admin、Miniapp、权限和 E2E 发布门禁。请勿依据历史 Completion Report 或 Jira 勾选项判断已经上线。唯一执行计划见
docs/善缘丹阳 V1.1 客户需求基线增量开发与修复计划.md。
项目简介
本平台帮助丹阳本地单身人士通过实名认证、人工审核、智能匹配、双向喜欢、在线沟通、公益红娘和线下相亲活动,安全、高效、真实地寻找合适伴侣。
用户永久免费。
技术栈
| 组件 | 技术 |
|---|---|
| 后端 | Java 21 + Spring Boot 3.x |
| 数据库 | PostgreSQL |
| 缓存/Session | Redis |
| 对象存储 | S3 兼容(MinIO / 国内云存储) |
| 实时通信 | WebSocket |
| 数据库迁移 | Flyway |
| 小程序 | 微信原生 + TypeScript |
| 管理后台 | Vue 3 + TypeScript + Vite + Pinia + Element Plus |
| 容器化 | Docker + Docker Compose + Nginx |
| CI/CD | GitHub Actions |
项目结构
├── backend/ # Spring Boot 后端服务
├── miniapp/ # 微信小程序用户端
├── admin-web/ # 运营管理后台(Web)
├── infrastructure/ # Docker Compose 编排
├── scripts/ # 运维脚本
├── tests/ # 测试代码
│ ├── unit/
│ ├── integration/
│ ├── api/
│ ├── permission/
│ ├── concurrency/
│ ├── e2e/
│ └── invariants/ # 核心不变量测试(每次CI必跑)
├── docs/ # 项目文档
│ ├── product/
│ ├── architecture/
│ ├── api/
│ ├── database/
│ ├── security/
│ ├── testing/
│ ├── ops/
│ └── decisions/
├── AGENTS.md # 项目最高执行规则摘要
├── CHANGELOG.md
└── README.md
快速开始(开发环境)
前置要求
- Docker & Docker Compose
- JDK 21
- Node.js 18+
- npm / pnpm
一键启动基础设施
# 进入基础设施目录
cd infrastructure
# 启动 PostgreSQL / Redis / MinIO
docker compose up -d
# 等待服务就绪(约30秒)
# 可运行:docker compose logs -f
启动后端
cd backend
# 复制环境变量
cp src/main/resources/application-dev.yml.example src/main/resources/application-dev.yml
# 编辑 application-dev.yml,设置数据库连接等
# 构建并启动
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
启动管理后台
cd admin-web
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
启动小程序
使用微信开发者工具打开 miniapp/ 目录,配置 AppID 后即可预览。
环境变量
所有环境变量参见各模块的 .env.example 文件。
关键变量:
# 数据库
DB_HOST=localhost
DB_PORT=5432
DB_NAME=danyang_match
DB_USER=app_rw
DB_PASSWORD=<secret>
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
# 对象存储
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=<secret>
MINIO_SECRET_KEY=<secret>
MINIO_BUCKET_PUBLIC=public
MINIO_BUCKET_PRIVATE=private
# 微信
WECHAT_APP_ID=<secret>
WECHAT_APP_SECRET=<secret>
Secret 不进 Git。
数据库迁移
cd backend
./mvnw flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/danyang_match
运行测试
Phase 01 一键基线检查
PowerShell:
.\scripts\verify-phase01.ps1
Bash:
./scripts/verify-phase01.sh
脚本依次检查 Git、Backend tests、Admin type-check/build、Miniapp TypeScript 和 V1.1 E2E。任一门禁失败时脚本返回非零退出码,并在结尾列出失败项。Windows 未安装 JDK/Maven 时,Backend 检查使用 Docker 中的 JDK 21 与仓库内 Maven 包;不会永久修改系统环境。
首次执行 Admin/Miniapp 检查前,在 admin-web 目录运行 npm ci。E2E 使用 python -m pytest,不要依赖全局 pytest 命令。
分项命令
# 后端单元测试
cd backend
./mvnw test
# 后端集成测试
./mvnw verify
# 管理后台构建检查
cd admin-web
pnpm build
# 小程序编译检查
cd miniapp
# 在微信开发者工具中查看编译结果
构建部署
# 构建后端镜像
docker build -t danyang-match-backend:latest ./backend
# 构建管理后台
cd admin-web && pnpm build
# 完整部署
cd infrastructure && docker compose up -d
核心业务闭环
微信登录 → 绑定手机 → 实名认证 → 填写资料 → 设置择偶 → 提交审核
↓
审核通过 → 系统推荐 → 用户Like → 双向Match → 安全聊天
↓
公益红娘辅助 / 参加线下活动 → 进一步了解 → 双方确认成功牵手
开发阶段
项目按 Phase 01~Phase 26 顺序推进。详见 docs/STATUS.md。
许可证
本项目为公益项目,服务于丹阳市单身人士婚恋匹配。