# AGENTS.md ## 项目定位 本项目是**帮道 APP**,按“陪练 → 大喇叭+知识学习平台 → 北森对接”三阶段推进。正式验收主线是阶段一试点;后续能力提前发布不等于整体验收。结论须区分生产部署、正式账号/真机验证和严格试点。 ## 工程边界 - `backend/` 是 `dromara/RuoYi-Vue-Plus` 的 `5.X` 分支检出。 - `frontend/` 是 `CrazyLionCat/plus-ui` 的 `5.X` 分支检出,只承载管理端。 - `mobile-uni/` 是当前用户侧工程,承载员工端、候选人端、主管端,使用 uni-app Vue3 H5 + App-Plus;原生资源、隐私/签名和真机门禁见 `docs/MOBILE_APP_PACKAGING.md`,旧 `mobile/` 仅保留为 MVP 演示兜底,不再承载新增功能。 - 本项目自己的本地编排放在根目录:`docker-compose.dev.yml`、`scripts/`;运行说明在 `docs/DEV_SETUP.md`。 - 除非确实要接业务模块,不要改上游框架默认配置;本地端口和开关优先放根目录脚本里覆盖。 ## 本地运行 - MySQL:`127.0.0.1:13306`,库 `ry-vue`,账号 `root/root`。 - Redis:`127.0.0.1:16379`,密码 `ruoyi123`。 - MinIO:API `127.0.0.1:9000`,Console `127.0.0.1:9001`,账号 `ruoyi / ruoyi123`,bucket `ruoyi`。 - Qdrant:REST `127.0.0.1:6333`,默认 collection `aihr_knowledge`;可用 `AIHR_QDRANT_URL`、`AIHR_QDRANT_COLLECTION`、`AIHR_QDRANT_API_KEY` 覆盖。 - 资料导入根目录:默认 `./.data/import`,由 `scripts/dev-backend.sh` 传入 `aihr.import.root`;也可用 `AIHR_IMPORT_ROOT` 覆盖。 - 本地私密配置:根目录 `.env.local` 已被 `.gitignore` 忽略,`scripts/dev-backend.sh` 会自动加载;阿里云短信密钥只放这里或外部环境变量,不写入 `application-*.yml`。未经本轮用户明确授权,本地管理端图形验证码和移动端短信校验必须保持关闭,方便自动化登录;只有同时按需设置 `AIHR_DEV_CAPTCHA_ENABLED=true`、`AIHR_SMS_VERIFICATION_ENABLED=true` 和移动端 `VITE_SMS_VERIFICATION_ENABLED=true` 才开启对应验证码。生产短信是移动端唯一认证因子,默认保持开启,不复用本地免验证码开关。 - Windows + Docker Desktop 按 `docs/DEV_SETUP.md` 启动:基础设施跑 Docker,应用跑 Windows,`.sh` 仅用 Git Bash。代理/TUN 干扰 `*.localhost` 时,Vite 从 `portless list` 取端口直连 `127.0.0.1`。 - 后端默认通过 portless 启动,入口 `https://wygj-api.localhost/`;使用 `portless run --name wygj-api ./scripts/dev-backend.sh` 或 `./scripts/dev.sh`,`PORTLESS=0` 回退 `8080`。管理端代理目标在 `frontend/.env.development`。 - 管理端前端:`./scripts/dev-frontend.sh`,默认走 portless,入口 `https://wygj-admin.localhost/`;显式 `PORTLESS=0` 时回退端口 `5173`。 - 当前用户侧前端:`portless` 启动 `mobile-uni`,入口 `https://wygj-mobile-uni.localhost/h5/`。 - 移动端主任务页发布前必须用 `390×844` 复核首屏:核心操作和主按钮无需滚动即可看到,规则/免责声明默认折叠,并实际点击主路径;源码存在或页面可加载不能替代该验收。 - 旧移动端兜底:`./scripts/dev-mobile.sh`,端口 `5174`,只用于回看 MVP 演示壳。 - 重置数据:`./scripts/reset-dev-db.sh`,会删除并重建本地 `ry-vue`。 导入 SQL 必须带 `--default-character-set=utf8mb4`,否则中文昵称可能按错误字符集导入并触发字段长度问题。 ## 验证口径 - 前端首页:`https://wygj-admin.localhost/` - 用户侧首页:`https://wygj-mobile-uni.localhost/h5/` - 后端接口:`https://wygj-api.localhost/` - 租户接口:`https://wygj-admin.localhost/dev-api/auth/tenant/list` - 验证码接口:`https://wygj-admin.localhost/dev-api/auth/code` - 默认登录:租户 `000000`,管理员 `admin / admin123`。 ## 发布口径 - 线上管理端:`https://peilian.njzhmj.top/`,Caddy 服务 `/opt/wygj/www`;该目录包含移动端 `/h5`,发布管理端时先备份整个目录,再 `rsync -az frontend/dist/ YCWY:/opt/wygj/www/`,**不得**对根目录使用 `--delete`。纯管理端静态修复不需要重启后端。 - 线上移动端 H5:`https://peilian.njzhmj.top/h5/`,Caddy 服务 `/opt/wygj/www/h5`。 - 只发布移动端静态资源时,用 `npm --prefix mobile-uni run build:h5` 后备份远端 `/opt/wygj/www/h5`,再 `rsync -az --delete mobile-uni/dist/build/h5/ YCWY:/opt/wygj/www/h5/`;前端静态修复不需要重启后端。 - 原生 App 不复用 H5 静态发布流程;`npm --prefix mobile-uni run build:app` 仅生成 HBuilderX 出包资源,未提供法务 HTTPS 链接、签名或真机验收前不得称为已出包或上架。 - 定向后端发布只启用远端后端 + schema 的 `release-preflight`,不得因本轮未发布的管理端/H5 不匹配而制造假失败,也不得把结果称为完整包匹配;完整发布收口须同时启用远端静态、后端和 schema,只有三项都通过才可称当前本地构建已与线上完整包匹配。 - 定向后端发布先运行只读 `scripts/release-backend.sh plan`;`deploy`/`rollback` 必须获得独立明确授权并使用计划输出的完整哈希授权串。脚本目标固定为 `YCWY:/opt/wygj/app/ruoyi-admin.jar` 和 `wygj-aihr.service`,不得绕过备份、原子切换、发布后预检和失败恢复链路手工覆盖。在 macOS 上运行发布/预检脚本需要 GNU stat(脚本内 `stat -c` 为 GNU 语法):安装 coreutils 后用 `PATH="/.tmp/gnu-bin:$PATH"` 垫片(`ln -sf $(brew --prefix)/bin/gstat .tmp/gnu-bin/stat`),远端 SSH 内命令不受影响。 - `aihr.practice.runtime-schema-bootstrap` / `AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP` 仅限本地开发逃生开关,Spring 默认关闭;生产请求只能校验表、列和关键索引,任何 DDL 都必须由正式 SQL 迁移完成,完整预检会拒绝开启该开关的服务。 ## 当前业务边界 - 管理端业务路由集中在 `frontend/src/router/index.ts`,覆盖首页、AI 面试、训练运营、问题榜、案例、知识空间、SOP、资料处理、大喇叭、五渠道直通反馈、系统配置、组织权限和成长激励;侧栏过滤在 `frontend/src/layout/components/Sidebar/index.vue`,不要恢复若依默认全量菜单。 - 用户侧只改 `mobile-uni/src/pages/*`;员工、候选人、主管首页分别为 `/pages/user/today/index`、`/pages/candidate/index/index`、`/pages/supervisor/index/index`,旧 `/h5/user|candidate|supervisor|employee|admin` 只做兼容重定向,底栏固定「今日/练/问/我」。“问”统一调用 `/api/aihr/agent/messages|messages/media`,服务端规划意图并按固定策略选择既有工具,客户端不得提交 `toolCode`;旧知识查询仅作底层/兼容。登录端短期会话为 30 分钟/最新 6 轮,原文件/视频经 `/api/knowledge/resources/{attachmentId}/content` 重新鉴权。总结卡只接受当前答案中的最多 5 个 `DOCUMENT` 引用 `fragmentIds`,服务端重新鉴权后仅基于这些片段生成固定「问题/建议/标准」结构;不得二次检索,失败不得拿原文冒充结构化步骤。全网外发必须先同意,显式记忆先出确认卡,再通过不透明 `draftId` 按 `PRIVATE/COMPANY` 确认;`COMPANY` 仅为 `PENDING`,不得冒充已派单或送达。`aihr_agent_run` 不保存问题、答案或附件,外部知识 API 保持无状态。 - 大喇叭发布支持 `ALL/TARGET_ONLY`:`TARGET_ONLY` 必须有目标并冻结收件人,列表、详情、未读、阅读、附件和追问统一复核可见性,非目标按不存在处理;`ALL` 下目标只作定向提醒。详情追问只让客户端传 `broadcastMessageId`,消息正文、附件文本、租户和身份均由服务端重新校验并加载;撤回、跨租户或非在职员工不得继续使用消息上下文。单条消息最多绑定一个属于当前租户、当前上传人且状态为 `READY` 的公司文件;`allowDownload=false` 时客户端不展示且服务端拒绝下载,在线查看返回受控文本并记录审计,动态水印只用于追溯。主题标签必须带原文短依据且不得参与授权。员工端不返回提取全文或原始 OSS 地址;默认岗位视角由服务端按认证员工岗位选择,客户端不得提交视角代码;解读处于 `PENDING/PARTIAL/FAILED` 不阻断摘要、受控查看、发布或追问。消息/知识回答不得把通用建议包装成当前员工的真实待办,强行动入口只能来自服务端已授权的真实任务数据。 - 直通车固定为总裁、财务、人力、审计、运营五个渠道;业务匿名只隐藏处理端的提交人展示,服务端仍保留内部提交账号供本人查询、幂等和审计。`direct_president/direct_finance/direct_hr/direct_audit/direct_operations` 只处理各自渠道,`superadmin` 可处理全部;只有 `superadmin` 可维护获批处理人,候选人必须由服务端限定为当前租户已启用的非 APP、非超级管理员后台用户,写入须校验租户上下文,系统不得自动把任意账号绑定成真实收件人。当前产品边界只允许一次正式回复,不扩展为多轮聊天、工单、转派或 SLA。员工提交页支持语音转文字输入(复用 `/api/ai/asr` 与 `services/speech.ts`);该表单页以文字为主,录音不可用或权限失败时只提示改文字,是不提供音频文件降级的明确例外。 - 术语和数据边界:工作助手承载日常事实与确认式记忆;现有 `/pages/user/report/index`、`/api/aihr/work-report/**` 和 `aihr_work_report` 只承载 CASE/VIDEO/SOP/KNOWLEDGE 四类投稿审核,产品名为“成果投稿”;“今日工作成果”按员工 + 项目 + 自然日从已确认记录确定性聚合,员工页为 `/pages/user/work-results/index`,主管页为 `/pages/supervisor/work-results/index`,默认当日但允许查看历史日期且不得选择未来日期。不要把三条链路合表或自动互写。多项目交互只让用户按项目名称选择,内部项目编码必须由服务端按当前身份复核,不让用户输入编码。 - 不要把三端概括成全模态:员工对练/每日题、问师傅和直通车反馈支持文字/语音,问师傅图片/视频只用于本次分析,案例传音频;候选面试支持文字/语音,资料可传文档/图片但图片不参与评分;主管写文字复盘/指派并回听录音。员工对练图像/视频情境、服务录像回放和方言正式验收仍未完成;语音继续复用 `services/speech.ts` 与 `/api/ai/asr`。 - 问题榜奖励只记积分/学习学分,不得擅自增加现金、提现、预算或税务语义;选最佳答案和考试提交必须保持请求幂等。 - 问师傅的未解决答案只有在本人先提交 `down` 反馈并再次确认后,才能由服务端重读本人查询审计和反馈创建 `PENDING` 问题榜条目;客户端不得提交改写答案、引用、身份或奖励,重复请求必须返回同一问题。正式学习任务与每日三题分开:材料只允许当前租户 `READY` 附件,任务保存材料版本、周期、起止时间和完成规则;`EXAM_PASS` 只能由关联考试通过完成,随机组卷只从已审核启用题库抽取并在发布时冻结来源和答案。 - 案例与训练高分只进入经验候选;业务审核不等于正式发布。正式经验必须另行确认来源授权、脱敏、适用岗位、负责人、版本和生效期后进入 `PUBLISHED`,员工只可召回当前生效的正式经验;下线后立即停止员工召回。案例、成果投稿和知识空间不得自动互写。 - 全网 AI 与企业问师傅必须分入口、分来源和分免责声明;提供方仅允许公网 HTTPS,修改地址/密钥后必须连接测试成功才能启用,未配置时明确不可用且不生成假答案。 - 多租户知识平台的有效范围是“租户 + 调用应用绑定 + 主体授权”的交集;不信任客户端传入身份,API_TOKEN 不得进入浏览器或小程序包。生产排序规则以 `aihr_knowledge_info.tenant_id` 为基准,新表最后执行 `aihr_20260718_release_collation_compat_mysql8.sql`。 - 移动端首页接口:`GET /api/aihr/mobile/home/{role}`,当前 `@SaIgnore` 公开只读 seed,用于 H5 首屏 API 优先 + 本地 fallback;后续确定小程序登录后再接移动端 token,不复用管理后台登录态。 - 移动端手机号登录和短信参数见 `docs/API_INTEGRATION.md`。密钥只放 `.env.local` 或外部环境;dev 默认免短信验证码,显式开启验证后可用固定码;prod 的验证码校验默认开启,但固定码默认关闭,试点期必须同时显式开启固定码和值,停用时两者一并清除。手机号不存在时自动注册 `app_user`。 - 移动端训练必须带 APP 登录态并由服务端强制 `mode=mobile`。APP 身份只按认证手机号精确匹配 `person_phone`,运营/组织身份只按 `ext_party_id`;禁止 `OR` 查询、互相后备或客户端指定身份,碰撞/不唯一一律失败关闭。员工历史、画像、证据、复盘和录音只对验证后的 APP 主体开放;管理端仅允许服务端绑定的 `operator:{userId}`、`mode=preview` 运营预览,且不得进入员工历史或试点统计。主管旧手机号只有与在职外部 ID 双向唯一时才可规范化,团队、详情、复盘和音频授权使用同一规则。 - 正式试点 CSV 起止日必填;训练、校准和 SOP 评审按同一窗口、唯一在职身份统计,完训定义为每人至少 10 次。严格预检使用 `AIHR_PILOT_START_DATE`、`AIHR_PILOT_END_DATE` 与 `AIHR_PILOT_STRICT=true ./scripts/demo-check.sh`,不得用 seed、开发身份或四舍五入比率冒充通过。 - 生产移动端浏览器验收可从 `aihr_org_snapshot` 只读选择手机号与外部 ID 双向唯一的在职账号;手机号仅在进程内使用,不进日志、截图、报告或仓库。固定码登录仍须先请求 `/resource/sms/code`。 - 候选面试复用 `/api/recruit/interview/**`;补充资料走认证的移动端接口,先写 `sys_oss`/MinIO,再写 `aihr_candidate_material`,状态仅为 `待审核/已通过/已驳回`,由管理端 `/recruit/interview` 审核。上传接口不得放入 class-level `@SaIgnore`。 - 后端 API 对接先看 `docs/API_INTEGRATION.md`。三角色对练 `/turn`/`/finish` 使用 `AihrPracticeLlmService`,必须保留“未配置/失败回退 seed”的降级链。 - 会话式语音复用 `/api/ai/asr|tts`;生产 ASR 用 `dashscope/qwen3-asr-flash`,SiliconFlow `/audio/transcriptions` 保留兼容。TTS 兼容旧 `voice` 和角色音色。除直通车表单外,浏览器录音不可用时用 `audio/*` file input 继续走 ASR;multipart 外发须清洗 filename/contentType 的 CRLF。 - 实时对练 Beta(WebRTC)的人设与工具声明只由服务端 `AihrRealtimePersonaRegistry` 白名单组装,客户端原样转发 session.update,不得恢复前端自组 instructions 或音色 picker;工具执行按登录态 + Redis 会话归属 + 人设白名单三重校验,仅只读知识检索且 `source=realtime` 不落 SOP 评审/知识缺口表;实时 Beta 不计分、不持久化,支持 H5 与 App-Plus(App 通过 renderjs WebView 执行媒体/WebRTC,并由逻辑层代理认证 SDP 和工具请求),需 APP 登录态,接口契约见 `docs/API_INTEGRATION.md`。 - 后端业务代码不要塞进上游 `ruoyi-demo`;自有 API 放在 `backend/ruoyi-modules/ruoyi-aihr`,再接入 `ruoyi-admin`。 - AI 面试、三角色对练、案例、SOP 和三端首页保持真实 API/模型优先与既有降级。知识检索以 MySQL 为事实源,Qdrant/vector/rerank 是可选增强;向量维度不一致必须经状态与重建入口处理,不得静默换成本地向量。 - 批量资料和所有视频只走 `/api/knowledge/doc/upload-async` 异步队列;同步 `/api/knowledge/doc/upload` 仅供 SOP 单文件即时预览,禁止把重加工塞回请求线程。格式、大小、超时、OCR/视频解析和重试契约以 `docs/API_INTEGRATION.md` 为准;图片无可用视觉结果时保持「待处理」,视频关键帧不得退回纯 OCR。 - 资料处理页只保留异步“批量导入”,不得恢复浏览器选目录、服务端目录导入或任务面板;目录导入接口仅供后端运维/调试,且路径必须位于 `aihr.import.root` 下。 - `ruoyi-ai` 只按 `docs/RUOYI_AI_INCREMENTAL_MIGRATION.md` 分片迁移到 `ruoyi-aihr`,不要整包搬 `ruoyi-chat`;已落地页面保持真实接口/模型优先与 seed fallback,不能退回静态壳。 - 自有业务表统一使用 `aihr_*`;当前表、接口和同步契约以 `docs/API_INTEGRATION.md`、TechSpec 与正式 SQL 迁移为准。组织快照为 `aihr_org_snapshot`:本地 reset 可有 Demo seed,生产/试点只从开放组织系统同步。组织主体身份以稳定 `employee.id` 为准(`employee_number` 不可靠,仅个位数匹配既有主体);日常岗位/人员变更用 `POST /api/aihr/org/sync-changes` 增量(先 `dryRun=true` 再以同起点 `dryRun=false`),全量 `/sync` 遇脱敏手机号或重复成员关系一律 fail-closed,不得用 `allowPartialReplace` 绕过身份漂移或把手机号刷空。 ## 业务文档 - 索引与范围:`README.md`、`docs/README.md`、`docs/银城员工端APP分阶段实施总纲.md`、`docs/AI陪练完整交付计划-20260724.md`;旧二期计划只作追溯。 - 当前事实与契约:`docs/BRD_IMPLEMENTATION_AUDIT.md`、`docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md`、`docs/API_INTEGRATION.md`、BRD/TechSpec 与 `docs/FIGMA_DESIGN_INVENTORY.md`。