|
- import fs from 'node:fs';
- import assert from 'node:assert/strict';
- import {login,call} from './role-permissions-live.mjs';
- import {scripts,scriptDefinition} from '../../unreal_tran_web/src/features/virtual-training-scripts/definition.js';
- const dir='reports/bridge-new-models-006-008-20260917';fs.mkdirSync(dir,{recursive:true});
- const signed=await login('root');
- const api=async(endpoint,body,method)=>{const r=await call('tran/v1/'+endpoint,signed.accessToken,body,method);assert.equal(r.status,200,endpoint+': '+r.message);return r.data;};
- const backup=(name,value)=>{const p=dir+'/'+name+'.json';if(!fs.existsSync(p))fs.writeFileSync(p,JSON.stringify(value,null,2));};
- for(const id of [86,116])backup('unchanged-'+id,await api('teaching/assignments/'+id));
- const migrated=[];
- for(const [id,code]of [[87,'TASK-VIRTUAL-006'],[88,'TASK-VIRTUAL-007'],[89,'TASK-VIRTUAL-008']]){
- let task=await api('teaching/assignments/'+id),detail=await api('content/projects/'+task.contentProjectId);
- assert.equal(task.code,code);const script=scripts.find(s=>s.code===code);assert.equal(task.definitionSnapshot.runtime.scriptId,script.id);
- backup('before-task-'+id,task);backup('before-project-'+task.contentProjectId,detail);
- if(task.definitionSnapshot.runtime.scriptVersion==='4'){migrated.push({id,code,versionId:task.contentVersionId});continue;}
- const content=structuredClone(detail.currentVersion.content),next=scriptDefinition(script);
- // Retain all scoring, speech assets, step codes, observations and task membership.
- content.scenario=next.scenario;content.runtime={...content.runtime,scriptVersion:'4'};
- if(code==='TASK-VIRTUAL-006'){
- const current=content.steps[4],replacement=next.steps[4];
- current.action=replacement.action;current.targetId=replacement.targetId;current.targetName='滤油器出口球阀 1';
- }
- if(detail.currentVersion.content.runtime.scriptVersion!=='4'){
- detail=await api('content/projects/'+detail.project.id,{...detail.project,content,assets:detail.currentVersion.assets,dependencies:detail.currentVersion.dependencies,version:detail.project.version,changeSummary:'换用0916整车及配套零件,原位操作;保留步骤编码、讲解与成绩规则'},'PUT');
- }
- if(detail.project.publishedVersionId!==detail.currentVersion.id)detail=await api('content/projects/'+detail.project.id+'/publish',{version:detail.project.version});
- if(id!==87 && task.status==='PUBLISHED'){
- task=await api('teaching/assignments/'+id+'/model-version',{contentVersionId:detail.project.publishedVersionId,version:task.version,reason:'只更新模型,保留步骤、操作、讲解、成绩及已有训练记录'},'PUT');
- }else{
- if(task.status==='PUBLISHED')task=await api('teaching/assignments/'+id+'/withdraw',{version:task.version,reason:'更新为已核验的0916模型版本,保留原任务与历史训练记录'});
- assert.ok(['DRAFT','WITHDRAWN'].includes(task.status));
- task=await api('teaching/assignments/'+id,{...task,contentVersionId:detail.project.publishedVersionId,version:task.version},'PUT');
- task=await api('teaching/assignments/'+id+'/publish',{version:task.version});
- }
- assert.equal(task.status,'PUBLISHED');assert.equal(task.definitionSnapshot.runtime.scriptVersion,'4');
- migrated.push({id,code,projectId:task.contentProjectId,versionId:task.contentVersionId,steps:task.definitionSnapshot.steps.length});console.log(migrated.at(-1));
- }
- for(const id of [86,116]){const before=JSON.parse(fs.readFileSync(dir+'/unchanged-'+id+'.json')),after=await api('teaching/assignments/'+id);delete before.serverNow;delete after.serverNow;assert.deepEqual(after,before);}
- fs.writeFileSync(dir+'/migration.json',JSON.stringify({pass:true,migrated,unchanged:[86,116]},null,2));
|