6de2455917
- Added GLOBAL_MARKETS_TITLE to all translation files - Updated footer with 12 markets (4 active + 8 upcoming) - Translated market section to: zh-cn, zh-tw, ja, ko, th, vi, id, ms, hi - Built and deployed to production - CloudFront invalidation: I3RTMXVFDJXWLG3SYX208OP1CC
204 lines
5.2 KiB
JavaScript
204 lines
5.2 KiB
JavaScript
/**
|
|
* VIMS Demo Script
|
|
* Demonstrates complete VIMS flow with test data
|
|
*/
|
|
|
|
const axios = require('axios');
|
|
const fs = require('fs').promises;
|
|
const path = require('path');
|
|
|
|
const API_URL = process.env.VIMS_API_URL || 'http://localhost:3450';
|
|
|
|
class VIMSDemo {
|
|
constructor() {
|
|
this.results = [];
|
|
}
|
|
|
|
log(step, data) {
|
|
console.log(`\n${'='.repeat(60)}`);
|
|
console.log(`STEP: ${step}`);
|
|
console.log('='.repeat(60));
|
|
console.log(JSON.stringify(data, null, 2));
|
|
this.results.push({ step, data });
|
|
}
|
|
|
|
async run() {
|
|
console.log('\n🚀 VIMS Demo Starting...\n');
|
|
|
|
try {
|
|
// Step 1: Health Check
|
|
await this.healthCheck();
|
|
|
|
// Step 2: Create Object
|
|
const object = await this.createObject();
|
|
|
|
// Step 3: Set Baseline
|
|
await this.setBaseline(object.id);
|
|
|
|
// Step 4: Upload Observation
|
|
const observation = await this.uploadObservation(object.id);
|
|
|
|
// Step 5: Process Observation
|
|
await this.processObservation(observation.id);
|
|
|
|
// Step 6: Get Results
|
|
await this.getResults(object.id, observation.id);
|
|
|
|
// Step 7: Dashboard
|
|
await this.getDashboard();
|
|
|
|
console.log('\n✅ Demo completed successfully!\n');
|
|
|
|
// Save results
|
|
await fs.writeFile(
|
|
'demo/results.json',
|
|
JSON.stringify(this.results, null, 2)
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ Demo failed:', error.message);
|
|
if (error.response) {
|
|
console.error('Response:', error.response.data);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
async healthCheck() {
|
|
const res = await axios.get(`${API_URL}/health`);
|
|
this.log('Health Check', res.data);
|
|
return res.data;
|
|
}
|
|
|
|
async createObject() {
|
|
const objectData = {
|
|
objectTypeId: 'atm-type-uuid',
|
|
customerId: 'demo-customer',
|
|
name: 'Demo ATM - Stureplan',
|
|
externalId: 'ATM-DEMO-001',
|
|
location: {
|
|
latitude: 59.3368,
|
|
longitude: 18.0555
|
|
},
|
|
address: 'Stureplan 4, Stockholm',
|
|
manufacturer: 'NCR',
|
|
model: 'SelfServ 22'
|
|
};
|
|
|
|
const res = await axios.post(`${API_URL}/api/v1/objects`, objectData);
|
|
this.log('Create Object', res.data);
|
|
return res.data;
|
|
}
|
|
|
|
async setBaseline(objectId) {
|
|
const baselineData = {
|
|
images: [
|
|
{
|
|
angle: 'front',
|
|
imageUrl: 'https://demo.landvex.com/baseline/atm-front.jpg'
|
|
},
|
|
{
|
|
angle: 'back',
|
|
imageUrl: 'https://demo.landvex.com/baseline/atm-back.jpg'
|
|
},
|
|
{
|
|
angle: 'left',
|
|
imageUrl: 'https://demo.landvex.com/baseline/atm-left.jpg'
|
|
},
|
|
{
|
|
angle: 'right',
|
|
imageUrl: 'https://demo.landvex.com/baseline/atm-right.jpg'
|
|
}
|
|
]
|
|
};
|
|
|
|
const res = await axios.post(
|
|
`${API_URL}/api/v1/objects/${objectId}/baseline`,
|
|
baselineData
|
|
);
|
|
this.log('Set Baseline', res.data);
|
|
return res.data;
|
|
}
|
|
|
|
async uploadObservation(objectId) {
|
|
// Create a test image
|
|
const sharp = require('sharp');
|
|
const imageBuffer = await sharp({
|
|
create: {
|
|
width: 640,
|
|
height: 480,
|
|
channels: 3,
|
|
background: { r: 200, g: 200, b: 200 }
|
|
}
|
|
})
|
|
.composite([{
|
|
input: Buffer.from([255, 0, 0]),
|
|
raw: { width: 1, height: 1, channels: 3 },
|
|
tile: true,
|
|
blend: 'over'
|
|
}])
|
|
.jpeg()
|
|
.toBuffer();
|
|
|
|
const FormData = require('form-data');
|
|
const form = new FormData();
|
|
form.append('images', imageBuffer, { filename: 'observation.jpg' });
|
|
form.append('objectId', objectId);
|
|
form.append('angle', 'front');
|
|
form.append('zoomerId', 'demo-zoomer');
|
|
|
|
const res = await axios.post(
|
|
`${API_URL}/api/v1/observations`,
|
|
form,
|
|
{ headers: form.getHeaders() }
|
|
);
|
|
this.log('Upload Observation', res.data);
|
|
return res.data.observations[0];
|
|
}
|
|
|
|
async processObservation(observationId) {
|
|
const res = await axios.post(
|
|
`${API_URL}/api/v1/observations/${observationId}/process`
|
|
);
|
|
this.log('Process Observation', res.data);
|
|
return res.data;
|
|
}
|
|
|
|
async getResults(objectId, observationId) {
|
|
// Get object
|
|
const objectRes = await axios.get(`${API_URL}/api/v1/objects/${objectId}`);
|
|
this.log('Get Object', objectRes.data);
|
|
|
|
// Get observation
|
|
const obsRes = await axios.get(`${API_URL}/api/v1/observations/${observationId}`);
|
|
this.log('Get Observation', obsRes.data);
|
|
|
|
// Get detections
|
|
const detRes = await axios.get(`${API_URL}/api/v1/detections?observationId=${observationId}`);
|
|
this.log('Get Detections', detRes.data);
|
|
|
|
// Get alerts
|
|
const alertRes = await axios.get(`${API_URL}/api/v1/alerts?objectId=${objectId}`);
|
|
this.log('Get Alerts', alertRes.data);
|
|
}
|
|
|
|
async getDashboard() {
|
|
const overview = await axios.get(`${API_URL}/api/v1/dashboard/overview`);
|
|
this.log('Dashboard Overview', overview.data);
|
|
|
|
const timeline = await axios.get(`${API_URL}/api/v1/dashboard/timeline?days=7`);
|
|
this.log('Dashboard Timeline', timeline.data);
|
|
|
|
const topAlerts = await axios.get(`${API_URL}/api/v1/dashboard/top-alerts`);
|
|
this.log('Top Alerts', topAlerts.data);
|
|
}
|
|
}
|
|
|
|
// Run demo if called directly
|
|
if (require.main === module) {
|
|
const demo = new VIMSDemo();
|
|
demo.run();
|
|
}
|
|
|
|
module.exports = { VIMSDemo };
|