// QA harness: boots the real server with the chain reads stubbed, so the join flow // can be driven end to end without spending POL or waiting on the indexer. // // TEST_ADDR=0x.. TEST_ID=9001 COLD=1 PORT=3399 DATA_DIR=... node qa/harness-server.js // // COLD=1 reproduces the state that broke #787: the cached index does NOT know the // brand-new position, so only a live contract read can resolve it. const path = require('path'); process.chdir(path.join(__dirname, '..')); const chain = require('../chain.js'); const ADDR = String(process.env.TEST_ADDR || '').toLowerCase(); const ID = Number(process.env.TEST_ID || 9001); const COLD = process.env.COLD !== '0'; let seeded = !COLD; // warm index = already knows the member chain.startIndexer = function () { /* no RPC polling in the harness */ }; chain.memberIdByAccount = function (a) { return (seeded && String(a || '').toLowerCase() === ADDR) ? ID : null; }; chain.verifyMember = async function (id) { if (Number(id) !== ID) return { registered: false }; seeded = true; // a live read seeds the index, as the real one does return { registered: true, id: ID, account: ADDR, referrerId: 21, uplineId: 21, tier: 2, level: 1, directCount: 0, joinedAt: Math.floor(Date.now() / 1000), tierName: 'Premium', levelName: 'Scintilla' }; }; chain.memberPublic = async function (id) { return Number(id) === ID ? { registered: true, id: ID, level: 1, tier: 2, directCount: 0 } : { registered: false, id }; }; chain.memberLookup = async function (id) { return chain.memberPublic(id); }; chain.isInTeam = function () { return true; }; chain.getPayoutsPublic = function () { return []; }; chain.getIncome = async function () { return []; }; chain.getMatrixTree = async function () { return null; }; chain.getCoachingScan = async function () { return { rows: [] }; }; chain.liveDirects = async function () { return []; }; chain.balanceOf = async function () { return '0'; }; chain.getOwnerUpgradeNeeds = async function () { return null; }; chain.getOrgRouting = async function () { return null; }; chain.getOrgShare = async function () { return null; }; chain.nextOpenPosition = function () { return 21; }; console.log('harness: addr=' + ADDR + ' id=' + ID + ' coldIndex=' + COLD); require('../server.js');