Files
juzi/h5/lib/capture-diagnostics.js
T

44 lines
2.3 KiB
JavaScript

'use strict';
const CaptureQuality = require('../js/capture-quality.js');
const HeadPose = require('../js/head-pose.js');
const views = ['front', 'left', 'right'];
function scalar(value) { return typeof value === 'number' && Number.isFinite(value) ? value : null; }
// Client observations are untrusted calibration hints, never authorization or
// a provider-quality verdict. Strip arbitrary strings/extra fields on ingestion.
function normalize(input) {
if (!input || typeof input !== 'object') return null;
const version = typeof input.version === 'string' && /^[\w.-]{1,64}$/.test(input.version) ? input.version : 'unknown';
const result = { version, source: 'client-untrusted', views: {} };
for (const key of views) {
const row = input.views && input.views[key];
if (!row || typeof row !== 'object') continue;
const out = { mode: ['live', 'file', 'unchecked', 'mock'].includes(row.mode) ? row.mode : 'unknown' };
if (['preview', 'none'].includes(row.check_stage)) out.check_stage = row.check_stage;
if (row.reason === 'model-unavailable') out.reason = row.reason;
if (typeof row.direction_checked === 'boolean') out.direction_checked = row.direction_checked;
for (const metric of ['yaw', 'pitch', 'roll', 'score', 'luma', 'ratio', 'center_x', 'center_y']) {
const value = scalar(row[metric]);
if (value != null && Math.abs(value) <= 1000) out[metric] = value;
}
result.views[key] = out;
}
if (version === CaptureQuality.config.version) result.policy = { capture: CaptureQuality.config, pose: HeadPose.config };
return result;
}
function assess(raw) {
const nested = raw.side_result || {};
const result = { status: 'valid', views: {} };
for (const key of ['left', 'right']) {
const side = raw[key + '_side_result'] || nested[key + '_side_result'];
const node = side && side[key + '_jawline_info'];
const quality = scalar(node && node[key + '_jawline_quality']);
const angle = scalar(node && node[key + '_jawline_angle']);
const status = quality == null ? 'unavailable' : quality === 1 && angle != null ? 'valid' : 'invalid';
result.views[key] = { quality, angle, status };
if (status === 'invalid') result.status = 'invalid';
else if (status === 'unavailable' && result.status === 'valid') result.status = 'unavailable';
}
return result;
}
module.exports = { normalize, assess };