feat(aihr): finalize practice growth and access boundaries
This commit is contained in:
+27
-33
@@ -43,7 +43,7 @@ check_mobile_h5_shell() {
|
||||
icon_url="${MOBILE_URL%/}${href}"
|
||||
code="$(curl -k -sS -o /tmp/wygj-demo-check.favicon -w '%{http_code}' "$icon_url")"
|
||||
[[ "$code" == "200" ]] || fail "mobile H5 favicon returned HTTP $code: $icon_url"
|
||||
contains mobile-uni/src/manifest.json '"enable": false'
|
||||
contains mobile-uni/src/manifest.json '"enable" : false'
|
||||
echo "OK: mobile H5 shell"
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ contains mobile-uni/src/services/home.ts "/api/aihr/mobile/home/"
|
||||
contains mobile-uni/src/services/home.ts "auth: isLoggedIn()"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMobileSeedService.java "public HomeResponse publicHome(String role)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "return R.ok(mobileSeedService.publicHome(role))"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.home(role, identity)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.home(role, resolvedIdentity)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "!UserType.APP_USER.getUserType().equals(loginUser.getUserType())"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "无权访问该录音"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "return AihrSensitiveText.forModel(value)"
|
||||
@@ -462,7 +462,6 @@ contains mobile-uni/src/pages/candidate/materials/index.vue "clearData();"
|
||||
contains mobile-uni/src/pages/candidate/progress/index.vue "const clearData = () =>"
|
||||
contains mobile-uni/src/pages/candidate/study/index.vue "searchKnowledge"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "岗位 SOP"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "当前摘要不代表正式上岗资格"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "岗位学习范围加载失败"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "getPracticeAssignments"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "searchKnowledge"
|
||||
@@ -471,8 +470,6 @@ contains frontend/src/views/recruit/interview.vue "建议复试"
|
||||
contains frontend/src/views/recruit/interview.vue 'v-loading="recordsLoading"'
|
||||
contains frontend/src/views/recruit/interview.vue "const recordsLoading = ref(true)"
|
||||
contains frontend/src/views/train/practice.vue "导师改写"
|
||||
contains frontend/src/views/train/practice.vue 'v-loading="recordsLoading"'
|
||||
contains frontend/src/views/train/practice.vue "const records = ref<Array<(typeof baseRecords)[number]>>([])"
|
||||
contains frontend/src/views/knowledge/cases.vue "真实语音"
|
||||
contains frontend/src/views/knowledge/cases.vue 'v-loading="recordsLoading"'
|
||||
contains frontend/src/views/knowledge/cases.vue "const records = ref<CaseRecord[]>([])"
|
||||
@@ -485,11 +482,8 @@ contains backend/script/sql/update/aihr_20260714_case_learning_mysql8.sql "super
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "/records/{caseId}/review"
|
||||
contains frontend/src/api/aihr/case.ts "reviewKnowledgeCase"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "系统用户上传案例必须明确所属项目"
|
||||
contains frontend/src/views/index.vue "核心流程覆盖待内容确认"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "核心流程覆盖待内容确认"
|
||||
contains frontend/src/views/index.vue "不等于端到端验收"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "不等于端到端验收"
|
||||
contains frontend/src/views/index.vue "正式试点身份待核对"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "正式试点身份待核对"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "TenantHelper.getTenantId()"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "TenantHelper.getTenantId()"
|
||||
@@ -500,7 +494,6 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "private String persistedTraineeName"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "persistedTraineeName(extPartyId.matches"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "if (!orgSnapshotTableExists() && !isDemoProfile())"
|
||||
contains frontend/src/views/index.vue "待同步"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrDashboardService.java "核心流程待确认"
|
||||
contains frontend/src/views/knowledge/sop.vue "训练题已生成"
|
||||
contains frontend/src/views/knowledge/sop.vue "不代表这些文档已真实入库"
|
||||
@@ -515,14 +508,12 @@ contains frontend/src/views/system/model/index.vue "提示词模板"
|
||||
contains frontend/src/views/system/model/index.vue "不代表真实租户配置"
|
||||
contains frontend/src/views/system/model/index.vue "不代表真实租户模板数据"
|
||||
contains frontend/src/views/system/prompts.vue "保存并启用"
|
||||
contains frontend/src/views/competency/growth.vue "学分规则(待 HR 配置)"
|
||||
contains frontend/src/views/competency/growth.vue "规划参考,当前不生效"
|
||||
contains frontend/src/views/competency/growth.vue "训练画像等级(参考)"
|
||||
contains frontend/src/views/competency/growth.vue "人工贡献分"
|
||||
contains frontend/src/views/train/reviews.vue "人工贡献分"
|
||||
contains frontend/src/views/train/reviews.vue "incentivePoint: null as number | null"
|
||||
contains frontend/src/views/train/reviews.vue "incentivePoint: reviewForm.incentivePoint ?? undefined"
|
||||
contains frontend/src/views/competency/growth.vue "person.personName || person.extPartyId"
|
||||
contains frontend/src/router/index.ts "path: 'reviews'"
|
||||
contains frontend/src/router/index.ts "path: 'difficulties'"
|
||||
contains frontend/src/router/index.ts "path: '/competency/growth'"
|
||||
contains frontend/src/router/index.ts "redirect: '/train/tasks'"
|
||||
contains mobile-uni/src/pages/supervisor/review/index.vue "人工贡献分"
|
||||
contains mobile-uni/src/pages/supervisor/review/index.vue "confirmedGrowthLevel"
|
||||
contains mobile-uni/src/pages/user/profile/index.vue "成长证据包(待人工复核)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "训练画像参考等级"
|
||||
contains frontend/src/router/index.ts "/system/prompts"
|
||||
@@ -545,8 +536,9 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains frontend/src/api/aihr/practice.ts "/api/train/practice/start"
|
||||
contains frontend/src/api/aihr/practice.ts "/api/aihr/prompt-templates"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "/api/train/practice"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "practiceSeedService.turn(request, currentAppUsername(), currentAppUserId())"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "practiceSeedService.finish(request, currentAppUsername())"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java 'practiceSeedService.turn(request, requirePracticeActorIdentity("继续训练"), currentAppUserId())'
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java 'practiceSeedService.finish(request, requirePracticeActorIdentity("完成训练"))'
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "private static String requirePracticeActorIdentity(String action)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "训练会话不存在或无权访问"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "finished_time IS NOT NULL"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "人工校准必须明确填写总分"
|
||||
@@ -575,12 +567,13 @@ 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/pages/supervisor/team/index.vue "常见难题"
|
||||
contains mobile-uni/src/pages/supervisor/team/index.vue "一键派专项"
|
||||
contains mobile-uni/src/types/api.ts "PracticeMistakeAggregate"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/mistakes"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "错题本"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "mistakeFilters"
|
||||
contains mobile-uni/src/pages/user/profile/index.vue "AI训练综合分仅作训练参考"
|
||||
contains mobile-uni/src/pages/user/profile/index.vue "AI训练综合分仅作参考"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "aihr_practice_session"
|
||||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_practice_scenario"
|
||||
contains backend/script/sql/update/aihr_20260714_practice_catalog_schema_mysql8.sql "aihr_practice_rubric_dimension"
|
||||
@@ -596,12 +589,9 @@ contains backend/script/sql/aihr_practice_mysql8.sql "summary_card"
|
||||
contains frontend/src/views/train/practice.vue "训练前预习卡"
|
||||
contains frontend/src/views/train/practice.vue "Rubric 预览"
|
||||
contains frontend/src/views/train/practice.vue "提示词模板"
|
||||
contains frontend/src/views/train/practice.vue "导出试点CSV"
|
||||
contains frontend/src/views/train/practice.vue "训练记录接口暂不可用,当前显示演示记录"
|
||||
contains frontend/src/views/train/practice.vue "listPracticeReviews"
|
||||
contains frontend/src/views/train/reviews.vue "导出试点 CSV"
|
||||
contains frontend/src/views/train/reviews.vue "人工校准总分"
|
||||
contains frontend/src/views/train/reviews.vue "不展示演示复盘记录或猜测性试点指标"
|
||||
contains frontend/src/views/train/practice.vue "此页仅用于不绑定员工身份的运营预览"
|
||||
contains frontend/src/views/train/practice.vue "不会使用或生成员工身份"
|
||||
contains frontend/src/router/index.ts "meta: { title: '复盘校准', icon: 'finish', activeMenu: '/train/tasks' }"
|
||||
contains frontend/src/api/aihr/practice.ts "/api/train/practice/export"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "final_adopted_score"
|
||||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_practice_calibration"
|
||||
@@ -640,7 +630,7 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/control
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java 'firstNonBlank(position, "生活顾问")'
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "formalPositionSopTopics(position, effectiveProjectType, projectCodes)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "formal-applicability"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "qualificationStatus === 'NOT_CONFIGURED'"
|
||||
contains mobile-uni/src/pages/user/learning/index.vue "const qualificationStatusLabel = computed(() =>"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "currentAppProjectCodes()"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "FIND_IN_SET(?, REPLACE(a.org_scope, ' ', '')) > 0"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "normalizeSearchSource"
|
||||
@@ -668,7 +658,9 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSpeechService.java "Duration.ofSeconds(5)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrMobileSeedService.java "待复盘对练"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/reviews"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "StpUtil.hasRoleOr(TenantConstants.SUPER_ADMIN_ROLE_KEY, \"hr_operator\")"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "private String supervisorScopeExtPartyId()"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "后台管理账号不能使用主管带教接口"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.requireMobileSupervisorIdentity(currentAppUsername())"
|
||||
contains mobile-uni/src/pages/supervisor/review/index.vue "人工贡献分"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "/practice/reviews/{id}/reviewed"
|
||||
contains mobile-uni/src/pages/supervisor/review/index.vue "标记已复盘"
|
||||
@@ -712,7 +704,8 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "currentProjectScopes"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "projectScopesForAppUser"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrCaseController.java "/api/knowledge/case"
|
||||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/search"
|
||||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/query"
|
||||
contains frontend/src/api/aihr/sop.ts "UnifiedQueryResponse"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "@SaCheckLogin"
|
||||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/doc/upload"
|
||||
contains frontend/src/api/aihr/sop.ts "/api/knowledge/reviews"
|
||||
@@ -740,7 +733,8 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "requireSessionTenant(session, tenantId())"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "private record InterviewSession(String tenantId"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "canReadPracticeAudioForTenant"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.canReadPracticeAudioForTenant(ossId)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "if (!UserType.APP_USER.getUserType().equals(loginUser.getUserType()))"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "mobileSeedService.canReadPracticeAudio(ossId, currentAppUsername())"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "oss.getOssId(), \"\")"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "new TtsResponse(inlineAudioUrl, \"openai-compatible\", oss.getOssId(), inlineAudioUrl)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "exposedAudioUrl"
|
||||
@@ -755,7 +749,8 @@ contains backend/ruoyi-admin/src/main/resources/application-dev.yml "AIHR_REDIS_
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrOrgSyncService.java "person_phone like ?"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrOrgSyncServiceTest.java "hiddenDisplayFieldsStillAllowIdentitySearchByPhone"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "requester_ext_party_id"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "currentRequesterExtPartyId"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/knowledge/service/AihrKnowledgePrincipalResolver.java "mobileSeedService.requireMobileIdentity(trim(loginUser.getUsername()))"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/knowledge/service/AihrKnowledgeQueryService.java 'principal == null ? "" : principal.extPartyId(), spaceIds'
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "hasExplicitSopReviewDecision"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "validateFeedbackFragmentOwnership"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java "normalizeFeedbackReviewId"
|
||||
@@ -768,7 +763,6 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSpeechController.java "tts audio upload failed(处理错误已隐藏)"
|
||||
contains mobile-uni/src/pages/user/history/index.vue "inlineAudioSrc"
|
||||
contains mobile-uni/src/pages/supervisor/review/index.vue "inlineAudioSrc"
|
||||
contains frontend/src/views/train/reviews.vue "inlineAudioSource"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSensitiveText.java "外部 AI 模型前"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "AihrSensitiveText.forModel(prompt)"
|
||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrModelSeedService.java "外部响应体已隐藏"
|
||||
|
||||
+11
-2
@@ -244,12 +244,21 @@ else
|
||||
fi
|
||||
PIDS+=("$!")
|
||||
|
||||
./scripts/dev-frontend.sh &
|
||||
BACKEND_PROXY_TARGET=""
|
||||
if using_portless_backend; then
|
||||
for _ in {1..20}; do
|
||||
BACKEND_PROXY_TARGET="$(portless get wygj-api 2>/dev/null || true)"
|
||||
[[ -n "$BACKEND_PROXY_TARGET" ]] && break
|
||||
sleep 0.1
|
||||
done
|
||||
fi
|
||||
|
||||
VITE_APP_PROXY_TARGET="${VITE_APP_PROXY_TARGET:-$BACKEND_PROXY_TARGET}" ./scripts/dev-frontend.sh &
|
||||
PIDS+=("$!")
|
||||
|
||||
if using_portless_mobile; then
|
||||
portless alias --remove wygj-mobile-uni >/dev/null 2>&1 || true
|
||||
VITE_PROXY_TARGET="${VITE_PROXY_TARGET:-https://wygj-api.localhost}" portless run --name wygj-mobile-uni --force npm --prefix mobile-uni run dev &
|
||||
VITE_PROXY_TARGET="${VITE_PROXY_TARGET:-$BACKEND_PROXY_TARGET}" portless run --name wygj-mobile-uni --force npm --prefix mobile-uni run dev &
|
||||
else
|
||||
./scripts/dev-mobile.sh &
|
||||
fi
|
||||
|
||||
@@ -71,6 +71,9 @@ fi
|
||||
if [[ "${RELEASE_VERIFY_REMOTE_SCHEMA:-false}" == "true" && "${RELEASE_VERIFY_REMOTE_MATCH:-false}" != "true" ]]; then
|
||||
fail "RELEASE_VERIFY_REMOTE_SCHEMA=true requires RELEASE_VERIFY_REMOTE_MATCH=true"
|
||||
fi
|
||||
if [[ "${AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP:-false}" == "true" ]]; then
|
||||
fail "AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP must stay false for a release; apply the formal SQL migration instead"
|
||||
fi
|
||||
|
||||
head_epoch="$(git show -s --format=%ct HEAD)"
|
||||
|
||||
@@ -106,6 +109,60 @@ require_remote_business_success() {
|
||||
echo "$label=200 $url"
|
||||
}
|
||||
|
||||
require_remote_practice_schema_guard() {
|
||||
local remote_ssh="${RELEASE_REMOTE_SSH:-YCWY}"
|
||||
local remote_service="${RELEASE_REMOTE_SERVICE:-wygj-aihr.service}"
|
||||
[[ "$remote_service" =~ ^[A-Za-z0-9_.@-]+\.service$ ]] \
|
||||
|| fail "remote systemd service name is invalid: $remote_service"
|
||||
|
||||
local state
|
||||
state="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_service" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
service="$1"
|
||||
matches_enabled_guard() {
|
||||
grep -Eiq '(AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP|aihr\.practice\.runtime-schema-bootstrap)[[:space:]]*=[[:space:]]*"?true"?'
|
||||
}
|
||||
|
||||
runtime_environment="$(systemctl show "$service" --property=Environment --value --no-pager)"
|
||||
unit_source="$(systemctl cat "$service")"
|
||||
if printf '%s\n' "$runtime_environment" | matches_enabled_guard \
|
||||
|| printf '%s\n' "$unit_source" | matches_enabled_guard; then
|
||||
printf 'enabled\n'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while IFS= read -r environment_file; do
|
||||
[[ -z "$environment_file" ]] && continue
|
||||
if [[ ! -r "$environment_file" ]]; then
|
||||
printf 'unreadable:%s\n' "$environment_file"
|
||||
exit 0
|
||||
fi
|
||||
if matches_enabled_guard < "$environment_file"; then
|
||||
printf 'enabled\n'
|
||||
exit 0
|
||||
fi
|
||||
done < <(printf '%s\n' "$unit_source" | sed -nE 's/^[[:space:]]*EnvironmentFile=-?([^[:space:]#]+).*/\1/p')
|
||||
|
||||
printf 'disabled-or-default\n'
|
||||
REMOTE
|
||||
)" || fail "remote runtime schema guard check failed: $remote_ssh:$remote_service"
|
||||
|
||||
case "$state" in
|
||||
disabled-or-default)
|
||||
echo "remote_practice_runtime_schema_bootstrap=false/default $remote_ssh:$remote_service"
|
||||
;;
|
||||
enabled)
|
||||
fail "remote AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP is enabled; disable it and apply formal SQL migrations"
|
||||
;;
|
||||
unreadable:*)
|
||||
fail "remote runtime schema guard cannot inspect ${state#unreadable:}; grant read access or unset the file before release"
|
||||
;;
|
||||
*)
|
||||
fail "remote runtime schema guard returned an unexpected state: $state"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
require_remote_schema() {
|
||||
local remote_ssh="${RELEASE_REMOTE_SSH:-YCWY}"
|
||||
local remote_db="${RELEASE_REMOTE_DB_NAME:-ry-vue}"
|
||||
@@ -232,6 +289,87 @@ REMOTE
|
||||
|
||||
[[ -z "$missing_work_report_columns" ]] \
|
||||
|| fail "remote work-report schema missing required columns: $(printf '%s' "$missing_work_report_columns" | tr '\n' ', ' | sed 's/, $//')"
|
||||
local missing_practice_curriculum_columns
|
||||
missing_practice_curriculum_columns="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
db="$1"
|
||||
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
|
||||
SELECT CONCAT(required.table_name, '.', required.column_name)
|
||||
FROM (
|
||||
SELECT 'aihr_practice_scenario' AS table_name, 'growth_level' AS column_name
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'competency_code'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'collaboration_positions'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'review_status'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'risk_level'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'curriculum_version'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'reviewer'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'reviewer_user_id'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'reviewed_time'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'second_reviewer'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'second_reviewer_user_id'
|
||||
UNION ALL SELECT 'aihr_practice_scenario', 'second_reviewed_time'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'position_snapshot'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'project_type_snapshot'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'growth_level'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'competency_code'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'collaboration_positions'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'curriculum_version'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'growth_confirmation_level'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'growth_confirmed_by'
|
||||
UNION ALL SELECT 'aihr_practice_session', 'growth_confirmed_time'
|
||||
) required
|
||||
LEFT JOIN information_schema.columns actual
|
||||
ON actual.table_schema = DATABASE()
|
||||
AND actual.table_name = required.table_name
|
||||
AND actual.column_name = required.column_name
|
||||
WHERE actual.column_name IS NULL
|
||||
ORDER BY required.table_name, required.column_name;
|
||||
SQL
|
||||
REMOTE
|
||||
)" || fail "remote practice-curriculum schema check failed: $remote_ssh:$remote_db"
|
||||
|
||||
[[ -z "$missing_practice_curriculum_columns" ]] \
|
||||
|| fail "remote practice-curriculum schema missing required columns: $(printf '%s' "$missing_practice_curriculum_columns" | tr '\n' ', ' | sed 's/, $//')"
|
||||
local practice_assignment_request_unique_index
|
||||
practice_assignment_request_unique_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
db="$1"
|
||||
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
|
||||
SELECT CONCAT(
|
||||
COALESCE(MIN(non_unique), -1), '|',
|
||||
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
|
||||
COALESCE(SUM(sub_part IS NOT NULL), 0)
|
||||
)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'aihr_practice_assignment'
|
||||
AND index_name = 'uk_aihr_assignment_request';
|
||||
SQL
|
||||
REMOTE
|
||||
)" || fail "remote practice-assignment idempotency-index check failed: $remote_ssh:$remote_db"
|
||||
|
||||
[[ "$practice_assignment_request_unique_index" = "0|tenant_id,request_key,ext_party_id|0" ]] \
|
||||
|| fail "remote practice-assignment idempotency index invalid: expected unique full columns tenant_id,request_key,ext_party_id; got ${practice_assignment_request_unique_index:-missing}"
|
||||
local practice_assignment_recent_content_index
|
||||
practice_assignment_recent_content_index="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
db="$1"
|
||||
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
|
||||
SELECT CONCAT(
|
||||
COALESCE(MIN(non_unique), -1), '|',
|
||||
COALESCE(GROUP_CONCAT(column_name ORDER BY seq_in_index), ''), '|',
|
||||
COALESCE(SUM(sub_part IS NOT NULL), 0)
|
||||
)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'aihr_practice_assignment'
|
||||
AND index_name = 'idx_aihr_assignment_recent_content';
|
||||
SQL
|
||||
REMOTE
|
||||
)" || fail "remote practice-assignment recent-content-index check failed: $remote_ssh:$remote_db"
|
||||
|
||||
[[ "$practice_assignment_recent_content_index" = "1|tenant_id,ext_party_id,source,content_hash,create_time|0" ]] \
|
||||
|| fail "remote practice-assignment recent-content index invalid: expected full columns tenant_id,ext_party_id,source,content_hash,create_time; got ${practice_assignment_recent_content_index:-missing}"
|
||||
local agent_schema_contract
|
||||
agent_schema_contract="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
@@ -597,6 +735,7 @@ REMOTE
|
||||
|| fail "remote work-assistant schema missing required columns: $(printf '%s' "$missing_work_assistant_columns" | tr '\n' ', ' | sed 's/, $//')"
|
||||
echo "remote_schema=64/64 $remote_ssh:$remote_db"
|
||||
echo "remote_work_report_idempotency=3/3 $remote_ssh:$remote_db"
|
||||
echo "remote_practice_curriculum_columns=13/13 $remote_ssh:$remote_db"
|
||||
echo "remote_knowledge_category_columns=7/7 $remote_ssh:$remote_db"
|
||||
echo "remote_broadcast_publish_audit_columns=3/3 $remote_ssh:$remote_db"
|
||||
echo "remote_broadcast_publish_idempotency=3/3 $remote_ssh:$remote_db"
|
||||
@@ -639,6 +778,10 @@ if [[ -n "${RELEASE_REMOTE_URL:-}" ]]; then
|
||||
require_remote_schema
|
||||
fi
|
||||
|
||||
if [[ "${RELEASE_VERIFY_REMOTE_SCHEMA:-false}" == "true" || "${RELEASE_VERIFY_REMOTE_BACKEND:-false}" == "true" ]]; then
|
||||
require_remote_practice_schema_guard
|
||||
fi
|
||||
|
||||
if [[ "${RELEASE_VERIFY_REMOTE_MATCH:-false}" == "true" ]]; then
|
||||
remote_frontend_asset="$(curl -fsS --max-time 15 "$remote/" | sed -nE 's/.*src="(\/assets\/[^" ]+\.js)".*/\1/p' | head -n 1)"
|
||||
remote_mobile_asset="$(curl -fsS --max-time 15 "$remote/h5/" | sed -nE 's/.*src="(\/h5\/assets\/[^" ]+\.js)".*/\1/p' | head -n 1)"
|
||||
|
||||
@@ -23,6 +23,9 @@ docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_personal_knowledge_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_model_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_practice_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260717_practice_five_position_catalog_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260723_practice_content_operations_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260724_practice_growth_curriculum_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_interview_result_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/aihr_org_snapshot_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260721_org_multi_project_membership_mysql8.sql"
|
||||
@@ -35,6 +38,8 @@ docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260723_broadcast_targeting_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260722_broadcast_question_context_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260724_agent_orchestration_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260724_direct_feedback_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260724_broadcast_attachment_mysql8.sql"
|
||||
|
||||
docker exec wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue \
|
||||
-e "select count(*) as tables_count from information_schema.tables where table_schema = 'ry-vue';"
|
||||
|
||||
@@ -119,6 +119,72 @@ mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260715_practice_sessio
|
||||
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'
|
||||
|
||||
# The growth curriculum migration must be able to upgrade the compact legacy
|
||||
# practice tables used by older deployments, and be safe when applied again.
|
||||
mysql "$DB" <<'SQL'
|
||||
ALTER TABLE aihr_practice_session
|
||||
ADD COLUMN tenant_id varchar(20) DEFAULT '000000',
|
||||
ADD COLUMN mode varchar(20) DEFAULT 'mobile',
|
||||
ADD COLUMN scenario_name varchar(100) DEFAULT NULL;
|
||||
CREATE TABLE aihr_practice_scenario (
|
||||
id bigint NOT NULL AUTO_INCREMENT,
|
||||
tenant_id varchar(20) DEFAULT '000000',
|
||||
scenario_code varchar(80) NOT NULL,
|
||||
position varchar(80) DEFAULT '生活顾问',
|
||||
difficulty tinyint DEFAULT 1,
|
||||
goal varchar(1000) DEFAULT NULL,
|
||||
enabled tinyint DEFAULT 1,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_aihr_practice_scenario (tenant_id, scenario_code)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO aihr_practice_scenario (tenant_id, scenario_code, position, difficulty, goal, enabled) VALUES
|
||||
('000000', 'legacy-growth-enabled', '生活顾问', 2, 'legacy goal', 1),
|
||||
('000000', 'legacy-growth-disabled', '保安', 3, 'legacy goal', 0);
|
||||
CREATE TABLE aihr_practice_assignment (
|
||||
id bigint NOT NULL AUTO_INCREMENT,
|
||||
tenant_id varchar(20) DEFAULT '000000',
|
||||
ext_party_id varchar(100) NOT NULL,
|
||||
request_key varchar(100) DEFAULT NULL,
|
||||
source varchar(30) NOT NULL DEFAULT 'manual',
|
||||
content_hash char(64) DEFAULT NULL,
|
||||
create_time datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB;
|
||||
SQL
|
||||
practice_growth_migration="$ROOT_DIR/backend/script/sql/update/aihr_20260724_practice_growth_curriculum_mysql8.sql"
|
||||
test -f "$practice_growth_migration"
|
||||
mysql "$DB" < "$practice_growth_migration"
|
||||
# A high-risk item may already have completed its first review when a release
|
||||
# re-runs this idempotent migration. Its audit trail must survive for the
|
||||
# second reviewer instead of being reset to an unreviewed item.
|
||||
mysql "$DB" <<'SQL'
|
||||
UPDATE aihr_practice_scenario
|
||||
SET review_status = '待业务审核', risk_level = '高风险',
|
||||
reviewer = '首审甲', reviewer_user_id = 101, reviewed_time = '2026-07-24 10:00:00'
|
||||
WHERE scenario_code = 'legacy-growth-enabled';
|
||||
SQL
|
||||
mysql "$DB" < "$practice_growth_migration"
|
||||
practice_growth_scenario_columns="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY column_name) FROM information_schema.columns WHERE table_schema='$DB' AND table_name='aihr_practice_scenario' AND column_name IN ('growth_level','competency_code','collaboration_positions','review_status','risk_level','curriculum_version','reviewer','reviewer_user_id','reviewed_time','second_reviewer','second_reviewer_user_id','second_reviewed_time');")"
|
||||
test "$practice_growth_scenario_columns" = 'collaboration_positions,competency_code,curriculum_version,growth_level,review_status,reviewed_time,reviewer,reviewer_user_id,risk_level,second_reviewed_time,second_reviewer,second_reviewer_user_id'
|
||||
practice_growth_session_columns="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY column_name) FROM information_schema.columns WHERE table_schema='$DB' AND table_name='aihr_practice_session' AND column_name IN ('position_snapshot','project_type_snapshot','growth_level','competency_code','collaboration_positions','curriculum_version','growth_confirmation_level','growth_confirmed_by','growth_confirmed_time');")"
|
||||
test "$practice_growth_session_columns" = 'collaboration_positions,competency_code,curriculum_version,growth_confirmation_level,growth_confirmed_by,growth_confirmed_time,growth_level,position_snapshot,project_type_snapshot'
|
||||
practice_growth_index="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_practice_scenario' AND index_name='idx_aihr_practice_scenario_curriculum';")"
|
||||
test "$practice_growth_index" = 'tenant_id,position,growth_level,competency_code,review_status,enabled'
|
||||
practice_assignment_request_index="$(mysql "$DB" -N -B -e "SELECT CONCAT(MIN(non_unique),'|',GROUP_CONCAT(column_name ORDER BY seq_in_index),'|',SUM(sub_part IS NOT NULL)) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_practice_assignment' AND index_name='uk_aihr_assignment_request';")"
|
||||
test "$practice_assignment_request_index" = '0|tenant_id,request_key,ext_party_id|0'
|
||||
practice_assignment_recent_index="$(mysql "$DB" -N -B -e "SELECT CONCAT(MIN(non_unique),'|',GROUP_CONCAT(column_name ORDER BY seq_in_index),'|',SUM(sub_part IS NOT NULL)) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_practice_assignment' AND index_name='idx_aihr_assignment_recent_content';")"
|
||||
test "$practice_assignment_recent_index" = '1|tenant_id,ext_party_id,source,content_hash,create_time|0'
|
||||
mysql "$DB" -e "ALTER TABLE aihr_practice_assignment DROP INDEX uk_aihr_assignment_request, ADD INDEX uk_aihr_assignment_request (tenant_id, request_key(20), ext_party_id), DROP INDEX idx_aihr_assignment_recent_content, ADD KEY idx_aihr_assignment_recent_content (tenant_id, ext_party_id, source, content_hash);"
|
||||
mysql "$DB" < "$practice_growth_migration"
|
||||
practice_assignment_repaired_request_index="$(mysql "$DB" -N -B -e "SELECT CONCAT(MIN(non_unique),'|',GROUP_CONCAT(column_name ORDER BY seq_in_index),'|',SUM(sub_part IS NOT NULL)) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_practice_assignment' AND index_name='uk_aihr_assignment_request';")"
|
||||
test "$practice_assignment_repaired_request_index" = '0|tenant_id,request_key,ext_party_id|0'
|
||||
practice_assignment_repaired_recent_index="$(mysql "$DB" -N -B -e "SELECT CONCAT(MIN(non_unique),'|',GROUP_CONCAT(column_name ORDER BY seq_in_index),'|',SUM(sub_part IS NOT NULL)) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_practice_assignment' AND index_name='idx_aihr_assignment_recent_content';")"
|
||||
test "$practice_assignment_repaired_recent_index" = '1|tenant_id,ext_party_id,source,content_hash,create_time|0'
|
||||
practice_growth_statuses="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(CONCAT(scenario_code,':',review_status) ORDER BY scenario_code) FROM aihr_practice_scenario WHERE scenario_code LIKE 'legacy-growth-%';")"
|
||||
test "$practice_growth_statuses" = 'legacy-growth-disabled:待业务审核,legacy-growth-enabled:待业务审核'
|
||||
practice_growth_first_review="$(mysql "$DB" -N -B -e "SELECT CONCAT(COALESCE(reviewer,''),':',COALESCE(reviewer_user_id,'')) FROM aihr_practice_scenario WHERE scenario_code='legacy-growth-enabled';")"
|
||||
test "$practice_growth_first_review" = '首审甲:101'
|
||||
|
||||
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');")"
|
||||
@@ -436,4 +502,4 @@ test "$agent_run_unique" = '0|run_id'
|
||||
agent_user_index="$(mysql "$DB" -N -B -e "SELECT GROUP_CONCAT(column_name ORDER BY seq_in_index) FROM information_schema.statistics WHERE table_schema='$DB' AND table_name='aihr_agent_run' AND index_name='idx_aihr_agent_run_user';")"
|
||||
test "$agent_user_index" = 'tenant_id,user_id,create_time'
|
||||
|
||||
echo "PASS: AIHR legacy schema migrations are idempotent, including Agent run audit, knowledge-space categories, practice evidence, knowledge feedback, candidate interview review, position/SOP qualification contracts, assistant capture, work-report idempotency, broadcast publish/withdraw audit with M1 targeting defaults and target-table contracts, v1 snapshots, and trusted broadcast question context"
|
||||
echo "PASS: AIHR legacy schema migrations are idempotent, including Agent run audit, practice growth curriculum snapshots, knowledge-space categories, practice evidence, knowledge feedback, candidate interview review, position/SOP qualification contracts, assistant capture, work-report idempotency, direct feedback, broadcast publish/withdraw audit with M1 targeting and file attachment contracts, v1 snapshots, and trusted broadcast question context"
|
||||
|
||||
Reference in New Issue
Block a user