gigafibre-fsm/services/targo-hub/lib/traccar.js
louispaulb 320655b0a0 refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables
- Remove apps/dispatch/ (100% replaced by ops dispatch module, unmaintained)
- Commit services/targo-hub/lib/ (24 modules, 6290 lines — was never tracked)
- Commit services/docuseal + services/legacy-db docker-compose configs
- Extract client app composables: useOTP, useAddressSearch, catalog data, format utils
- Refactor CartPage.vue 630→175 lines, CatalogPage.vue 375→95 lines
- Clean hardcoded credentials from config.js fallback values
- Add client portal: catalog, cart, checkout, OTP verification, address search
- Add ops: NetworkPage, AgentFlowsPage, ConversationPanel, UnifiedCreateModal
- Add ops composables: useBestTech, useConversations, usePermissions, useScanner
- Add field app: scanner composable, docker/nginx configs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 17:38:38 -04:00

68 lines
2.1 KiB
JavaScript

'use strict'
const cfg = require('./config')
const { log, json, parseBody } = require('./helpers')
const authHeader = 'Basic ' + Buffer.from(cfg.TRACCAR_USER + ':' + cfg.TRACCAR_PASS).toString('base64')
async function traccarFetch (path) {
const res = await fetch(cfg.TRACCAR_URL + path, {
headers: { Authorization: authHeader, Accept: 'application/json' },
})
if (!res.ok) throw new Error(`Traccar ${res.status}: ${path}`)
return res.json()
}
// Cache devices for 60s (they rarely change)
let _devCache = null, _devCacheTs = 0
async function getDevices () {
if (_devCache && Date.now() - _devCacheTs < 60000) return _devCache
_devCache = await traccarFetch('/api/devices?all=true')
_devCacheTs = Date.now()
return _devCache
}
async function getPositions (deviceIds) {
if (!deviceIds?.length) return []
const results = await Promise.allSettled(
deviceIds.map(id => traccarFetch('/api/positions?deviceId=' + id))
)
return results.flatMap(r => r.status === 'fulfilled' ? r.value : [])
}
async function handle (req, res, method, path) {
const sub = path.replace('/traccar', '').replace(/^\//, '')
if (sub === 'devices' && method === 'GET') {
try {
return json(res, 200, await getDevices())
} catch (e) {
log('Traccar devices error:', e.message)
return json(res, 502, { error: 'Traccar unavailable' })
}
}
if (sub === 'positions' && method === 'GET') {
try {
const url = new URL(req.url, 'http://localhost')
const ids = (url.searchParams.get('deviceIds') || '').split(',').map(Number).filter(Boolean)
return json(res, 200, await getPositions(ids))
} catch (e) {
log('Traccar positions error:', e.message)
return json(res, 502, { error: 'Traccar unavailable' })
}
}
// Proxy any other Traccar API path (fallback)
if (method === 'GET') {
try {
return json(res, 200, await traccarFetch('/api/' + sub))
} catch (e) {
return json(res, 502, { error: e.message })
}
}
json(res, 404, { error: 'Traccar endpoint not found' })
}
module.exports = { handle, getDevices, getPositions }