#!/usr/bin/env bun import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs' import { dirname, join } from 'path' const root = process.cwd() const outRoot = join(root, 'content_population_exports') const stagingRoot = join(root, 'data', 'staging') const importLogRoot = join(stagingRoot, 'import-logs') const pdpCheckRoot = join(stagingRoot, 'pdp-checks') const cutoverPath = join(stagingRoot, 'cutover-approval.json') mkdirSync(outRoot, { recursive: true }) mkdirSync(importLogRoot, { recursive: true }) mkdirSync(pdpCheckRoot, { recursive: true }) function readJson(path: string, fallback: any = null) { if (!existsSync(path)) return fallback return JSON.parse(readFileSync(path, 'utf8').replace(/^\uFEFF/, '')) } function writeJson(path: string, data: any) { mkdirSync(dirname(path), { recursive: true }) writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf8') } function csv(rows: any[], headers: string[]) { const esc = (value: any) => { if (value === undefined || value === null) value = '' if (Array.isArray(value)) value = value.join(' | ') value = String(value) return /[",\n\r]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value } return [headers.join(','), ...rows.map(row => headers.map(header => esc(row[header])).join(','))].join('\n') + '\n' } const generatedAt = new Date().toISOString() const cutoverTemplate = readJson(join(stagingRoot, '_templates', 'cutover-approval-template.json'), { approved: false, approvedBy: '', approvedAt: '', stagingImportEvidence: 'data/staging/import-logs/', pdpSpotCheckEvidence: 'data/staging/pdp-checks/', knownRisksAccepted: [], notes: '' }) let cutoverCreated = false if (!existsSync(cutoverPath)) { writeJson(cutoverPath, { ...cutoverTemplate, approved: false, approvedBy: '', approvedAt: '', knownRisksAccepted: [], notes: 'Pending. This file is an editable cutover approval tracker, not approval evidence until approved=true with approver/date after staging checks pass.' }) cutoverCreated = true } const importReadmePath = join(importLogRoot, 'README.md') const pdpReadmePath = join(pdpCheckRoot, 'README.md') if (!existsSync(importReadmePath)) { writeFileSync(importReadmePath, [ '# Staging import logs', '', 'Save real Matrixify staging import log JSON files here after Lewis/Euan run imports.', '', 'Required files/evidence are not generated by this dashboard. Use `data/staging/_templates/import-log-template.json` as the schema, then run `bun run staging:evidence`.', '', 'Do not place placeholder JSON files here; any JSON in this folder is treated as submitted evidence by the validator.', '' ].join('\n'), 'utf8') } if (!existsSync(pdpReadmePath)) { writeFileSync(pdpReadmePath, [ '# Staging PDP spot checks', '', 'Save real staging PDP spot-check JSON files here after checking live staging URLs.', '', 'At least 5 passing checks are required. Use `data/staging/_templates/pdp-spot-check-template.json` as the schema, then run `bun run staging:evidence`.', '', 'Do not place placeholder JSON files here; any JSON in this folder is treated as submitted evidence by the validator.', '' ].join('\n'), 'utf8') } const rows = [ { Item: 'cutover_approval_tracker', Path: 'data/staging/cutover-approval.json', Status: cutoverCreated ? 'created_pending_tracker' : 'already_present', EvidenceValue: 'Not approval until approved=true with approver and approvedAt after staging evidence passes.', NextAction: 'Lewis/Euan/project owner fills after import logs and PDP checks pass.' }, { Item: 'import_log_folder_instructions', Path: 'data/staging/import-logs/README.md', Status: 'present', EvidenceValue: 'Instructions only; no import evidence generated.', NextAction: 'Save real Matrixify import log JSON files after staging imports.' }, { Item: 'pdp_check_folder_instructions', Path: 'data/staging/pdp-checks/README.md', Status: 'present', EvidenceValue: 'Instructions only; no PDP evidence generated.', NextAction: 'Save at least 5 real PDP spot-check JSON files after staging URL checks.' } ] const manifest = { generatedAt, ready: false, purpose: 'Initializes editable staging evidence intake locations without fabricating import logs, PDP checks, or cutover approval.', cutoverCreated, counts: { intakeItems: rows.length, fakeEvidenceCreated: 0 }, rows, files: { markdown: 'content_population_exports/staging_evidence_intake.md', json: 'content_population_exports/staging_evidence_intake.json', csv: 'content_population_exports/staging_evidence_intake.csv', cutoverApproval: 'data/staging/cutover-approval.json', importLogReadme: 'data/staging/import-logs/README.md', pdpCheckReadme: 'data/staging/pdp-checks/README.md' } } writeJson(join(outRoot, 'staging_evidence_intake.json'), manifest) writeFileSync(join(outRoot, 'staging_evidence_intake.csv'), csv(rows, ['Item', 'Path', 'Status', 'EvidenceValue', 'NextAction']), 'utf8') writeFileSync(join(outRoot, 'staging_evidence_intake.md'), [ '# Staging evidence intake', '', `Generated: ${generatedAt}`, '', 'Ready: **NO**', '', 'This initializes the editable staging evidence intake paths. It deliberately does not create fake Matrixify logs, fake PDP checks, or a signed cutover approval.', '', `Fake evidence created: ${manifest.counts.fakeEvidenceCreated}`, '', '## Intake rows', '| Item | Path | Status | Next action |', '|---|---|---|---|', ...rows.map(row => `| ${row.Item} | ${row.Path} | ${row.Status} | ${row.NextAction} |`), '', '## Guardrail', 'Only JSON files created from real staging activity should be placed in `data/staging/import-logs/` and `data/staging/pdp-checks/`. The cutover tracker remains blocked until real approval is recorded.', '' ].join('\n'), 'utf8') console.log(`Staging evidence intake initialized; cutoverCreated=${cutoverCreated}`) console.log('Fake evidence created: 0')