From ef21d4d61ba7cdbf057654406896ca420f07c492 Mon Sep 17 00:00:00 2001 From: let5sne Date: Wed, 15 Jul 2026 00:53:52 +0800 Subject: [PATCH] fix(aihr): version practice session evidence migration --- ...60715_practice_session_evidence_mysql8.sql | 89 +++++++++++++++++++ docs/BRD_IMPLEMENTATION_AUDIT.md | 2 + docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md | 5 +- scripts/demo-check.sh | 1 + scripts/tests/aihr-schema-migrations.test.sh | 16 +++- 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql diff --git a/backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql b/backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql new file mode 100644 index 00000000..2118343b --- /dev/null +++ b/backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql @@ -0,0 +1,89 @@ +-- AIHR 对练会话证据字段迁移(MySQL 8.x) +-- 补齐严格试点门禁要求的 5 个会话证据字段;不写入业务数据,可重复执行。 + +SET @aihr_practice_session_table_exists := ( + SELECT COUNT(*) + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' +); + +SET @aihr_session_annotations_exists := ( + SELECT COUNT(*) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' + AND COLUMN_NAME = 'annotations_json' +); +SET @aihr_session_annotations_ddl := IF( + @aihr_practice_session_table_exists = 1 AND @aihr_session_annotations_exists = 0, + 'ALTER TABLE aihr_practice_session ADD COLUMN `annotations_json` text DEFAULT NULL COMMENT ''逐句标注JSON''', + 'SELECT 1' +); +PREPARE aihr_session_annotations_stmt FROM @aihr_session_annotations_ddl; +EXECUTE aihr_session_annotations_stmt; +DEALLOCATE PREPARE aihr_session_annotations_stmt; + +SET @aihr_session_review_advice_exists := ( + SELECT COUNT(*) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' + AND COLUMN_NAME = 'review_advice' +); +SET @aihr_session_review_advice_ddl := IF( + @aihr_practice_session_table_exists = 1 AND @aihr_session_review_advice_exists = 0, + 'ALTER TABLE aihr_practice_session ADD COLUMN `review_advice` varchar(1000) DEFAULT NULL COMMENT ''主管复盘建议''', + 'SELECT 1' +); +PREPARE aihr_session_review_advice_stmt FROM @aihr_session_review_advice_ddl; +EXECUTE aihr_session_review_advice_stmt; +DEALLOCATE PREPARE aihr_session_review_advice_stmt; + +SET @aihr_session_incentive_point_exists := ( + SELECT COUNT(*) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' + AND COLUMN_NAME = 'incentive_point' +); +SET @aihr_session_incentive_point_ddl := IF( + @aihr_practice_session_table_exists = 1 AND @aihr_session_incentive_point_exists = 0, + 'ALTER TABLE aihr_practice_session ADD COLUMN `incentive_point` int DEFAULT NULL COMMENT ''主管人工贡献分''', + 'SELECT 1' +); +PREPARE aihr_session_incentive_point_stmt FROM @aihr_session_incentive_point_ddl; +EXECUTE aihr_session_incentive_point_stmt; +DEALLOCATE PREPARE aihr_session_incentive_point_stmt; + +SET @aihr_session_satisfaction_score_exists := ( + SELECT COUNT(*) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' + AND COLUMN_NAME = 'satisfaction_score' +); +SET @aihr_session_satisfaction_score_ddl := IF( + @aihr_practice_session_table_exists = 1 AND @aihr_session_satisfaction_score_exists = 0, + 'ALTER TABLE aihr_practice_session ADD COLUMN `satisfaction_score` tinyint DEFAULT NULL COMMENT ''员工训练满意度1-5分''', + 'SELECT 1' +); +PREPARE aihr_session_satisfaction_score_stmt FROM @aihr_session_satisfaction_score_ddl; +EXECUTE aihr_session_satisfaction_score_stmt; +DEALLOCATE PREPARE aihr_session_satisfaction_score_stmt; + +SET @aihr_session_satisfaction_comment_exists := ( + SELECT COUNT(*) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'aihr_practice_session' + AND COLUMN_NAME = 'satisfaction_comment' +); +SET @aihr_session_satisfaction_comment_ddl := IF( + @aihr_practice_session_table_exists = 1 AND @aihr_session_satisfaction_comment_exists = 0, + 'ALTER TABLE aihr_practice_session ADD COLUMN `satisfaction_comment` varchar(500) DEFAULT NULL COMMENT ''员工训练满意度意见''', + 'SELECT 1' +); +PREPARE aihr_session_satisfaction_comment_stmt FROM @aihr_session_satisfaction_comment_ddl; +EXECUTE aihr_session_satisfaction_comment_stmt; +DEALLOCATE PREPARE aihr_session_satisfaction_comment_stmt; diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index 46071179..c4d7c303 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -1,5 +1,7 @@ # BRD 功能审查与未完成项记录 +- 2026-07-15 BRD 4.3/4.4/4.5 生产迁移缺口修复:严格试点门禁要求 `aihr_practice_session` 的 8 个证据字段,但版本化迁移此前只覆盖三项五维字段,`annotations_json`、主管复盘建议、人工贡献分和满意度字段仍可能依赖运行时懒迁移。现新增幂等 MySQL 8 迁移补齐其余 5 列,纳入 Runbook、schema 回归和 `demo-check` marker;仅补结构,不写业务数据,尚未执行生产迁移。 + - 2026-07-15 BRD G3/4.7 生产迁移缺口修复:`aihr_knowledge_gap` 与 `aihr_knowledge_answer_feedback` 此前只在 `AihrSopSeedService` 运行时懒建,生产迁移 Runbook 没有对应版本化脚本,可能出现应用启动前结构缺失、反馈/知识缺口审计不可用。现新增幂等 MySQL 8 迁移,兼容旧反馈表补齐 `review_id/reviewer/reviewed_time`,纳入迁移 Runbook、迁移回归测试和 `demo-check` marker;仅补结构,不写业务数据,尚未执行生产迁移。 - 2026-07-15 BRD 剩余功能复核:重新核对动态难度、案例视频和 SOP 反馈治理三条链路。场景表已有 `difficulty` 但没有 HR 确认的升降级阈值、候选场景映射和人工关闭规则;案例当前能保存/回放脱敏音频,但没有正式预渲染视频样片及对应学习场景契约;SOP 负反馈队列已有问题、片段、评审状态和人工复核入口,但没有经业务批准的纠正内容、版本替换和署名入库规则。本轮不硬编码业务规则、不用音频冒充视频、不把“标记已复核”伪装成知识修复;以上继续作为 P1/发布前输入项跟踪。 diff --git a/docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md b/docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md index 6e8169ab..4554173c 100644 --- a/docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md +++ b/docs/BRD_PRODUCTION_MIGRATION_RUNBOOK.md @@ -32,6 +32,7 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_case_media_mysql8.sql mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_case_learning_mysql8.sql mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_practice_five_dimensions_mysql8.sql +mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_daily_drill_score_mode_mysql8.sql mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_sop_requester_identity_mysql8.sql mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_knowledge_feedback_mysql8.sql @@ -60,7 +61,7 @@ FROM information_schema.columns WHERE table_schema = DATABASE() AND ( (table_name = 'aihr_case_record' AND column_name IN ('media_oss_id', 'media_url', 'learning_points', 'supervisor_comment')) - OR (table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion', 'dim_response_timeliness', 'response_latency_ms')) + OR (table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion', 'dim_response_timeliness', 'response_latency_ms', 'annotations_json', 'review_advice', 'incentive_point', 'satisfaction_score', 'satisfaction_comment')) OR (table_name = 'aihr_practice_assignment' AND column_name IN ('score', 'score_mode')) OR (table_name = 'aihr_sop_answer_review' AND column_name IN ('prompt_version', 'requester_ext_party_id')) OR (table_name = 'aihr_org_snapshot' AND column_name = 'hire_date') @@ -73,7 +74,7 @@ WHERE tenant_id = '000000' AND code IN ('summary_card', 'sop_answer', 'mentor_rewrite', 'review_annotation', 'prep_card', 'supervision_image_analysis_maintenance'); ``` -预期是三张场景/Rubric 表、三张证据表和两张知识治理表均存在,字段查询覆盖所有列,内置 Prompt 数量为 `6`。这只证明 schema/seed 迁移完成,不证明正式试点完成。 +预期是三张场景/Rubric 表、三张证据表和两张知识治理表均存在,会话证据字段为 `8/8`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。这只证明 schema/seed 迁移完成,不证明正式试点完成。 ## 迁移后应用回归 diff --git a/scripts/demo-check.sh b/scripts/demo-check.sh index 2138ade4..6cda14e7 100755 --- a/scripts/demo-check.sh +++ b/scripts/demo-check.sh @@ -539,6 +539,7 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service contains frontend/src/views/train/practice.vue "label: '任务完成度'" contains backend/script/sql/aihr_practice_mysql8.sql "task_completion" contains backend/script/sql/update/aihr_20260714_practice_five_dimensions_mysql8.sql "aihr_brd_rubric_codes" +contains backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql "annotations_json" contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/domain/AihrPracticeDto.java "MistakeAggregateResponse" contains mobile-uni/src/pages/supervisor/team/index.vue "团队错题本" contains mobile-uni/src/types/api.ts "PracticeMistakeAggregate" diff --git a/scripts/tests/aihr-schema-migrations.test.sh b/scripts/tests/aihr-schema-migrations.test.sh index a8affe4c..c1892cdb 100755 --- a/scripts/tests/aihr-schema-migrations.test.sh +++ b/scripts/tests/aihr-schema-migrations.test.sh @@ -95,6 +95,20 @@ mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260715_knowledge_feedb feedback_review_columns="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY ordinal_position) FROM information_schema.columns WHERE table_schema='$DB' AND table_name='aihr_knowledge_answer_feedback' AND column_name IN ('review_id','reviewer','reviewed_time');")" test "$feedback_review_columns" = 'review_id,reviewer,reviewed_time' +mysql "$DB" <<'SQL' +CREATE TABLE aihr_practice_session ( + id bigint NOT NULL AUTO_INCREMENT, + session_id varchar(100) NOT NULL, + total_score int, + ai_comment varchar(1000), + PRIMARY KEY (id) +) ENGINE=InnoDB; +SQL +mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql" +mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260715_practice_session_evidence_mysql8.sql" +practice_session_evidence_columns="$(mysql "$DB" -N -B -e "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='$DB' AND table_name='aihr_practice_session' AND column_name IN ('annotations_json','review_advice','incentive_point','satisfaction_score','satisfaction_comment');")" +test "$practice_session_evidence_columns" = '5' + mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql" mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260714_practice_evidence_mysql8.sql" evidence_tables="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(table_name ORDER BY table_name) FROM information_schema.tables WHERE table_schema='$DB' AND table_name IN ('aihr_practice_audio','aihr_practice_audio_upload','aihr_practice_calibration');")" @@ -126,4 +140,4 @@ mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260714_org_hire_date_m org_columns="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY ordinal_position) FROM information_schema.columns WHERE table_schema='$DB' AND table_name='aihr_org_snapshot' AND column_name='hire_date';")" test "$org_columns" = 'hire_date' -echo "PASS: AIHR legacy schema migrations are idempotent, including case media, learning, and knowledge feedback fields" +echo "PASS: AIHR legacy schema migrations are idempotent, including practice evidence and knowledge feedback fields"