import { open, mkdir, readFile } from 'node:fs/promises' import { resolve, dirname } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' import { parseEnv } from 'node:util' import { createHash } from 'node:crypto' import { AcceptanceRun } from './admin-test-env-acceptance.mjs' import { runQuoteSession } from './admin-test-env-modules/fleet-quotes-operations.mjs' export const READY_COMMIT = 'a6fd0ba3' export const MARKER = 'FLEET-QUOTE-20261003' const repository = resolve(dirname(fileURLToPath(import.meta.url)), '..') const outputDirectory = resolve(repository, 'reports/fleet-quote-live-20261003') const sensitive = /password|token|authorization|cookie|secret|loginId|username/i export function requireTestProfile(args, execArgs) { if (args.length !== 1 || args[0] !== `--ready-commit=${READY_COMMIT}`) throw new Error('Explicit current ready-commit required; no resume or replay mode') const files = [] for (let i = 0; i < execArgs.length; i++) { if (execArgs[i].startsWith('--env-file=')) files.push(execArgs[i].slice(11)) else if (execArgs[i] === '--env-file') files.push(execArgs[++i]) else throw new Error('Only the explicit TEST env-file runtime option is allowed') } if (files.length !== 1 || !files[0] || !resolve(files[0]).replaceAll('\\', '/').endsWith('/.codex/env/chongchong-global/test-acceptance.env')) throw new Error('Explicit authorized TEST profile required') return resolve(files[0]) } /** Append-only, fsync-before-send evidence. A fixed exclusive claim prohibits automatic reruns even after a crash. */ export async function installQuoteJournal(context, directory, { persist, secrets = [] } = {}) { let sequence = 0, halted = false const knownSecrets = new Set(secrets.filter(Boolean)) function discover(value) { if (!value || typeof value !== 'object') return for (const [key, child] of Object.entries(value)) { if (sensitive.test(key) && typeof child === 'string' && child) knownSecrets.add(child) else if (child && typeof child === 'object') discover(child) } } function clean(value) { discover(value) if (typeof value === 'string') { let result = value for (const secret of knownSecrets) result = result.split(secret).join('[REDACTED]') return result } if (Array.isArray(value)) return value.map(clean) if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, sensitive.test(key) ? '[REDACTED]' : clean(child)])) return value } const save = persist || (async (name, value) => { const file = await open(resolve(directory, name), 'wx', 0o600) try { await file.writeFile(`${JSON.stringify(value, null, 2)}\n`, 'utf8'); await file.sync() } finally { await file.close() } }) async function checkpoint(kind, value) { const name = `${String(++sequence).padStart(5, '0')}-${kind}.json` await save(name, clean({ marker: MARKER, at: new Date().toISOString(), ...value })) return name } await checkpoint('claim', { expectedCommit: READY_COMMIT, scope: 'QUOTES_ONLY', status: 'CLAIMED', rerun: 'FORBIDDEN; reconcile original samples manually' }) async function bodyEvidence(body) { if (!(body instanceof FormData)) return body === undefined ? { encoding: 'absent' } : { encoding: 'json', value: structuredClone(body) } const parts = [] for (const [name, value] of body.entries()) { if (typeof value === 'string') parts.push({ name, value }) else { const bytes = Buffer.from(await value.arrayBuffer()) parts.push({ name, filename: value.name, contentType: value.type, size: bytes.length, sha256: createHash('sha256').update(bytes).digest('hex'), base64: bytes.toString('base64') }) } } return { encoding: 'multipart', parts } } for (const name of ['request', 'requestWithBody', 'requestBinary']) { const original = context[name].bind(context) context[name] = async (method, path, ...rest) => { method = String(method).toUpperCase() const logout = method === 'POST' && path === '/api/auth/logout' if (halted && !logout) throw new Error('Unknown request outcome: halted; original sample retained, no retry or cleanup') const body = name === 'requestBinary' ? undefined : rest[0] discover(body) const request = { method, path, transport: name, body: await bodyEvidence(body), headers: name === 'requestBinary' ? {} : rest[2] || {}, idempotencyKey: body?.idempotencyKey ?? null } let sample try { sample = await checkpoint('before', request) } catch (error) { halted = true; context.quoteRequestOutcomeUnknown = true; throw error } let response try { response = await original(method, path, ...rest) } catch { response = { http: 0, body: null, requestId: null, traceId: null } } discover(response?.body) const code = String(response?.body?.code ?? '') const write = !['GET', 'HEAD'].includes(method) const known = response?.http === 200 && (code === '200' || /^A04\d+$/.test(code)) || response?.http >= 400 && response?.http < 500 && response?.http !== 408 const unknown = write && !known if (unknown) { halted = true; context.quoteRequestOutcomeUnknown = true } try { await checkpoint('after', { sample, method, path, outcome: unknown ? 'UNKNOWN_STOP' : 'RECEIVED', http: response?.http, code, requestId: response?.requestId, traceId: response?.traceId, // Only write responses belong to our isolated fixture. Do not persist unrelated directory records. body: write ? response?.body : undefined, createdResources: context.createdResources, steps: context.steps }) } catch (error) { halted = true; context.quoteRequestOutcomeUnknown = true; throw error } if (unknown) throw new Error('Unknown write outcome; reconcile persisted original request before further business actions') return response } } const executeModule = context.executeModule.bind(context) context.executeModule = async (name, handler) => { await checkpoint('module-start', { module: name, createdResources: context.createdResources }) try { return await executeModule(name, handler) } finally { await checkpoint('module-end', { module: name, createdResources: context.createdResources, steps: context.steps, modules: context.modules }) } } return { checkpoint, unknown: () => halted } } export async function execute(args = process.argv.slice(2), execArgs = process.execArgv) { const file = requireTestProfile(args, execArgs) if (!repository.replaceAll('\\', '/').endsWith('/chongchong-global/baiyue-firstleg')) throw new Error('Only registered TEST workspace is allowed') const env = parseEnv(await readFile(file, 'utf8')) if (env.CHONGCHONG_ENV !== 'test' || !env.CHONGCHONG_ADMIN_USERNAME || !env.CHONGCHONG_ADMIN_PASSWORD) throw new Error('TEST credentials missing') const base = new URL(env.CHONGCHONG_ADMIN_API_BASE_URL) if (!['http:', 'https:'].includes(base.protocol) || base.pathname.replace(/\/$/, '') !== '/api' || base.username || base.password || base.search || base.hash) throw new Error('Invalid unified TEST API base') await mkdir(outputDirectory, { recursive: true }) const context = new AcceptanceRun({ environment: 'test', gateway: base.origin, username: env.CHONGCHONG_ADMIN_USERNAME, password: env.CHONGCHONG_ADMIN_PASSWORD, quiet: true, modules: [] }) const journal = await installQuoteJournal(context, outputDirectory, { secrets: [env.CHONGCHONG_ADMIN_USERNAME, env.CHONGCHONG_ADMIN_PASSWORD] }) let report try { report = await runQuoteSession(context, { marker: MARKER }) } catch { report = { success: false, fatal: 'Session interrupted; inspect durable request checkpoints', operationsStatus: 'NOT_TESTED' } } finally { context.token = ''; context.refreshToken = '' } const success = Boolean(report.success) && !journal.unknown() await journal.checkpoint('final', { ...report, success, outcome: journal.unknown() ? 'UNKNOWN_STOP' : success ? 'VERIFIED' : 'FAILED', createdResources: context.createdResources }) return { outputDirectory, success, realExecution: true } } if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { execute().then(result => { console.log(JSON.stringify(result)); process.exitCode = result.success ? 0 : 1 }) .catch(() => { console.error('报价验收未启动或已中止;核对TEST配置、就绪标记和持久检查点,禁止自动重跑。'); process.exitCode = 1 }) }