/** * Read-only preflight: can we reach every configured cluster, what's in it, and * which one will take the next write? Run this before pointing prod anywhere. * * node scripts/check-shards.mjs */ import { MongoClient } from 'mongodb' import { readFileSync } from 'node:fs' // Load .env without a dependency - values may contain '=' so split on the first only. for (const line of readFileSync(new URL('../.env', import.meta.url), 'utf8').split('\n')) { const t = line.trim() if (!t || t.startsWith('#')) continue const i = t.indexOf('=') if (i > 0) process.env[t.slice(0, i).trim()] ??= t.slice(i + 1).trim() } const DB_NAME = process.env.MONGO_DB_NAME ?? 'costingDB' const QUOTA = 512 * 1024 * 1024 const ROLLOVER = 0.9 const urisFor = (prefix) => Object.keys(process.env) .filter((k) => new RegExp(`^${prefix}\\d+$`).test(k)) .sort((a, b) => Number(a.slice(prefix.length)) - Number(b.slice(prefix.length))) .map((k) => [k, process.env[k].trim()]) const host = (uri) => uri.match(/@([^/?]+)/)?.[1] ?? '?' for (const [group, prefix, collection] of [ ['COSTING', 'CostingDBURL', 'llm_events'], ['LAMBDA', 'LambdaDBURL', 'lambda_events'], ]) { const uris = urisFor(prefix) console.log(`\n=== ${group} — ${uris.length} shard(s), db "${DB_NAME}" ===`) if (!uris.length) { console.log(' none configured') continue } let writeTarget = null for (const [name, uri] of uris) { const client = new MongoClient(uri, { serverSelectionTimeoutMS: 15000, maxPoolSize: 2 }) try { await client.connect() const db = client.db(DB_NAME) const stats = await db.command({ dbStats: 1, scale: 1 }) const used = (stats.dataSize ?? 0) + (stats.indexSize ?? 0) const pct = ((used / QUOTA) * 100).toFixed(1) const cols = (await db.listCollections().toArray()).map((c) => c.name) const docs = cols.includes(collection) ? await db.collection(collection).estimatedDocumentCount() : 0 const open = used < QUOTA * ROLLOVER if (open && writeTarget === null) writeTarget = name console.log( ` ${name.padEnd(15)} ${host(uri).padEnd(38)} ${(used / 1e6).toFixed(1).padStart(7)} MB (${pct.padStart(5)}%) ` + `${collection}=${docs} collections=[${cols.join(', ') || '-'}] ${open ? 'OPEN' : 'FULL'}` ) } catch (err) { console.log(` ${name.padEnd(15)} ${host(uri).padEnd(38)} UNREACHABLE: ${String(err).split('\n')[0].slice(0, 90)}`) } finally { await client.close() } } console.log(` -> next write goes to: ${writeTarget ?? 'NONE (all full)'}`) }