| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- // Read-only verification of the completed sample run; never replays either import.
- import fs from 'node:fs';
- import assert from 'node:assert/strict';
- import crypto from 'node:crypto';
- import {request,classRows} from '../server/scripts/platform-client.mjs';
- import {TASK_KEY,dedupTask} from './workshop-dedup-acceptance.mjs';
- const sourceId='V6AS9Qf10d',materialId='SGOF-c5vTo';
- const rounds=[
- {round:'batch-a',jobId:'2MDXH_CzC5',operation:'created',created:1,unchanged:0,externalKey:TASK_KEY+':material:a',invocationId:'d23c55cc-bea2-4fb6-99a7-df53aca5d8e1',entryInvocationId:'fc6eb96b-6bd7-4aab-96f9-e54cd139d742'},
- {round:'batch-b',jobId:'L68OPSHuXW',operation:'unchanged',created:0,unchanged:1,externalKey:TASK_KEY+':material:b',invocationId:'4f984682-6fa7-4696-b29b-b7eb04026676',entryInvocationId:'df418c3a-fbf0-44c1-9b0f-b030b38e01b3'}
- ];
- const pointer=(className,objectId)=>({__type:'Pointer',className,objectId});
- const get=(className,id)=>request('GET','/classes/'+className+'/'+encodeURIComponent(id));
- try{
- const task=dedupTask('a'),contentHash=crypto.createHash('sha256').update(task.source.rawText).digest('hex');
- const [source,material,sources,materials,jobs]=await Promise.all([
- get('KfSource',sourceId),get('KfMaterial',materialId),
- classRows('KfSource',{contentHash}),classRows('KfMaterial',{name:task.records[0].data.name}),
- classRows('KfImportJob',{jobKey:{$regex:TASK_KEY}})
- ]);
- assert.equal(source.objectId,sourceId);assert.equal(material.objectId,materialId);
- for(const [k,v]of Object.entries(task.source))assert.deepEqual(source[k],v);
- assert.equal(source.contentHash,contentHash);
- for(const [k,v]of Object.entries(task.records[0].data))assert.deepEqual(material[k],v);
- assert.deepEqual(material.sourceRef,pointer('KfSource',sourceId));
- assert.equal(sources.length,1);assert.equal(sources[0].objectId,sourceId);
- assert.equal(materials.length,1);assert.equal(materials[0].objectId,materialId);
- assert.equal(material.externalKey,rounds[0].externalKey,'reuse preserves original business key');
- assert.equal(jobs.length,2);assert.deepEqual(jobs.map(j=>j.objectId).sort(),rounds.map(r=>r.jobId).sort());
- const result=[];
- for(const round of rounds){
- const job=jobs.find(j=>j.objectId===round.jobId),items=await classRows('KfImportItem',{jobRef:pointer('KfImportJob',round.jobId)});
- assert.equal(job.status,'succeeded');assert.equal(job.expectedCount,1);assert.equal(job.successCount,1);assert.equal(job.failureCount,0);
- assert.ok(job.jobKey.endsWith(':'+TASK_KEY+':'+round.round+':item:material'));
- assert.deepEqual(job.inputSourceRef,pointer('KfSource',sourceId));
- const counts=JSON.parse(job.summary).counts;
- assert.equal(counts.created,round.created);assert.equal(counts.unchanged,round.unchanged);
- assert.equal(counts.updated,0);assert.equal(counts.failed,0);
- assert.equal(items.length,1);const item=items[0];
- assert.equal(item.itemKey,'material');assert.equal(item.targetClass,'KfMaterial');assert.equal(item.targetId,materialId);
- assert.equal(item.status,'succeeded');assert.equal(item.operation,round.operation);assert.equal(item.businessKey,round.externalKey);
- result.push({round:round.round,jobId:round.jobId,sourceId,materialId,created:counts.created,unchanged:counts.unchanged,operation:item.operation});
- }
- assert.deepEqual(jobs[0].producer.agent,jobs[1].producer.agent);
- assert.equal(jobs[0].producer.agent.key,'agent-account:7c9f85363ca4c5a529a5b363308b065998924e2394e846145a5c62c904506d2e');
- const receipt={ok:true,operation:'sample-material-dedup-independently-verified',at:new Date().toISOString(),readOnly:true,businessWrites:0,taskKey:TASK_KEY,sourceId,materialId,rounds:result,exactSourceMatches:sources.length,exactMaterialMatches:materials.length,importJobCount:jobs.length,importItemCount:2,originalMaterialBusinessKeyPreserved:true,sameAgentAttribution:true,dataMode:'sample',actualPlatformCollectionPerformed:false,formalReportPublished:false,invocationEvidence:{basis:'user-forwarded-tool-receipts; IDs not independently authenticated by database',rounds:rounds.map(({round,invocationId,entryInvocationId})=>({round,invocationId,entryInvocationId}))}};
- fs.writeFileSync('work/dedup-acceptance-readback-20261102.json',JSON.stringify(receipt,null,2));
- console.log(JSON.stringify(receipt,null,2));
- }catch{
- console.error(JSON.stringify({ok:false,error:'DEDUP_READBACK_FAILED',message:'只读核验未通过;未输出原始异常、账号或凭据。'}));
- process.exitCode=1;
- }
|