51 lines
2.4 KiB
TypeScript
51 lines
2.4 KiB
TypeScript
/**
|
|||
|
|
* Exercises the REAL admin-queries against the live DB to prove the admin
|
||
|
|
* dashboard data layer works end-to-end. Run after seed-users + seed-admin.
|
||
|
|
* Run: npx tsx scripts/verify-admin.ts
|
||
|
|
*/
|
||
|
|
import { config } from "dotenv"
|
||
|
|
config({ path: ".env.local" })
|
||
|
|
process.env.DATABASE_SSL = process.env.DATABASE_SSL ?? "disable"
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const q = await import("../lib/db/admin-queries")
|
||
|
|
const { pool } = await import("../lib/db")
|
||
|
|
|
||
|
|
const overview = await q.getAdminOverviewStats()
|
||
|
|
const dist = await q.getPlanDistribution()
|
||
|
|
const users = await q.getUsersPage({ page: 1, pageSize: 5 })
|
||
|
|
const ai = await q.getAiUsageAggregates()
|
||
|
|
const sys = await q.getSystemCounts()
|
||
|
|
|
||
|
|
console.log("── Overview ─────────────────────────────")
|
||
|
|
console.log(` total users: ${overview.totalUsers}`)
|
||
|
|
console.log(` paid / free: ${overview.paidUsers} / ${overview.freeUsers}`)
|
||
|
|
console.log(` MRR / ARR: $${overview.mrr} / $${overview.arr}`)
|
||
|
|
console.log(` lifetime revenue: $${overview.lifetimeRevenue}`)
|
||
|
|
console.log(` properties/tenants: ${overview.totalProperties} / ${overview.totalTenants}`)
|
||
|
|
console.log(` AI calls this month:${overview.aiCallsThisMonth}`)
|
||
|
|
console.log(` active (30d): ${overview.activeUsers30d}`)
|
||
|
|
console.log(` plan distribution: ${JSON.stringify(dist)}`)
|
||
|
|
console.log("── Users page (first 5) ─────────────────")
|
||
|
|
console.log(` total matched: ${users.total} (pageCount ${users.pageCount})`)
|
||
|
|
for (const u of users.rows) {
|
||
|
|
console.log(` ${u.email} [${u.plan}] props=${u.propertyCount} tenants=${u.tenantCount} role=${u.role ?? "user"} banned=${u.banned ?? false}`)
|
||
|
|
}
|
||
|
|
console.log("── AI usage ─────────────────────────────")
|
||
|
|
console.log(` this month total: ${ai.totalThisMonth}`)
|
||
|
|
console.log(` by type: ${JSON.stringify(ai.byType)}`)
|
||
|
|
console.log("── System counts ────────────────────────")
|
||
|
|
console.log(` ${JSON.stringify(sys.counts)}`)
|
||
|
|
|
||
|
|
// sanity assertions
|
||
|
|
const ok = overview.totalUsers >= 11 && users.total >= 11
|
||
|
|
console.log(`\n${ok ? "✓ PASS" : "✗ CHECK"} — expected >= 11 users (10 landlords + admin)`)
|
||
|
|
|
||
|
|
await pool.end()
|
||
|
|
}
|
||
|
|
|
||
|
|
main().catch((e) => {
|
||
|
|
console.error("verify-admin failed:", e)
|
||
|
|
process.exit(1)
|
||
|
|
})
|