| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- // Read-only acceptance of the existing v2. Never calls start, save or import.
- import fs from 'node:fs';
- import assert from 'node:assert/strict';
- import crypto from 'node:crypto';
- import {invoke,classRows} from '../server/scripts/platform-client.mjs';
- import {loadPublicBoard} from '../src/services/workshop-data.js';
- const sessionId='btrFqkz0yw',artifactId='G8IrkkDG7X',previousArtifactId='cOm6c8gg7z',outputSourceId='SwVWicwjev';
- const template=JSON.parse(fs.readFileSync('work/first-live-S1-v2-template.json','utf8'));
- const oldTemplate=JSON.parse(fs.readFileSync('server/test/fixtures/first-live-S1-20261102.json','utf8'));
- const sha=x=>crypto.createHash('sha256').update(x).digest('hex');
- const read=async(className,objectId)=>{
- const r=await invoke('ksfGetRecord',{className,objectId});
- assert.equal(r.http,200);assert.equal(r.body?.result?.ok,true);return r.body.result.data.record;
- };
- try{
- const [session,artifact,previous,output,origins,history]=await Promise.all([
- read('KfSession',sessionId),read('KfArtifact',artifactId),read('KfArtifact',previousArtifactId),read('KfSource',outputSourceId),
- Promise.all(template.sourceIds.map(id=>read('KfSource',id))),
- classRows('KfArtifact',{workshopKey:'KSF-真实资料-20261102-01'})
- ]);
- assert.equal(session.dataMode,'live');assert.equal(artifact.sessionRef?.objectId,sessionId);assert.equal(artifact.ownerSession,sessionId);
- assert.equal(artifact.sourceRef?.objectId,outputSourceId);
- for(const field of ['title','rawText','version','stageCode','artifactType'])assert.deepEqual(artifact[field],template[field],field);
- assert.equal(artifact.dataMode,'live');assert.equal(artifact.dashboardState,'workshop');
- assert.equal(artifact.report.title,template.title);assert.ok(Number.isFinite(Date.parse(artifact.report.generatedAt)));
- assert.equal(artifact.report.executive[0],'课堂过程成果,未经员工正式确认;待验证项不作为市场结论。');
- assert.deepEqual(artifact.report.executive.slice(1),template.report.executive);
- for(const field of ['chapters','evidence'])assert.deepEqual(artifact.report[field],template.report[field],field);
- assert.deepEqual(artifact.meta.workshop.sourceIds,template.sourceIds);
- assert.deepEqual(artifact.meta.workshop.pendingQuestions,template.pendingQuestions);
- assert.equal(artifact.meta.workshop.formalConfirmation,false);
- assert.equal(artifact.contentConfirmedAt??null,null);assert.equal(artifact.dashboardPublishedAt??null,null);
- assert.equal(artifact.projectRef??null,null);
- assert.equal(output.rawText,template.rawText);assert.equal(output.contentHash,sha(template.rawText));assert.equal(output.dataMode,'live');
- let quotes=0;
- for(const entry of Object.values(artifact.report.evidence)){
- const origin=origins.find(o=>o.objectId===entry.sourceId);assert.ok(origin);assert.equal(origin.dataMode,'live');
- for(const q of entry.quotes){assert.ok(origin.rawText.includes(q.text));quotes++;}
- }
- assert.equal(quotes,5);assert.equal(artifact.sources.length,5);assert.equal(artifact.evidenceCount,5);
- for(const field of ['title','rawText','version','stageCode'])assert.deepEqual(previous[field],oldTemplate[field]);
- assert.equal(previous.reportSeriesKey,artifact.reportSeriesKey);assert.equal(artifact.reportSeriesKey,template.taskKey);
- assert.deepEqual(previous.meta.attribution,artifact.meta.attribution);assert.deepEqual(session.meta.attribution,artifact.meta.attribution);
- const participantAccountKey='participant-account:f83edd27dda7e0989a0d313c158314043fd129efb86b8f6a07db8140033c5708';
- const expected='participant:'+sha(JSON.stringify([session.workshopKey,participantAccountKey]));
- assert.equal(session.meta.attribution.participantKey,expected);
- const versions=history.filter(a=>a.reportSeriesKey===template.taskKey).sort((a,b)=>a.version-b.version);
- assert.deepEqual(versions.map(a=>[a.objectId,a.version]),[[previousArtifactId,1],[artifactId,2]]);
- const raw=await loadPublicBoard({url:'https://kangshifu.fmode.cn/api/functions',appId:'FKieRbIoGt_main'});
- for(const [id,version]of [[previousArtifactId,1],[artifactId,2]]){
- assert.ok(raw.artifact.some(a=>a.objectId===id&&a.version===version&&a.dataMode==='live'));
- }
- for(const privateValue of [session.meta.attribution.participantAccount?.accountId,session.meta.attribution.agentAccount?.accountId,session.meta.attribution.conversationKey].filter(Boolean)){
- assert.equal(JSON.stringify(raw).includes(privateValue),false);
- }
- const result={ok:true,operation:'live-S1-v2-independently-verified',at:new Date().toISOString(),readOnly:true,businessWrites:0,
- sessionId,artifactId,previousArtifactId,outputSourceId,reportUrl:'https://kangshifu.fmode.cn/report/'+artifactId,
- version:2,stageCode:'S1',dataMode:'live',dashboardState:'workshop',reportSeriesKey:artifact.reportSeriesKey,
- versions:versions.map(a=>({artifactId:a.objectId,version:a.version})),previousVersionRef:artifact.previousVersionRef?.objectId??null,
- versionIdentification:'reportSeriesKey + workshop attribution + version',derivedParticipantMatched:true,participantKeyPrefix:'participant',
- privateAttributionMatched:true,previousVersionPreserved:true,templateMatched:true,sourceIds:template.sourceIds,
- reportQuoteCount:quotes,pendingQuestionCount:template.pendingQuestions.length,publicBoardDataVerified:true,
- formalReportPublished:false,employeeConfirmed:false,browserVerified:false};
- fs.writeFileSync('work/live-S1-v2-readback-20261102.json',JSON.stringify(result,null,2)+'\n');console.log(JSON.stringify(result,null,2));
- }catch(e){
- console.error(JSON.stringify({ok:false,error:'LIVE_S1_V2_READBACK_STOPPED',checkLine:e.stack?.match(/verify-live-S1-v2-readback\.mjs:(\d+):/)?.[1],readOnly:true,businessWrites:0}));
- process.exitCode=1;
- }
|