#!/usr/bin/env node
import dotenv from 'dotenv';
import { UmbrellaAuth } from './auth.js';
import { UmbrellaApiClient } from './api-client.js';
dotenv.config();
// Simple test processor for SAOLA account
class SaolaProcessor {
private auth: UmbrellaAuth;
private apiClient: UmbrellaApiClient;
private isAuthenticated = false;
constructor(baseURL: string) {
this.auth = new UmbrellaAuth(baseURL);
this.apiClient = new UmbrellaApiClient(baseURL);
}
async authenticate(): Promise<boolean> {
try {
await this.auth.authenticate({
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
});
this.apiClient.setAuthToken(this.auth.getAuthHeaders());
this.isAuthenticated = true;
return true;
} catch (error) {
console.error('Auth error:', error);
return false;
}
}
async testAllQuestions(): Promise<void> {
console.log('π§ͺ TESTING ALL QUESTIONS WITH SAOLA ACCOUNT');
console.log('Username: david+saola@umbrellacost.com');
console.log('Testing exact questions from questions.test');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββ\n');
const questions = [
'show me the list of customers',
'what is my total cost?',
'what is my total AWS cost?',
'what is my total GCP cost?',
'what is my total Azure cost?',
'show me the total cost per month',
'show me the total AWS cost per month',
'show me the total cost for ALL Azure accounts',
'show me all available accounts',
'what do you recommend to to for saving AWS costs?',
'what are the potential savings percategory?',
'Is there any anomalies on AWS?'
];
for (let i = 0; i < questions.length; i++) {
const question = questions[i];
console.log('β'.repeat(80));
console.log(`Q${i+1}: "${question}"`);
console.log('β'.repeat(80));
let response = '';
try {
// Question 1: MSP Customers
if (question.includes('list of customers')) {
console.log('π§ Testing MSP customers endpoint...');
const result = await this.apiClient.getCustomers();
response = `**MSP Customers Response:**\nSuccess: ${result.success}\n` +
`Data: ${JSON.stringify(result.data, null, 2)}\n` +
`Error: ${result.error || 'None'}\n` +
`Message: ${result.message || 'None'}`;
}
// Question 2-7: Cost questions
else if (question.includes('total cost')) {
console.log('π§ Testing cost endpoints...');
const today = new Date();
const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const startDate = startOfMonth.toISOString().split('T')[0];
const endDate = today.toISOString().split('T')[0];
// Get accounts first
const accountsResult = await this.apiClient.getAccounts();
if (accountsResult.success && accountsResult.data) {
console.log(`Found ${accountsResult.data.length} accounts`);
// Use the main AWS account
const awsAccount = accountsResult.data.find((acc: any) =>
acc.accountId === '932213950603' || acc.accountName?.includes('932213950603')
);
if (awsAccount) {
console.log(`Using account: ${awsAccount.accountName} (${awsAccount.accountId})`);
const costResult = await this.apiClient.getCosts({
accountId: awsAccount.accountId,
startDate,
endDate,
groupBy: 'none',
periodGranLevel: 'month'
});
let totalCost = 0;
if (costResult.success && Array.isArray(costResult.data)) {
totalCost = costResult.data.reduce((sum: number, item: any) => {
return sum + (parseFloat(item.total_cost || item.cost || 0));
}, 0);
}
response = `**Cost Analysis Response:**\n` +
`Question: ${question}\n` +
`Account: ${awsAccount.accountName} (${awsAccount.accountId})\n` +
`Period: ${startDate} to ${endDate}\n` +
`Total Cost: $${totalCost.toLocaleString('en-US', {minimumFractionDigits: 2})}\n` +
`Success: ${costResult.success}\n` +
`Raw Data: ${JSON.stringify(costResult.data, null, 2)}`;
} else {
response = `**No suitable account found**\nAvailable accounts: ${JSON.stringify(accountsResult.data, null, 2)}`;
}
} else {
response = `**Failed to get accounts**\nError: ${accountsResult.error}`;
}
}
// Question 8: Available accounts
else if (question.includes('available accounts')) {
console.log('π§ Testing accounts endpoint...');
const result = await this.apiClient.getAccounts();
response = `**Available Accounts Response:**\n` +
`Success: ${result.success}\n` +
`Count: ${Array.isArray(result.data) ? result.data.length : 0}\n` +
`Accounts: ${JSON.stringify(result.data, null, 2)}`;
}
// Question 9-10: Recommendations
else if (question.includes('recommend') || question.includes('savings')) {
console.log('π§ Testing recommendations endpoint...');
const result = await this.apiClient.getRecommendations();
response = `**Recommendations Response:**\n` +
`Success: ${result.success}\n` +
`Total Count: ${result.total_count || 0}\n` +
`Total Savings: $${(result.total_potential_savings || 0).toLocaleString()}\n` +
`Category Breakdown: ${JSON.stringify(result.category_breakdown, null, 2)}\n` +
`Sample Recommendations: ${JSON.stringify(result.data?.slice(0, 3), null, 2)}`;
}
// Question 11: Anomalies
else if (question.includes('anomalies')) {
console.log('π§ Testing anomalies endpoint...');
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date();
startDate.setDate(startDate.getDate() - 30);
const result = await this.apiClient.getAnomalyDetection({
startDate: startDate.toISOString().split('T')[0],
endDate: endDate
});
response = `**Anomaly Detection Response:**\n` +
`Success: ${result.success}\n` +
`Period: Last 30 days (${startDate.toISOString().split('T')[0]} to ${endDate})\n` +
`Data: ${JSON.stringify(result.data, null, 2)}\n` +
`Error: ${result.error || 'None'}`;
}
else {
response = `**Generic Response:**\nQuestion not specifically handled: "${question}"`;
}
} catch (error: any) {
response = `**ERROR:**\n${error.message}\n${error.stack}`;
}
console.log('π€ SAOLA ACCOUNT RESPONSE:');
console.log(response);
console.log('\n');
// Small delay between questions
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log('β
All questions tested with saola account!');
}
}
async function main() {
const baseURL = 'https://api.umbrellacost.io/api/v1';
const processor = new SaolaProcessor(baseURL);
console.log('π Authenticating with david+saola@umbrellacost.com...');
const authenticated = await processor.authenticate();
if (!authenticated) {
console.error('β Authentication failed');
return;
}
console.log('β
Authentication successful!\n');
await processor.testAllQuestions();
}
main().catch(console.error);