import {test,after} from 'node:test'; import assert from 'node:assert/strict'; import {readFileSync} from 'node:fs'; import vm from 'node:vm'; import {PGlite} from '@electric-sql/pglite'; const source=readFileSync(new URL('../deploy-admin-functions.mjs',import.meta.url),'utf8'); const baseline=JSON.parse(readFileSync(new URL('../../perf/admin-data-2026-10-15/legacy-read-queries.json',import.meta.url),'utf8')); const db=new PGlite(),query=async(sql,args)=>(await db.query(sql,args)).rows; after(()=>db.close()); const ctx=vm.createContext({Psql:{query},companyIdOf:()=> 'a'}); vm.runInContext(source.match(/const operationsGatewayCode = String.raw`([\s\S]*?)\n`;/)[1],ctx); const sorted=rows=>rows.toSorted((a,b)=>JSON.stringify(a).localeCompare(JSON.stringify(b))); test('set-based course and appointment reads preserve tenant, cancellation, duplicates and missing metadata',async()=>{ await db.exec(`CREATE TABLE "CommonModel"(company text,"modelId" numeric,"itemId" numeric,status numeric); CREATE TABLE "CourseAppointment"(company text,id numeric,szyh text,dszt text,dslx text,yysj text,bxrq text,kcid text); CREATE TABLE "CourseBinding"(company text,kcid text); CREATE TABLE "Node"(company text,"nodeId" numeric,"parentId" numeric,"nodeName" text); INSERT INTO "Node" VALUES ('a',1,0,'小学'),('a',2,1,'课程甲'),('a',3,1,'课程乙'),('a',398,1,'写作'),('a',8,1,'未使用'),('b',2,0,'其他帐套课程'); INSERT INTO "CourseBinding" VALUES('a','2'),('a','2'),('a','bad'),('b','8'); INSERT INTO "CourseAppointment" VALUES('a',1,'s1','0','3','2099-01-02',null,'3'),('a',2,'s1','30','1','2026-10-01',null,'3'),('a',3,'s2','11','3',null,'2099-01-03','3'),('a',4,'s2','99','1',null,null,null),('a',5,null,null,null,null,null,null),('b',1,'s1','20','3',null,null,'2'); INSERT INTO "CommonModel" VALUES('a',54,1,99),('a',54,1,-2),('a',54,1,-2),('a',54,2,99),('a',59,3,-2),('b',54,3,-2),('b',54,1,99);`); const courseSql=vm.runInNewContext(source.match(/courseSql=('[\s\S]*?'),\[categories/)[1]); for(const co of ['a','b',null]){ assert.deepEqual(sorted(await ctx.memberAppointmentStats(co)),sorted(await query(baseline.appointments,[co]))); assert.deepEqual(await query(courseSql,[co]),await query(baseline.courses,[co])); } const members=await ctx.memberAppointmentStats('a'); assert.equal(members.find(r=>r.uid==='s1').appointment_count,2); assert.equal(members.find(r=>r.uid==='s1').unfinished,0); assert.equal(members.find(r=>r.uid==='s2').unfinished,1); assert.equal(members.find(r=>r.uid==='s2').abnormal,1); assert.deepEqual((await query(courseSql,['a'])).map(r=>r.id).sort(),['2','3','398']); });