# 留学黄页：多端产品共用一个业务事实来源

本文依据 2026 年 10 月本地检出的 `csc-server`、`csc-web`、`csc-admin` 代码与当前文档整理。它记录留学黄页项目的阶段性工程取舍，不代表线上部署状态，也不是新项目必须采用三仓结构的理由。值得借鉴的是数据、权限和业务判断归谁负责。

## 技术与运行形态

| 单元 | 仓库中的选择 | 职责 |
| --- | --- | --- |
| 用户前台 | Vue 3、Vite、TypeScript、Pinia、Element Plus | 展示院校、项目和申请工作台，调用 `/pc-api`。 |
| 运营后台 | Vue 3、Vite、TypeScript、Pinia、Element Plus | 根据服务端下发的菜单与权限管理目录，调用 `/admin-api`。 |
| 业务后端 | Java 17、Spring Boot 3、MyBatis-Plus、MySQL、Redis | 同时服务两个前端，拥有认证、授权、业务规则、事务和数据变更。 |

前后台是两个构建单元，业务后端仍是一个按领域划分的模块化单体。`csc-server` 的启动模块只做装配；留学目录、联系人、申请助手等能力放入所属模块。由此可见，**前端分开部署不要求把每个业务能力拆成独立服务**。

## 让一个功能形成真实闭环

项目曾同时有正式页面与演示数据。后续约定把正式路径收回到服务端：目录、收藏、申请草稿和候选结果读取真实 API；接口失败显示错误或空态，缺失的能力关闭入口或标明不可用。浏览器缓存可保存会话和显示偏好，不能成为申请状态、权限或院校资料的唯一事实来源。

对 Agent 的可执行启发是：交付一个页面前，沿“表与迁移 → 服务端规则与权限 → API → 前端状态”走通最小纵切片。若后端契约尚不存在，应先补契约或收起操作，不用本地数组和假成功补全演示效果。前端的隐藏菜单只影响可见性，后台 API 仍逐项校验权限。

## 不把目录事实推断成个人结论

已发布的院校或招生项目记录，只能证明目录中存在这条已发布记录。它不能自动证明某位学生符合申请条件、可获录取或具备奖学金资格。项目把候选筛选放到服务端，缺乏可靠依据的资格、材料和风险判断在界面上保留“待核验”。

这个边界适用于任何从内容目录延伸到推荐、评估或 AI 助手的产品：先定义数据能证明什么；模型和页面都不能把“有一条记录”说成“用户已经符合条件”。

## 把数据变更与代码一起交付

结构与必要基础数据由后端仓库的版本化 SQL 管理。项目选择人工按顺序执行迁移，服务启动不隐式修改数据库；新迁移和业务代码同一提交，并在执行后核对目标结构。这个流程针对其共享开发库和既有发布责任而定。可复用的原则是：**迁移有唯一归属、可审阅、可追溯，线上执行方式明确**。新项目不必照搬人工执行方式或三仓分支流程。

## 借鉴边界与核对入口

本案例展示三个仓库的实际协作，不定义公司新项目的仓库数量或技术栈。公司新项目以[四仓技术基线](../../engineering/scaffolds/technology-selections.md)和对应脚手架为准；本篇仅供判断数据与权限边界。

本篇主要核对 `csc-server/README.md`、`csc-server/docs/architecture/cross-repository-runtime-boundary.md`、`module-boundary.md`、`migrations/database-migrations.md`，以及 `csc-web/docs/analysis/2026-09-16-frontend-runtime-data-boundary.md`、`csc-admin/docs/csc-admin-boundary.md`。这些仓库中的文档与代码仍应在引用时重新核对；本篇未复制连接信息、账号或业务数据。
