|
|
@@ -1,6 +1,7 @@
|
|
|
#!/usr/bin/env node
|
|
|
// Patch only payroll entry points in the live shared gateway; preserve other releases.
|
|
|
import fs from 'node:fs';import path from 'node:path';import {createHash} from 'node:crypto';
|
|
|
+import {normalizeHistoricalReservationPreviewBase} from './payroll-gateway-transform.mjs';
|
|
|
const base=(process.env.XIAOSHU_PARSE_URL||'https://server.xiaoshu.pro/parse').replace(/\/$/,''),app=process.env.XIAOSHU_PARSE_APP_ID||'7pIbDBJmKx_main',master=process.env.XIAOSHU_MASTER_KEY;
|
|
|
if(!master)throw Error('缺少 XIAOSHU_MASTER_KEY');const out=process.env.XIAOSHU_PAYROLL_REPORT_DIR||path.resolve('artifacts/payroll-integrity');fs.mkdirSync(out,{recursive:true,mode:0o700});
|
|
|
async function api(p,method='GET',body){const res=await fetch(base+p,{method,headers:{'Content-Type':'application/json','X-Parse-Application-Id':app,'X-Parse-Master-Key':master},body:body?JSON.stringify(body):undefined});const data=await res.json();if(!res.ok||data.error)throw Error(data.error||'HTTP '+res.status);return data;}
|
|
|
@@ -13,9 +14,9 @@ for(const name of ['xiaoshu.ops.gateway','xiaoshu.ops.gateway.v3','xiaoshu.admin
|
|
|
const desired=source.match(/^function operationsRoleOf\(context\).*$/m)[0];if(!/^function operationsRoleOf\(context\).*$/m.test(code))throw Error('身份网关版本不兼容');code=code.replace(/^function operationsRoleOf\(context\).*$/m,desired);
|
|
|
}else{
|
|
|
if(code.includes(marker))code=code.slice(0,code.indexOf(marker));
|
|
|
+ code=normalizeHistoricalReservationPreviewBase(code);
|
|
|
code=code.replace(/^function roleOf\(context\).*$/m,raw.match(/^function roleOf\(context\).*$/m)[0]);
|
|
|
if(!code.includes("context=await auth(request);requireRole(context,['ops-manager','ops-staff','ops-auditor']);"))code=code.replace('context=await auth(request);',"context=await auth(request);requireRole(context,['ops-manager','ops-staff','ops-auditor']);");
|
|
|
- code=code.replace('async function historicalReservationPreview(context,input){','async function historicalReservationPreviewLegacy(context,input){');
|
|
|
code=code.replace("requireRole(context,['ops-manager','ops-staff','ops-auditor']);await releaseExpiredReservations(context,input);","requireRole(context,['ops-manager','ops-staff','ops-auditor']);");
|
|
|
for(const op of ['export','exclude-line']){const re=new RegExp("^ if\\(operation==='ops/payroll/"+op+"'\\).*?$",'m');if(!re.test(code))throw Error('工资路由版本不兼容 '+op);code=code.replace(re,raw.match(re)[0]);}
|
|
|
const extra=["ops/payroll/coaches","ops/course-mappings/students","ops/course-mappings/student-commit"].filter(op=>!code.includes("operation==='"+op+"'" )).map(op=>raw.split('\n').find(line=>line.includes("operation==='"+op+"'"))).join('\n');
|