18 KiB
18 KiB
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,Console127.0.0.1:9001,账号ruoyi / ruoyi123,bucketruoyi。 - Qdrant:REST
127.0.0.1:6333,默认 collectionaihr_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才开启;该开发开关不进入生产启动。 - 后端默认通过 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/。 - 旧移动端兜底:
./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 链接、签名或真机验收前不得称为已出包或上架。 - 完整发布收口须按
docs/DEV_SETUP.md运行同时启用远端静态、后端和 schema 的release-preflight;只有三项都通过,才可称当前本地构建已与线上完整包匹配。单纯 H5 资源匹配不等同于完整发布验证。 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重新鉴权,总结卡失败不兜假数据。全网外发必须先同意,显式记忆先出确认卡,再通过不透明draftId按PRIVATE/COMPANY确认;COMPANY仅为PENDING,不得冒充已派单或送达。aihr_agent_run不保存问题、答案或附件,外部知识 API 保持无状态。 - 大喇叭详情追问只让客户端传
broadcastMessageId,消息正文、附件文本、租户和身份均由服务端重新校验并加载;撤回、跨租户或非在职员工不得继续使用消息上下文。单条消息最多绑定一个属于当前租户、当前上传人且状态为READY的公司文件;员工端只返回摘要与受控下载入口,不返回提取全文或原始 OSS 地址。消息/知识回答不得把通用建议包装成当前员工的真实待办,强行动入口只能来自服务端已授权的真实任务数据。 - 直通车固定为总裁、财务、人力、审计、运营五个渠道;业务匿名只隐藏处理端的提交人展示,服务端仍保留内部提交账号供本人查询、幂等和审计。
direct_president/direct_finance/direct_hr/direct_audit/direct_operations只处理各自渠道,superadmin可处理全部;当前产品边界只允许一次正式回复,不扩展为多轮聊天、工单、转派或 SLA。 - 术语和数据边界:工作助手承载日常事实与确认式记忆;现有
/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。 - 问题榜奖励只记积分/学习学分,不得擅自增加现金、提现、预算或税务语义;选最佳答案和考试提交必须保持请求幂等。
- 全网 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,不复用管理后台登录态。 - 移动端手机号登录:验证码发送走
GET /resource/sms/code?phonenumber=...,登录走POST /auth/mobile/sms-login;短信发送复用sms.blends.config1阿里云配置。手机号不存在时自动注册app_user,备注为“移动端短信自动注册”。模板 ID 用AIHR_SMS_LOGIN_TEMPLATE_ID,AccessKey/Secret/签名用ALIYUN_SMS_ACCESS_KEY_ID、ALIYUN_SMS_ACCESS_KEY_SECRET、ALIYUN_SMS_SIGN_NAME,本地放.env.local。aihr.sms.dev-fixed-code非空则验证码固定(dev 默认123456)、不真发短信;prod 默认关闭,试点期必须同时显式设置AIHR_SMS_DEV_FIXED_CODE与AIHR_SMS_PROD_FIXED_CODE_ENABLED=true,停用时删除固定码并关闭生产开关。 - 移动端员工训练闭环:员工端首页“开始训练”复用
POST /api/train/practice/start、/turn、/finish,请求必须带移动端登录返回的Authorization与clientid;服务端强制当前 APP 身份和mode=mobile,才会写入aihr_practice_session并更新主管端首页完训率、“待复盘对练”、员工训练历史和能力画像。APP 身份只能按认证手机号精确匹配person_phone(/me、问师傅主体解析同样只走activeByMobilePhone),运营/调度身份只能按ext_party_id解析;严禁把两种字段混作替代查询键,映射碰撞或不唯一时必须拒绝任务读写。员工历史、画像、成长进度、晋升证据仅可使用该手机号服务端验证得到的受控别名集合;后台不得借/api/aihr/mobile/**传入组织ext_party_id读取员工历史、错题、画像、证据、主管复盘或录音;后台只保留/api/train/practice/**的内容/任务运营,以及服务端固定operator:{userId}、mode=preview的不绑定员工身份预览。主管团队范围只保存外部 ID;旧手机号仅当其唯一对应一个外部 ID,且该外部 ID 也唯一对应一个在职手机号时,才可规范化读取/统计;该相同的失败关闭规则必须用于团队列表、详情、复盘与音频授权。案例项目范围和岗位 SOP 同样复用已验证 APP 主体的精确项目范围,不得以person_phone OR ext_party_id或管理端组织模糊查询作为后备。superadmin/hr_operator管理端仅可走服务端绑定的operator:{userId}、mode=preview运营预览,忽略客户端员工身份/模式/任务,且预览不得进入员工历史、复盘、成长或试点统计;其他后台身份一律拒绝。主管端复盘详情查GET /api/aihr/mobile/practice/reviews/{id},标记复盘用POST /api/aihr/mobile/practice/reviews/{id}/reviewed。 - 正式试点 CSV 走
GET /api/train/practice/export?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD,起止日必填;训练、校准和 SOP 评审必须按同一窗口、唯一在职组织身份统计,完训定义为每人至少 10 次。CSV 应保留原始校准命中/SOP 可用计数,严格预检用AIHR_PILOT_START_DATE、AIHR_PILOT_END_DATE与AIHR_PILOT_STRICT=true ./scripts/demo-check.sh;不允许用历史 seed、开发身份或四舍五入比率伪造正式试点通过。 - 移动端候选人闭环:候选人端“开始面试/面试练习”复用
POST /api/recruit/interview/start、/answer、/finish;“补充资料”走认证接口POST /api/aihr/mobile/candidate/materials(multipartfile+candidateId/candidateName/materialType)和GET /api/aihr/mobile/candidate/materials,文件先写sys_oss/MinIO,再写aihr_candidate_material状态待审核。HR 审核复用管理端/recruit/interview页,接口为GET /api/aihr/hr/candidate/materials和POST /api/aihr/hr/candidate/materials/{id}/review,状态只用待审核/已通过/已驳回。上传接口不要放进 class-level@SaIgnore的AihrMobileController。 - 后端 API 对接先看
docs/API_INTEGRATION.md。三角色对练/turn//finish使用AihrPracticeLlmService,必须保留“未配置/失败回退 seed”的降级链。 - 对练语音走
POST /api/ai/asr(≤5MB multipart)和POST /api/ai/tts(文本≤300字,返回 base64 dataURL);TTS 保留旧voice字符串,并支持voiceProfile={role,voice?,speed?,emotion?},当前老师傅/业主/面试官分音色,业主按对练情绪分调整语气与语速。模型走aihr_model_config的asr/tts类目(category全集:chat/vector/rerank/asr/tts/vision)。移动端getUserMedia/MediaRecorder不可用或麦克风权限失败时,用隐藏audio/*file input 选择/录制音频后继续走同一 ASR 接口,不要退回只有文字输入。multipart 头部的 filename/contentType 已做 CRLF 清洗,新增外发 HTTP 时同样注意。 - 后端业务代码不要塞进上游
ruoyi-demo;自有 API 放在backend/ruoyi-modules/ruoyi-aihr,再接入ruoyi-admin。 - AI 面试页、三角色对练页、案例沉淀页、SOP 知识库页和移动端三端首页已是 API 优先 + 本地 fallback;SOP 知识库优先查
aihr_knowledge_fragment的 MySQL Fulltext,vector 模型和 Qdrant 可用时混合召回,category=rerank模型启用时融合后语义重排(失败保持 RRF 顺序);支持.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx、图片.jpg/.jpeg/.png/.gif/.webp/.bmp及视频.mp4/.mov/.avi/.mkv/.webm/.m4v上传解析入库。 - 浏览器批量上传走异步队列
POST /api/knowledge/doc/upload-async(暂存目录aihr.upload.staging默认./.data/staging,队列表aihr_knowledge_upload_item,单文件重试);同步接口POST /api/knowledge/doc/upload只留给 SOP 页单文件即时预览,不要把重加工逻辑加回同步请求线程。视频(≤500MB/≤60分钟)只走异步队列,依赖服务器安装 ffmpeg/ffprobe。 - SOP 上传接口是
POST /api/knowledge/doc/upload,表单字段为file和category;当前限制 100MB 内,支持 txt/md/PDF/Word/Excel/PPT 及图片,先写 MinIO/sys_oss再绑定aihr_knowledge_attach.oss_id,同一知识库同名文件会替换旧 fragment。若数据库启用category=vector的模型配置,会同步调用 OpenAI-compatible/embeddings,写入embedding_json并尽力 upsert 到 Qdrant;配置缺失或外部 embedding 失败才用local-hash-v1兜底,Qdrant 不可用时保留 MySQL Fulltext/seed fallback。管理端uploadKnowledgeDoc单接口 timeout 是 180s;遇到约 50sBroken pipe先查浏览器客户端超时,不要改全局 axios。 - 图片视觉 OCR:上传图片时经
visionRuntime()找启用模型(优先aihr_model_config.category='vision',无则回退category='chat'),把图片编码成 base64 data URL 调 OpenAI-compatible/chat/completions提取文字再切分入库;无可用视觉模型或 OCR 无结果时按「待处理」落库(0 片段),不算失败。视频关键帧用带画面描述的 FRAME_PROMPT(文字+一句场景描述),改 prompt 时别退回纯 OCR。不依赖 Tesseract。 - 向量库状态接口是
GET /api/knowledge/doc/vector-index-status,重建接口是POST /api/knowledge/doc/rebuild-vector-index;外部 embedding 成功但 Qdrant collection 维度不一致时不要静默降级,走状态提示和重建。 - 资料处理接口是
GET /api/knowledge/processing/overview,直接聚合aihr_knowledge_attach、aihr_knowledge_fragment和sys_oss.ext1;页面只保留“批量导入”,走POST /api/knowledge/doc/upload-async,不要恢复“选择目录”“服务端导入”或目录导入任务面板。POST /api/knowledge/doc/import-local、POST /api/knowledge/doc/import-local-task、GET /api/knowledge/doc/import-tasks和POST /api/knowledge/doc/import-tasks/{id}/cancel仅保留为后端运维/调试接口;目录只能是aihr.import.root下的相对路径。 ruoyi-ai只按docs/RUOYI_AI_INCREMENTAL_MIGRATION.md分片迁移到ruoyi-aihr,不要整包搬ruoyi-chat;已落地页面保持真实接口/模型优先与 seed fallback,不能退回静态壳。- 本项目 AI 表前缀用
aihr_*:知识库是aihr_knowledge_info/attach/fragment,问师傅短期会话是aihr_knowledge_conversation,Agent 审计是aihr_agent_run,大喇叭公司文件是aihr_broadcast_attachment,直通车反馈是aihr_direct_feedback,确认式采集是aihr_memory_candidate/aihr_assistant_capture(旧项目记录兼容aihr_service_memory/version),上传队列是aihr_knowledge_upload_item,导入任务是aihr_knowledge_import_task,模型配置是aihr_model_provider/config,移动端训练记录是aihr_practice_session,候选人补充资料是aihr_candidate_material,组织人员快照是aihr_org_snapshot(本地 reset 有 Demo seed;生产/试点从docs/open-org-sync-api-design-v1.md对应开放组织系统同步,入口POST /api/aihr/org/sync)。
业务文档
- 索引与范围:
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。