2const { Pool } = require('pg');
5 host: 'rmm-psa-db-do-user-28531160-0.i.db.ondigitalocean.com',
9 password: 'AVNS_J8RJAmsEwsHFG52_-F2',
10 ssl: { rejectUnauthorized: false }
16async function verifyContracts() {
17 const tenantId = '00000000-0000-0000-0000-000000000001';
19 console.log('╔══════════════════════════════════════════════════════════╗');
20 console.log('║ WHMCS Migration Verification Report ║');
21 console.log('╚══════════════════════════════════════════════════════════╝\n');
24 const stats = await pool.query(`
26 (SELECT COUNT(*) FROM customers WHERE tenant_id = $1) as customers,
27 (SELECT COUNT(*) FROM products WHERE tenant_id = $1) as products,
28 (SELECT COUNT(*) FROM invoices WHERE tenant_id = $1) as invoices,
29 (SELECT COUNT(*) FROM contracts WHERE tenant_id = $1) as contracts,
30 (SELECT COUNT(*) FROM contract_line_items cli
31 JOIN contracts c ON cli.contract_id = c.contract_id
32 WHERE c.tenant_id = $1) as line_items
35 console.log('MIGRATION SUMMARY');
36 console.log('=================');
37 console.log(`✓ Customers: ${stats.rows[0].customers}`);
38 console.log(`✓ Products: ${stats.rows[0].products}`);
39 console.log(`✓ Invoices: ${stats.rows[0].invoices}`);
40 console.log(`✓ Contracts: ${stats.rows[0].contracts}`);
41 console.log(`✓ Line Items: ${stats.rows[0].line_items}\n`);
44 const contracts = await pool.query(`
48 cust.name as customer_name,
52 c.auto_invoice_enabled,
54 cli.description as product_description
56 JOIN customers cust ON c.customer_id = cust.customer_id
57 LEFT JOIN contract_line_items cli ON c.contract_id = cli.contract_id
58 WHERE c.tenant_id = $1
59 ORDER BY c.contract_id
62 console.log('CONTRACT DETAILS');
63 console.log('================\n');
65 let totalMonthlyRevenue = 0;
67 for (const contract of contracts.rows) {
68 const price = parseFloat(contract.unit_price || 0);
70 // Convert to monthly equivalent
71 let monthlyEquiv = price;
72 if (contract.billing_interval === 'yearly') monthlyEquiv = price / 12;
73 else if (contract.billing_interval === 'quarterly') monthlyEquiv = price / 3;
74 else if (contract.billing_interval === 'semi_annually') monthlyEquiv = price / 6;
76 totalMonthlyRevenue += monthlyEquiv;
78 console.log(`Contract #${contract.contract_id}: ${contract.title}`);
79 console.log(` Customer: ${contract.customer_name}`);
80 console.log(` Status: ${contract.status}`);
81 console.log(` Billing: $${price.toFixed(2)}/${contract.billing_interval}`);
82 console.log(` Next Billing: ${contract.next_billing_date || 'Not set'}`);
83 console.log(` Auto Invoice: ${contract.auto_invoice_enabled ? 'Yes' : 'No'}`);
84 console.log(` Product: ${contract.product_description}`);
88 console.log('REVENUE ANALYSIS');
89 console.log('================');
90 console.log(`Total Monthly Recurring Revenue (MRR): $${totalMonthlyRevenue.toFixed(2)}`);
91 console.log(`Projected Annual Recurring Revenue: $${(totalMonthlyRevenue * 12).toFixed(2)}\n`);
94 const statusBreakdown = await pool.query(`
95 SELECT status, COUNT(*) as count
102 console.log('CONTRACT STATUS BREAKDOWN');
103 console.log('=========================');
104 for (const row of statusBreakdown.rows) {
105 console.log(` ${row.status.padEnd(15)} ${row.count} contracts`);
109 // Customers with most contracts
110 const topCustomers = await pool.query(`
113 COUNT(c.contract_id) as contract_count,
114 SUM(cli.unit_price) as total_value
116 JOIN contracts c ON cust.customer_id = c.customer_id
117 LEFT JOIN contract_line_items cli ON c.contract_id = cli.contract_id
118 WHERE cust.tenant_id = $1
119 GROUP BY cust.customer_id, cust.name
120 ORDER BY contract_count DESC, total_value DESC
124 console.log('TOP 10 CUSTOMERS BY CONTRACT COUNT');
125 console.log('===================================');
126 for (const customer of topCustomers.rows) {
127 console.log(` ${customer.name.padEnd(40)} ${customer.contract_count} contracts ($${parseFloat(customer.total_value || 0).toFixed(2)})`);
131 console.log('✓ Migration verification complete!\n');
136verifyContracts().catch(console.error);