import fs from 'node:fs' import path from 'node:path' // Explicit TEST identity handoff. Reuses an existing PDA account without changing roles or account state. export async function createF33PdaOperator({ env, credentialFile, reportFile }) { if (String(env.CHONGCHONG_ENV).toUpperCase() !== 'TEST') throw Error('EXPLICIT_TEST_REQUIRED') if (fs.existsSync(credentialFile) || fs.existsSync(reportFile)) throw Error('EXISTING_RESULT_RECONCILE_NO_RECREATE') const warehouseId = '193000000000200003', roleCode = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR' const actors = JSON.parse(env.CHONGCHONG_ACCEPTANCE_PDA_ACTORS || '[]') const actor = actors.find(item => String(item.warehouseId) === warehouseId && item.membershipId && item.username && item.password) if (!actor) throw Error('EXISTING_PDA_ACCOUNT_CONFIGURATION_REQUIRED_NO_CREATE') const report = { reused: true, startedAt: new Date().toISOString(), warehouseId, roleCode, requests: [], success: false, existingAccountsChanged: false, rolePermissionsChanged: false, businessOperationsIssued: 0 } const save = () => { fs.mkdirSync(path.dirname(reportFile), {recursive:true}); fs.writeFileSync(reportFile, JSON.stringify(report,null,2)) } let admin, pda const call = async(method, route, body, token=admin?.accessToken) => { const entry={method,path:route.split('?')[0],phase:'INTENT'};report.requests.push(entry);save() let response try { response=await fetch(env.CHONGCHONG_ADMIN_API_BASE_URL.replace(/\/$/,'')+route,{method,redirect:'error',signal:AbortSignal.timeout(20000),headers:{Accept:'application/json',...(token?{Authorization:`Bearer ${token}`} : {}),...(body?{'Content-Type':'application/json'}:{})},...(body?{body:JSON.stringify(body)}:{})}) } catch {entry.phase='OUTCOME_UNKNOWN';save();throw Error('OUTCOME_UNKNOWN_RECONCILE_NO_RETRY')} const value=JSON.parse(await response.text());Object.assign(entry,{phase:'ACKNOWLEDGED',http:response.status,code:String(value.code),requestId:response.headers.get('x-request-id'),traceId:response.headers.get('x-trace-id')});save() if(response.status!==200||String(value.code)!=='200')throw Error(`FORMAL_API_REJECTED_${response.status}_${value.code}`) return value.data } try { admin=await call('POST','/auth/login',{loginId:env.CHONGCHONG_ADMIN_USERNAME,password:env.CHONGCHONG_ADMIN_PASSWORD},'') const roles=await call('GET','/platform/v1/iam/roles') const permissions=await call('GET','/platform/v1/iam/permissions') const role=roles.find(r=>r.roleCode===roleCode&&r.status==='ACTIVE') const operate=permissions.find(p=>p.permissionCode==='lastleg:pda:operate') if(!role||!operate||!(role.permissionIds||[]).some(id=>String(id)===String(operate.id)))throw Error('EXISTING_ROLE_OPERATE_PERMISSION_REQUIRED') let created for (let page=1;page<=100;page++) { const users=await call('GET',`/platform/v1/iam/users?page=${page}&size=100`) if(!Array.isArray(users?.records)||!Number.isSafeInteger(Number(users.total)))throw Error('EXISTING_ACCOUNT_PAGE_INVALID') created=users.records.find(row=>String(row.membershipId)===String(actor.membershipId)&&row.username===actor.username) if(created||page*100>=Number(users.total))break } if(!created)throw Error('EXISTING_ACCOUNT_NOT_FOUND_NO_CREATE') const username=actor.username,password=actor.password report.subject={membershipId:String(created.membershipId),userId:String(created.userId),authUserId:String(created.authUserId), tenantId:String(created.tenantId),roleIds:(created.roleIds||[]).map(String),overseasWarehouseId:String(created.overseasWarehouseId), domesticWarehouseId:created.domesticWarehouseId??null,status:created.status,protectedAccount:created.protectedAccount} save() if(report.subject.tenantId!=='0'||report.subject.overseasWarehouseId!==warehouseId||report.subject.status!=='ACTIVE' ||report.subject.domesticWarehouseId!==null||report.subject.roleIds.length!==1||report.subject.roleIds[0]!==String(role.id))throw Error('EXISTING_SUBJECT_SCOPE_MISMATCH') fs.mkdirSync(path.dirname(credentialFile),{recursive:true}) fs.writeFileSync(credentialFile,`PDA_USERNAME=${username}\nPDA_PASSWORD=${password}\nPDA_MEMBERSHIP_ID=${actor.membershipId}\n`,{flag:'wx',mode:0o600}) pda=await call('POST','/auth/login',{loginId:username,password},'') if(pda.passwordChangeRequired||pda.mustChangePassword||pda.firstLogin||!pda.accessToken)throw Error('FIRST_PASSWORD_CHANGE_OR_NORMAL_LOGIN_BLOCKED') if(!(pda.authorities||[]).includes('lastleg:pda:operate')||!(pda.roles||[]).includes(roleCode)||(pda.roles||[]).length!==1)throw Error('NORMAL_LOGIN_ROLE_OR_PERMISSION_MISMATCH') const profile=await call('GET','/pda/v1/last-leg/receiving-containers/warehouse-profile',undefined,pda.accessToken) report.profile={warehouseId:String(profile.warehouseId),warehouseCode:profile.warehouseCode,warehouseName:profile.warehouseName} if(report.profile.warehouseId!==warehouseId||report.profile.warehouseCode!=='US-LAX-01')throw Error('FORMAL_WAREHOUSE_PROFILE_MISMATCH') report.cleanup={sessionLogoutOnly:true,sharedAccountStateUnchanged:true} report.status='ACTIVE_FOR_COORDINATOR_UI';report.loginVerified=true;report.warehouseProfileVerified=true;report.success=true }catch(error){report.failure=String(error.message).replace(/https?:\/\/\S+/g,'[redacted]')} finally{ if(pda?.refreshToken){try{await call('POST','/auth/logout',{refreshToken:pda.refreshToken},pda.accessToken);report.pdaSessionClosed=true}catch{report.pdaSessionClosed=false;report.success=false}}else report.pdaSessionClosed=!pda if(admin?.refreshToken){try{await call('POST','/auth/logout',{refreshToken:admin.refreshToken},admin.accessToken);report.adminSessionClosed=true}catch{report.adminSessionClosed=false;report.success=false}}else report.adminSessionClosed=!admin save() } return report }