/** * List SuperAdmin tenants (filter optional). * * SMS_LIST_Q=aygin npx ts-node --transpile-only prisma/list-tenants.ts */ import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); function env(name: string, fallback = '') { return String(process.env[name] ?? fallback).trim(); } async function main() { const q = env('SMS_LIST_Q').toLowerCase(); const rows = await prisma.tenant.findMany({ orderBy: [{ product: 'asc' }, { nameFa: 'asc' }], include: { smsAccount: true }, }); const filtered = q ? rows.filter((t) => { const blob = `${t.id} ${t.nameFa} ${t.nameEn || ''} ${t.domain} ${t.slug} ${t.nodeServer} ${t.appUrl || ''} ${JSON.stringify(t.domains)}`.toLowerCase(); return blob.includes(q) || blob.includes('آیگ') || blob.includes('ایگ') || blob.includes('montzar'); }) : rows; for (const t of filtered) { console.log( JSON.stringify( { id: t.id, nameFa: t.nameFa, product: t.product, domain: t.domain, domains: t.domains, appUrl: t.appUrl, nodeServer: t.nodeServer, smsSyncedAt: t.smsSyncedAt, balanceRials: t.smsAccount?.balanceRials ?? null, pricePerPartRials: t.smsAccount?.pricePerPartRials ?? null, isBlocked: t.smsAccount?.isBlocked ?? null, autoBlockBelowRials: t.smsAccount?.autoBlockBelowRials ?? null, }, null, 2, ), ); } console.log(`count=${filtered.length}`); } main() .catch((e) => { console.error(e); process.exitCode = 1; }) .finally(async () => { await prisma.$disconnect(); });