File: //tmp/360live-bind-revenue-gate.cjs
const fs = require('fs');
function replace(s, a, b, label){ if(!s.includes(a)) throw new Error('missing '+label); return s.replace(a,b); }
let route = fs.readFileSync('services/web/app/growth-status.json/route.ts','utf8');
route = replace(route,
` const [growthSmoke, campaignKit, contentSeed, outreach, supplyActivation, growth, hostbillReconcile, hostbillApiProbe, hostbillWebhookReadiness, leadReport, leadNurture, leadDispatch, revenueIntent, checkoutHandoff, hostbillMultisite, fanPassFunnel, hostbillTestOrderPlan] = await Promise.all([`,
` const [growthSmoke, campaignKit, contentSeed, outreach, supplyActivation, growth, hostbillReconcile, hostbillApiProbe, hostbillWebhookReadiness, leadReport, leadNurture, leadDispatch, revenueIntent, checkoutHandoff, hostbillMultisite, fanPassFunnel, hostbillTestOrderPlan, revenueGate] = await Promise.all([`, 'tuple');
route = replace(route,
` readJson("/home/360live.stream/var/growth/latest-hostbill-test-order-plan.json"),
]);`,
` readJson("/home/360live.stream/var/growth/latest-hostbill-test-order-plan.json"),
readJson("/home/360live.stream/var/growth/latest-revenue-gate-report.json"),
]);`, 'source');
route = replace(route,
` hostbill_test_order_plan_available: Boolean(hostbillTestOrderPlan?.generated_at),
},`,
` hostbill_test_order_plan_available: Boolean(hostbillTestOrderPlan?.generated_at),
revenue_gate_available: Boolean(revenueGate?.generated_at),
},`, 'automation');
route = replace(route,
` hostbill_test_order_plan: {`,
` revenue_gate: {
generated_at: revenueGate?.generated_at || null,
ok: Boolean(revenueGate?.ok),
gates: revenueGate?.gates || null,
proof: revenueGate?.proof || null,
checkout: revenueGate?.checkout || null,
infrastructure: revenueGate?.infrastructure || null,
intent: revenueGate?.intent || null,
next_actions: Array.isArray(revenueGate?.next_actions) ? revenueGate.next_actions : [],
},
hostbill_test_order_plan: {`, 'revenue gate section');
route = replace(route,
` hostbillTestOrderPlan?.ok ? "A guarded HostBill free test-order dry-run exists for entitlement validation; it does not count as revenue proof." : "Run hostbill:test-order in dry-run mode before any admin/free entitlement test.",`,
` revenueGate?.gates?.ready_to_sell ? "Revenue gate says ready_to_sell=true; keep paid traffic constrained until paid_revenue_proven=true." : "Revenue gate is not ready_to_sell; fix checkout, HostBill or intent capture before scaling.",
hostbillTestOrderPlan?.ok ? "A guarded HostBill free test-order dry-run exists for entitlement validation; it does not count as revenue proof." : "Run hostbill:test-order in dry-run mode before any admin/free entitlement test.",`, 'next action');
fs.writeFileSync('services/web/app/growth-status.json/route.ts', route, 'utf8');
let smoke = fs.readFileSync('services/web/scripts/public-growth-smoke.mjs','utf8');
smoke = replace(smoke,
`'"hostbill_test_order_plan"', '"executed"',`,
`'"revenue_gate"', '"ready_to_sell"', '"activation_infrastructure_ready"', '"hostbill_test_order_plan"', '"executed"',`, 'smoke status');
smoke = replace(smoke,
`'"hostbill_test_order_plan"', '"monetization_proof"',`,
`'"revenue_gate"', '"hostbill_test_order_plan"', '"monetization_proof"',`, 'smoke schema');
fs.writeFileSync('services/web/scripts/public-growth-smoke.mjs', smoke, 'utf8');
const schemaPath='services/web/public/schemas/growth-status.v1.json';
const schema=JSON.parse(fs.readFileSync(schemaPath,'utf8'));
if(!schema.required.includes('revenue_gate')) schema.required.splice(schema.required.indexOf('hostbill_test_order_plan'),0,'revenue_gate');
schema.properties.revenue_gate={
type:'object',
required:['ok','gates','proof','infrastructure','intent','next_actions'],
properties:{
generated_at:{type:['string','null']},
ok:{type:'boolean'},
gates:{type:['object','null']},
proof:{type:['object','null']},
checkout:{type:['object','null']},
infrastructure:{type:['object','null']},
intent:{type:['object','null']},
next_actions:{type:'array'}
}
};
fs.writeFileSync(schemaPath, JSON.stringify(schema,null,2)+'\n','utf8');