#!/usr/bin/env node
const https = require('https');
const axios = require('axios');
const axiosInstance = axios.create({
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
timeout: 60000 // 60 second timeout
});
async function checkSaolaAccount() {
console.log('\n' + '═'.repeat(70));
console.log(' 🌟 SAOLA ACCOUNT DETAILED CHECK');
console.log('═'.repeat(70));
const baseUrl = 'https://api.umbrellacost.io/api/v1';
try {
// Step 1: Authenticate
console.log('\n1️⃣ AUTHENTICATION');
console.log('────────────────────────────');
console.log('Username: david+saola@umbrellacost.com');
console.log('Password: Dsamsung1!');
const authResponse = await axiosInstance.post(`${baseUrl}/users/signin`, {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
if (!authResponse.data || !authResponse.data.jwtToken) {
throw new Error('No JWT token received');
}
const token = authResponse.data.jwtToken;
console.log('✅ Authentication successful');
// Parse JWT
const tokenPayload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const userKey = tokenPayload.username || tokenPayload['custom:username'] || tokenPayload.sub;
console.log(`User Key: ${userKey}`);
// Step 2: Get user info and accounts
console.log('\n2️⃣ FETCHING USER ACCOUNTS');
console.log('────────────────────────────');
let accounts = [];
let accountKey = '9350'; // Default SAOLA account
try {
const userResponse = await axiosInstance.get(`${baseUrl}/users`, {
headers: {
'Authorization': token,
'Content-Type': 'application/json'
},
timeout: 10000
});
if (userResponse.data && userResponse.data.accounts) {
accounts = userResponse.data.accounts;
console.log(`✅ Found ${accounts.length} account(s)`);
// Show all accounts
accounts.forEach((acc, i) => {
console.log(` ${i+1}. ${acc.accountName || 'Unnamed'} (Key: ${acc.accountKey}, Type: ${acc.cloudType || 'N/A'})`);
});
// Find SAOLA account
const saolaAccount = accounts.find(acc =>
acc.accountKey === '9350' ||
acc.accountKey === 9350 ||
(acc.accountName && acc.accountName.toLowerCase().includes('saola'))
);
if (saolaAccount) {
accountKey = saolaAccount.accountKey;
console.log(`\n✅ Using SAOLA account: ${saolaAccount.accountName} (Key: ${accountKey})`);
} else {
console.log(`\n⚠️ SAOLA account not found, using default key: ${accountKey}`);
}
}
} catch (userErr) {
console.log('⚠️ Could not fetch user accounts (timeout/error), using default');
console.log(` Error: ${userErr.message}`);
}
// Step 3: Build API key and query costs
const apiKey = `${userKey}:${accountKey}:0`;
console.log(`\nAPI Key: ${apiKey}`);
console.log('\n3️⃣ QUERYING SAOLA COSTS (March-July 2025)');
console.log('────────────────────────────────────────────');
// Try different query approaches
const queries = [
{
name: 'With groupBy=usagedate',
params: {
startDate: '2025-03-01',
endDate: '2025-07-31',
periodGranLevel: 'month',
groupBy: 'usagedate',
costType: 'cost'
}
},
{
name: 'With groupBy=none',
params: {
startDate: '2025-03-01',
endDate: '2025-07-31',
periodGranLevel: 'month',
groupBy: 'none',
costType: 'cost'
}
}
];
for (const query of queries) {
console.log(`\n📊 ${query.name}:`);
try {
const params = new URLSearchParams(query.params);
const response = await axiosInstance.get(`${baseUrl}/invoices/caui?${params}`, {
headers: {
'Authorization': token,
'apikey': apiKey,
'Content-Type': 'application/json'
},
timeout: 30000
});
if (response.data && response.data.length > 0) {
console.log(`✅ Got ${response.data.length} result(s)`);
// Show data
if (query.params.groupBy === 'usagedate') {
// Monthly breakdown
const expected = {
'2025-03': 104755.07,
'2025-04': 111340.42,
'2025-05': 149774.24,
'2025-06': 165666.57,
'2025-07': 183920.58
};
console.log('\n Month Actual Expected Match');
console.log(' ─────────────────────────────────────────────────');
response.data.forEach(item => {
const month = item.usage_date;
const monthName = {
'2025-03': 'March 2025',
'2025-04': 'April 2025',
'2025-05': 'May 2025',
'2025-06': 'June 2025',
'2025-07': 'July 2025'
}[month];
if (monthName && expected[month]) {
const actual = item.total_cost;
const exp = expected[month];
const match = Math.abs(actual - exp) < 1;
console.log(` ${monthName.padEnd(12)} $${actual.toFixed(2).padEnd(13)} $${exp.toFixed(2).padEnd(12)} ${match ? '✅' : '❌'}`);
}
});
console.log(`\n Account ID: ${response.data[0].account_id}`);
console.log(` Expected: 932213950603`);
console.log(` Match: ${response.data[0].account_id === '932213950603' ? '✅' : '❌'}`);
} else {
// Total
const total = response.data[0].total_cost;
const expectedTotal = 715456.88;
console.log(` Total Cost: $${total.toFixed(2)}`);
console.log(` Expected: $${expectedTotal.toFixed(2)}`);
console.log(` Account ID: ${response.data[0].account_id}`);
}
} else {
console.log('❌ No data returned');
}
} catch (queryErr) {
console.log(`❌ Query failed: ${queryErr.message}`);
}
}
console.log('\n' + '═'.repeat(70));
console.log(' TEST COMPLETE');
console.log('═'.repeat(70));
} catch (error) {
console.error('\n❌ Fatal Error:', error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', error.response.data);
}
}
}
checkSaolaAccount().catch(console.error);