// Read-only production drift probe. No authentication, writes, payments or // provider calls are performed. It intentionally fails when a required // deployment contract is missing. import { mkdir, writeFile } from 'node:fs/promises'; const base = String(process.argv[2] || process.env.IHALEIST_LIVE_URL || 'https://ihaleist.com').replace(/\/$/, ''); const timeoutMs = 15_000; const requiredHeaders = ['x-content-type-options', 'referrer-policy', 'permissions-policy']; const checks = {}; async function probe(path, successField = null) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(base + path, { signal: controller.signal, redirect: 'manual' }); const result = { status: response.status, contentType: response.headers.get('content-type'), headers: Object.fromEntries(requiredHeaders.map(name => [name, response.headers.get(name)])), }; if (successField) { const raw = await response.text(); try { result.json = JSON.parse(raw); } catch { result.jsonError = 'JSON yanıtı ayrıştırılamadı.'; } result.apiSuccess = result.json?.[successField] === true; } return result; } catch (error) { return { error: error.name === 'AbortError' ? `timeout after ${timeoutMs}ms` : error.message }; } finally { clearTimeout(timer); } } checks.home = await probe('/'); checks.health = await probe('/api/health', 'ok'); checks.ready = await probe('/api/ready', 'success'); const missingHeaders = requiredHeaders.filter(name => [checks.home, checks.health, checks.ready].some(check => check?.headers?.[name] == null)); const report = { base, readOnly: true, checkedAt: new Date().toISOString(), checks, pass: checks.home?.status === 200 && checks.health?.status === 200 && checks.health.apiSuccess === true && checks.ready?.status === 200 && checks.ready.apiSuccess === true && missingHeaders.length === 0, missingHeaders, }; await mkdir('docs/quality/evidence', { recursive: true }); await writeFile('docs/quality/evidence/qa-live-runtime.json', JSON.stringify(report, null, 2) + '\n'); console.log(JSON.stringify(report)); if (!report.pass) process.exitCode = 1;