galleria_photo_face_rknn_op.../api_v1/scanner/geocodeQueue.js
2026-10-03 12:16:58 +02:00

108 lines
1.9 KiB
JavaScript

const crypto = require('crypto');
const db = require('../../db/knex');
function normalizeCoordinate(value) {
if (value == null || value === '') {
return null;
}
const coordinate = Number(value);
if (!Number.isFinite(coordinate)) {
return null;
}
return coordinate;
}
async function enqueueGeocodeJob({
entityType,
entityId,
lat,
lon,
}) {
if (
entityType !== 'photo'
&& entityType !== 'activity'
) {
throw new Error(
`Tipo entità geocode non valido: ${entityType}`
);
}
if (!entityId) {
throw new Error(
'entityId geocode mancante'
);
}
const normalizedLat = normalizeCoordinate(lat);
const normalizedLon = normalizeCoordinate(lon);
if (
normalizedLat == null
|| normalizedLon == null
) {
return {
queued: false,
reason: 'coordinates_missing',
};
}
if (
normalizedLat < -90
|| normalizedLat > 90
|| normalizedLon < -180
|| normalizedLon > 180
) {
return {
queued: false,
reason: 'coordinates_invalid',
};
}
const now = db.fn.now();
await db('geocode_jobs')
.insert({
id: crypto.randomUUID(),
entity_type: entityType,
entity_id: String(entityId),
lat: normalizedLat,
lon: normalizedLon,
status: 'pending',
attempts: 0,
last_error: null,
started_at: null,
completed_at: null,
created_at: now,
updated_at: now,
})
.onConflict([
'entity_type',
'entity_id',
])
.merge({
lat: normalizedLat,
lon: normalizedLon,
status: 'pending',
attempts: 0,
last_error: null,
started_at: null,
completed_at: null,
updated_at: now,
});
return {
queued: true,
entity_type: entityType,
entity_id: String(entityId),
lat: normalizedLat,
lon: normalizedLon,
};
}
module.exports = {
enqueueGeocodeJob,
};