decharge-scout 4.5.0 โ†’ 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Vercel API Endpoint - Fleet Data Submission
3
+ *
4
+ * POST /api/agentone/fleet-submit
5
+ * Receives fleet optimization data and stores it in Supabase
6
+ */
7
+
8
+ import { createClient } from '@supabase/supabase-js';
9
+
10
+ export const config = {
11
+ runtime: 'edge',
12
+ };
13
+
14
+ export default async function handler(req) {
15
+ // CORS headers
16
+ const headers = {
17
+ 'Access-Control-Allow-Origin': '*',
18
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
19
+ 'Access-Control-Allow-Headers': 'Content-Type',
20
+ 'Content-Type': 'application/json',
21
+ };
22
+
23
+ // Handle OPTIONS request for CORS
24
+ if (req.method === 'OPTIONS') {
25
+ return new Response(null, { status: 200, headers });
26
+ }
27
+
28
+ // Only allow POST
29
+ if (req.method !== 'POST') {
30
+ return new Response(
31
+ JSON.stringify({ error: 'Method not allowed' }),
32
+ { status: 405, headers }
33
+ );
34
+ }
35
+
36
+ try {
37
+ const data = await req.json();
38
+
39
+ // Validate required fields for fleet submissions
40
+ if (!data.type || data.type !== 'fleet') {
41
+ return new Response(
42
+ JSON.stringify({ error: 'Invalid submission type. Expected "fleet"' }),
43
+ { status: 400, headers }
44
+ );
45
+ }
46
+
47
+ if (!data.agent_name || !data.location || !data.timestamp || !data.fleet_size || !data.summary) {
48
+ return new Response(
49
+ JSON.stringify({ error: 'Missing required fields for fleet submission' }),
50
+ { status: 400, headers }
51
+ );
52
+ }
53
+
54
+ // Initialize Supabase client
55
+ const supabase = createClient(
56
+ process.env.SUPABASE_URL,
57
+ process.env.SUPABASE_ANON_KEY
58
+ );
59
+
60
+ // Insert fleet submission
61
+ const { error: fleetError } = await supabase
62
+ .from('fleet_submissions')
63
+ .insert({
64
+ agent_name: data.agent_name,
65
+ wallet: data.wallet,
66
+ location: data.location,
67
+ timestamp: new Date(data.timestamp).toISOString(),
68
+ fleet_size: data.fleet_size,
69
+ total_distance_km: data.summary.total_distance_km,
70
+ total_cost_usd: data.summary.total_cost_usd,
71
+ savings_percent: data.summary.savings_percent,
72
+ co2_saved_kg: data.summary.co2_saved_kg,
73
+ duration_hours: data.summary.duration_hours,
74
+ route_geojson: data.route,
75
+ stops: data.stops,
76
+ simulation_basis: data.simulation_basis || 'weather-based simulation',
77
+ });
78
+
79
+ if (fleetError) throw fleetError;
80
+
81
+ // Update agent heartbeat (upsert)
82
+ const { error: heartbeatError } = await supabase
83
+ .from('agent_heartbeat')
84
+ .upsert(
85
+ {
86
+ agent_name: data.agent_name,
87
+ location: data.location,
88
+ last_seen: new Date().toISOString(),
89
+ },
90
+ { onConflict: 'agent_name' }
91
+ );
92
+
93
+ if (heartbeatError) throw heartbeatError;
94
+
95
+ return new Response(
96
+ JSON.stringify({
97
+ success: true,
98
+ message: 'Fleet data submitted successfully',
99
+ }),
100
+ { status: 200, headers }
101
+ );
102
+ } catch (error) {
103
+ console.error('Fleet submission error:', error);
104
+ return new Response(
105
+ JSON.stringify({
106
+ error: 'Internal server error',
107
+ message: error.message,
108
+ }),
109
+ { status: 500, headers }
110
+ );
111
+ }
112
+ }
@@ -65,3 +65,39 @@ FROM agent_submissions
65
65
  WHERE created_at > NOW() - INTERVAL '24 hours'
66
66
  GROUP BY DATE_TRUNC('hour', created_at)
67
67
  ORDER BY hour DESC;
68
+
69
+ -- Table: fleet_submissions
70
+ -- Stores fleet optimization submissions
71
+ CREATE TABLE IF NOT EXISTS fleet_submissions (
72
+ id SERIAL PRIMARY KEY,
73
+ agent_name VARCHAR(255) NOT NULL,
74
+ wallet VARCHAR(255),
75
+ location VARCHAR(255) NOT NULL,
76
+ timestamp TIMESTAMP NOT NULL,
77
+ fleet_size INTEGER NOT NULL,
78
+ total_distance_km INTEGER NOT NULL,
79
+ total_cost_usd DECIMAL(10, 2) NOT NULL,
80
+ savings_percent INTEGER NOT NULL,
81
+ co2_saved_kg INTEGER NOT NULL,
82
+ duration_hours INTEGER NOT NULL,
83
+ route_geojson JSONB,
84
+ stops JSONB,
85
+ simulation_basis VARCHAR(255),
86
+ created_at TIMESTAMP DEFAULT NOW()
87
+ );
88
+
89
+ -- Indexes for fleet queries
90
+ CREATE INDEX idx_fleet_created_at ON fleet_submissions(created_at DESC);
91
+ CREATE INDEX idx_fleet_agent ON fleet_submissions(agent_name);
92
+ CREATE INDEX idx_fleet_location ON fleet_submissions(location);
93
+
94
+ -- View: Fleet stats (last 24h)
95
+ CREATE OR REPLACE VIEW fleet_stats_daily AS
96
+ SELECT
97
+ COUNT(*) as total_fleets,
98
+ SUM(fleet_size) as total_vehicles,
99
+ SUM(total_distance_km) as total_distance,
100
+ AVG(savings_percent) as avg_savings,
101
+ SUM(co2_saved_kg) as total_co2_saved
102
+ FROM fleet_submissions
103
+ WHERE created_at > NOW() - INTERVAL '24 hours';
@@ -10,6 +10,10 @@
10
10
  "src": "/api/stats",
11
11
  "dest": "/api/stats.js"
12
12
  },
13
+ {
14
+ "src": "/api/agentone/fleet-submit",
15
+ "dest": "/api/agentone/fleet-submit.js"
16
+ },
13
17
  {
14
18
  "src": "/(.*)",
15
19
  "dest": "/public/index.html"
package/index.js CHANGED
@@ -511,7 +511,7 @@ async function runQueryCycle(wallet, agentName, location, options) {
511
511
  // Submit to DeCharge Scout dashboard
512
512
  try {
513
513
  const dashboardSpinner = ora('Submitting to DeCharge Scout dashboard...').start();
514
- const apiUrl = 'https://decharge-scout.vercel.app/api/agentone/submit';
514
+ const apiUrl = 'https://decharge-scout.vercel.app/api/submit';
515
515
 
516
516
  console.log(chalk.blue(`\n๐ŸŒ Dashboard API URL: ${apiUrl}`));
517
517
  console.log(chalk.gray(`๐Ÿ“ค Submitting data...`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decharge-scout",
3
- "version": "4.5.0",
3
+ "version": "4.7.0",
4
4
  "description": "Global Energy Scout - Weather-powered intelligent energy price forecasting with Solana integration",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/oracle.js CHANGED
@@ -123,7 +123,26 @@ export async function submitToOracle(wallet, submissionData) {
123
123
  * Anonymize submission data
124
124
  */
125
125
  function anonymizeData(data) {
126
- // Create anonymized version
126
+ // Check if this is a fleet submission or regular submission
127
+ if (data.type === 'fleet') {
128
+ // Fleet submission - different structure
129
+ return {
130
+ agent_id: hashString(data.agent_name),
131
+ location_region: generalizeLocation(data.location),
132
+ timestamp: data.timestamp,
133
+ type: 'fleet',
134
+ fleet_size: data.fleet_size,
135
+ summary: {
136
+ ...data.summary,
137
+ // Round values to reduce precision
138
+ total_cost_usd: parseFloat(data.summary.total_cost_usd.toFixed(2)),
139
+ savings_percent: Math.round(data.summary.savings_percent)
140
+ },
141
+ stops_count: data.stops?.length || 0
142
+ };
143
+ }
144
+
145
+ // Regular scout submission
127
146
  const anonymized = {
128
147
  agent_id: hashString(data.agent_name), // Hash the agent name
129
148
  location_region: generalizeLocation(data.location), // Generalize location
@@ -136,11 +136,39 @@ const KNOWN_CITIES = {
136
136
  'dallas': { latitude: 32.776, longitude: -96.797, name: 'Dallas', country: 'United States', timezone: 'America/Chicago' },
137
137
  };
138
138
 
139
+ /**
140
+ * Get weather data for coordinates directly
141
+ * Used by fleet module for intermediate route points
142
+ */
143
+ export async function getWeatherForCoordinates(latitude, longitude) {
144
+ // Get weather forecast directly without geocoding
145
+ const forecast = await fetchWeatherForecast(latitude, longitude, 'auto');
146
+
147
+ return {
148
+ location: {
149
+ latitude,
150
+ longitude,
151
+ name: `${latitude.toFixed(2)},${longitude.toFixed(2)}`,
152
+ country: 'ROUTE',
153
+ timezone: 'auto'
154
+ },
155
+ forecast
156
+ };
157
+ }
158
+
139
159
  /**
140
160
  * Get weather data for a location
141
161
  * Throws error if geocoding fails - caller should handle user interaction
142
162
  */
143
163
  export async function getWeatherForLocation(location) {
164
+ // Check if location is already in coordinate format (lat,lon)
165
+ const coordMatch = location.match(/^(-?\d+\.?\d*),\s*(-?\d+\.?\d*)$/);
166
+ if (coordMatch) {
167
+ const lat = parseFloat(coordMatch[1]);
168
+ const lon = parseFloat(coordMatch[2]);
169
+ return getWeatherForCoordinates(lat, lon);
170
+ }
171
+
144
172
  // Try geocoding - throw error if fails
145
173
  const coords = await getCoordinatesFromLocation(location);
146
174
  console.log(`๐Ÿ“ Location: ${coords.name}, ${coords.country} (${coords.latitude}, ${coords.longitude})`);
package/test-api.js CHANGED
@@ -10,8 +10,8 @@
10
10
  import fetch from 'node-fetch';
11
11
  import chalk from 'chalk';
12
12
 
13
- const DASHBOARD_API_URL = 'https://decharge-scout.vercel.app/agentone/api/submit';
14
- const STATS_API_URL = 'https://decharge-scout.vercel.app/agentone/api/stats';
13
+ const DASHBOARD_API_URL = 'https://decharge-scout.vercel.app/api/submit';
14
+ const STATS_API_URL = 'https://decharge-scout.vercel.app/api/stats';
15
15
 
16
16
  // Sample test data
17
17
  const testData = {
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Comprehensive API Test Script
5
+ *
6
+ * Tests both regular submit and fleet-submit endpoints
7
+ */
8
+
9
+ import fetch from 'node-fetch';
10
+ import chalk from 'chalk';
11
+
12
+ const SUBMIT_API_URL = 'https://decharge-scout.vercel.app/api/submit';
13
+ const FLEET_SUBMIT_API_URL = 'https://decharge-scout.vercel.app/api/agentone/fleet-submit';
14
+ const STATS_API_URL = 'https://decharge-scout.vercel.app/api/stats';
15
+
16
+ // Sample regular submission data
17
+ const regularSubmissionData = {
18
+ agent_name: `TestAgent-${Math.random().toString(36).substring(7).toUpperCase()}`,
19
+ location: 'Test City, TX, US',
20
+ timestamp: Date.now(),
21
+ results: {
22
+ cheapest_window: '2AM-3AM',
23
+ price: 0.0299,
24
+ savings: 75.5,
25
+ data_points: 24
26
+ }
27
+ };
28
+
29
+ // Sample fleet submission data
30
+ const fleetSubmissionData = {
31
+ type: 'fleet',
32
+ agent_name: `FleetAgent-${Math.random().toString(36).substring(7).toUpperCase()}`,
33
+ wallet: 'TestWallet123',
34
+ location: 'New York โ†’ Boston',
35
+ timestamp: Date.now(),
36
+ fleet_size: 10,
37
+ route: {
38
+ type: 'LineString',
39
+ coordinates: [
40
+ [-74.0060, 40.7128], // New York
41
+ [-71.0589, 42.3601] // Boston
42
+ ]
43
+ },
44
+ stops: [
45
+ {
46
+ lat: 41.5,
47
+ lon: -72.5,
48
+ time: '3AM-4AM',
49
+ price: 0.025,
50
+ savings: 80,
51
+ location: 'Hartford, CT',
52
+ segmentId: 1
53
+ }
54
+ ],
55
+ summary: {
56
+ total_distance_km: 350,
57
+ total_cost_usd: 150.00,
58
+ savings_percent: 78,
59
+ co2_saved_kg: 45,
60
+ duration_hours: 4
61
+ },
62
+ simulation_basis: 'Test simulation'
63
+ };
64
+
65
+ console.log(chalk.cyan.bold('\n๐Ÿงช Comprehensive API Test Suite\n'));
66
+ console.log(chalk.gray('=' .repeat(60)));
67
+
68
+ /**
69
+ * Test 1: Regular Submit Endpoint
70
+ */
71
+ async function testRegularSubmit() {
72
+ console.log(chalk.blue('\n๐Ÿ“ TEST 1: Regular Submit Endpoint'));
73
+ console.log(chalk.gray(` URL: ${SUBMIT_API_URL}`));
74
+ console.log(chalk.gray(` Agent: ${regularSubmissionData.agent_name}`));
75
+
76
+ try {
77
+ const response = await fetch(SUBMIT_API_URL, {
78
+ method: 'POST',
79
+ headers: {
80
+ 'Content-Type': 'application/json',
81
+ },
82
+ body: JSON.stringify(regularSubmissionData)
83
+ });
84
+
85
+ const responseText = await response.text();
86
+
87
+ console.log(chalk.blue(`\n ๐Ÿ“ฅ Status: ${response.status}`));
88
+ console.log(chalk.blue(` ๐Ÿ“ฅ Response: ${responseText}`));
89
+
90
+ if (response.ok) {
91
+ console.log(chalk.green('\n โœ… Regular submit: PASS'));
92
+ return { success: true, agent: regularSubmissionData.agent_name };
93
+ } else {
94
+ console.log(chalk.red('\n โŒ Regular submit: FAIL'));
95
+ return { success: false, error: responseText };
96
+ }
97
+ } catch (error) {
98
+ console.log(chalk.red(`\n โŒ Error: ${error.message}`));
99
+ return { success: false, error: error.message };
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Test 2: Fleet Submit Endpoint
105
+ */
106
+ async function testFleetSubmit() {
107
+ console.log(chalk.blue('\n\n๐Ÿš› TEST 2: Fleet Submit Endpoint'));
108
+ console.log(chalk.gray(` URL: ${FLEET_SUBMIT_API_URL}`));
109
+ console.log(chalk.gray(` Agent: ${fleetSubmissionData.agent_name}`));
110
+ console.log(chalk.gray(` Fleet size: ${fleetSubmissionData.fleet_size} EVs`));
111
+
112
+ try {
113
+ const response = await fetch(FLEET_SUBMIT_API_URL, {
114
+ method: 'POST',
115
+ headers: {
116
+ 'Content-Type': 'application/json',
117
+ },
118
+ body: JSON.stringify(fleetSubmissionData)
119
+ });
120
+
121
+ const responseText = await response.text();
122
+
123
+ console.log(chalk.blue(`\n ๐Ÿ“ฅ Status: ${response.status}`));
124
+ console.log(chalk.blue(` ๐Ÿ“ฅ Response: ${responseText}`));
125
+
126
+ if (response.ok) {
127
+ console.log(chalk.green('\n โœ… Fleet submit: PASS'));
128
+ return { success: true, agent: fleetSubmissionData.agent_name };
129
+ } else {
130
+ console.log(chalk.red('\n โŒ Fleet submit: FAIL'));
131
+ return { success: false, error: responseText };
132
+ }
133
+ } catch (error) {
134
+ console.log(chalk.red(`\n โŒ Error: ${error.message}`));
135
+ return { success: false, error: error.message };
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Test 3: Stats Endpoint
141
+ */
142
+ async function testStats() {
143
+ console.log(chalk.blue('\n\n๐Ÿ“Š TEST 3: Stats Endpoint'));
144
+ console.log(chalk.gray(` URL: ${STATS_API_URL}`));
145
+
146
+ try {
147
+ const response = await fetch(STATS_API_URL);
148
+ const data = await response.json();
149
+
150
+ console.log(chalk.blue(`\n ๐Ÿ“ฅ Status: ${response.status}`));
151
+
152
+ if (response.ok) {
153
+ console.log(chalk.green('\n โœ… Stats endpoint: PASS'));
154
+ console.log(chalk.magenta(` ๐Ÿ“Š Active Agents: ${data.activeAgents}`));
155
+ console.log(chalk.magenta(` ๐Ÿ“Š Total Submissions: ${data.totalSubmissions}`));
156
+ console.log(chalk.magenta(` ๐Ÿ“Š Locations tracked: ${data.locations?.length || 0}`));
157
+ return { success: true, data };
158
+ } else {
159
+ console.log(chalk.red('\n โŒ Stats endpoint: FAIL'));
160
+ return { success: false, error: await response.text() };
161
+ }
162
+ } catch (error) {
163
+ console.log(chalk.red(`\n โŒ Error: ${error.message}`));
164
+ return { success: false, error: error.message };
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Main test runner
170
+ */
171
+ async function main() {
172
+ console.log(chalk.yellow('\n๐Ÿš€ Starting comprehensive API tests...\n'));
173
+
174
+ // Run all tests
175
+ const regularResult = await testRegularSubmit();
176
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
177
+
178
+ const fleetResult = await testFleetSubmit();
179
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
180
+
181
+ const statsResult = await testStats();
182
+
183
+ // Summary
184
+ console.log(chalk.gray('\n' + '=' .repeat(60)));
185
+ console.log(chalk.cyan.bold('\n๐Ÿ“‹ Test Summary:\n'));
186
+
187
+ console.log(regularResult.success
188
+ ? chalk.green(' โœ… Regular submit endpoint: PASS')
189
+ : chalk.red(' โŒ Regular submit endpoint: FAIL'));
190
+
191
+ console.log(fleetResult.success
192
+ ? chalk.green(' โœ… Fleet submit endpoint: PASS')
193
+ : chalk.red(' โŒ Fleet submit endpoint: FAIL'));
194
+
195
+ console.log(statsResult.success
196
+ ? chalk.green(' โœ… Stats endpoint: PASS')
197
+ : chalk.red(' โŒ Stats endpoint: FAIL'));
198
+
199
+ const allPassed = regularResult.success && fleetResult.success && statsResult.success;
200
+
201
+ if (allPassed) {
202
+ console.log(chalk.green.bold('\n๐ŸŽ‰ All tests passed! Both endpoints are working!\n'));
203
+ console.log(chalk.blue(' ๐ŸŒ View dashboard: https://decharge-scout.vercel.app/agentone\n'));
204
+ console.log(chalk.yellow(' ๐Ÿ“ Check Supabase for:'));
205
+ console.log(chalk.gray(` - Regular submission: ${regularResult.agent}`));
206
+ console.log(chalk.gray(` - Fleet submission: ${fleetResult.agent}\n`));
207
+ } else {
208
+ console.log(chalk.red.bold('\nโš ๏ธ Some tests failed. Check errors above.\n'));
209
+
210
+ if (!regularResult.success || !fleetResult.success) {
211
+ console.log(chalk.yellow(' Common issues:'));
212
+ console.log(chalk.gray(' 1. Supabase tables not created (run schema.sql)'));
213
+ console.log(chalk.gray(' 2. Missing Vercel environment variables'));
214
+ console.log(chalk.gray(' 3. Need to redeploy Vercel after changes'));
215
+ console.log(chalk.gray(' 4. Check Vercel logs: vercel logs\n'));
216
+ }
217
+ }
218
+
219
+ console.log(chalk.gray('=' .repeat(60) + '\n'));
220
+ }
221
+
222
+ main().catch(error => {
223
+ console.error(chalk.red('Fatal error:'), error);
224
+ process.exit(1);
225
+ });
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Simple Live API Test - Hit both endpoints
5
+ */
6
+
7
+ import https from 'https';
8
+
9
+ const SUBMIT_API = 'https://decharge-scout.vercel.app/api/submit';
10
+ const FLEET_API = 'https://decharge-scout.vercel.app/api/agentone/fleet-submit';
11
+
12
+ // Test data for regular submit
13
+ const regularData = {
14
+ agent_name: `TestAgent-${Date.now()}`,
15
+ location: 'Test City, TX, US',
16
+ timestamp: Date.now(),
17
+ results: {
18
+ cheapest_window: '2AM-3AM',
19
+ price: 0.0299,
20
+ savings: 75.5,
21
+ data_points: 24
22
+ }
23
+ };
24
+
25
+ // Test data for fleet submit
26
+ const fleetData = {
27
+ type: 'fleet',
28
+ agent_name: `FleetAgent-${Date.now()}`,
29
+ wallet: 'TestWallet123',
30
+ location: 'New York โ†’ Boston',
31
+ timestamp: Date.now(),
32
+ fleet_size: 10,
33
+ route: {
34
+ type: 'LineString',
35
+ coordinates: [[-74.0060, 40.7128], [-71.0589, 42.3601]]
36
+ },
37
+ stops: [{
38
+ lat: 41.5,
39
+ lon: -72.5,
40
+ time: '3AM-4AM',
41
+ price: 0.025,
42
+ savings: 80,
43
+ location: 'Hartford, CT',
44
+ segmentId: 1
45
+ }],
46
+ summary: {
47
+ total_distance_km: 350,
48
+ total_cost_usd: 150.00,
49
+ savings_percent: 78,
50
+ co2_saved_kg: 45,
51
+ duration_hours: 4
52
+ },
53
+ simulation_basis: 'Test simulation'
54
+ };
55
+
56
+ function hitAPI(url, data, name) {
57
+ return new Promise((resolve, reject) => {
58
+ const urlObj = new URL(url);
59
+ const postData = JSON.stringify(data);
60
+
61
+ const options = {
62
+ hostname: urlObj.hostname,
63
+ path: urlObj.pathname,
64
+ method: 'POST',
65
+ headers: {
66
+ 'Content-Type': 'application/json',
67
+ 'Content-Length': Buffer.byteLength(postData)
68
+ }
69
+ };
70
+
71
+ console.log(`\n๐Ÿ”ต Testing ${name}...`);
72
+ console.log(` URL: ${url}`);
73
+ console.log(` Data: ${JSON.stringify(data, null, 2).substring(0, 200)}...`);
74
+
75
+ const req = https.request(options, (res) => {
76
+ let body = '';
77
+ res.on('data', (chunk) => body += chunk);
78
+ res.on('end', () => {
79
+ console.log(`\n Status: ${res.statusCode}`);
80
+ console.log(` Response: ${body}`);
81
+
82
+ if (res.statusCode === 200 || res.statusCode === 201) {
83
+ console.log(` โœ… ${name} PASSED`);
84
+ resolve({ success: true, status: res.statusCode, body });
85
+ } else {
86
+ console.log(` โŒ ${name} FAILED`);
87
+ resolve({ success: false, status: res.statusCode, body });
88
+ }
89
+ });
90
+ });
91
+
92
+ req.on('error', (error) => {
93
+ console.log(` โŒ ${name} ERROR: ${error.message}`);
94
+ reject(error);
95
+ });
96
+
97
+ req.write(postData);
98
+ req.end();
99
+ });
100
+ }
101
+
102
+ async function main() {
103
+ console.log('๐Ÿงช Testing Both APIs\n');
104
+ console.log('='.repeat(60));
105
+
106
+ try {
107
+ // Test 1: Regular Submit
108
+ const regularResult = await hitAPI(SUBMIT_API, regularData, 'Regular Submit API');
109
+
110
+ // Wait 2 seconds
111
+ await new Promise(r => setTimeout(r, 2000));
112
+
113
+ // Test 2: Fleet Submit
114
+ const fleetResult = await hitAPI(FLEET_API, fleetData, 'Fleet Submit API');
115
+
116
+ // Summary
117
+ console.log('\n' + '='.repeat(60));
118
+ console.log('\n๐Ÿ“Š RESULTS:\n');
119
+ console.log(regularResult.success ? 'โœ… Regular Submit: WORKING' : 'โŒ Regular Submit: FAILED');
120
+ console.log(fleetResult.success ? 'โœ… Fleet Submit: WORKING' : 'โŒ Fleet Submit: FAILED');
121
+
122
+ if (regularResult.success && fleetResult.success) {
123
+ console.log('\n๐ŸŽ‰ Both APIs are working correctly!\n');
124
+ } else {
125
+ console.log('\nโš ๏ธ Some APIs failed - check errors above\n');
126
+ }
127
+
128
+ } catch (error) {
129
+ console.error('\nโŒ Fatal error:', error.message);
130
+ }
131
+ }
132
+
133
+ main();