UNPKG

bowling-analysis-system

Version:

A comprehensive system for analyzing bowling techniques using video processing and metrics calculation

154 lines (134 loc) 4.53 kB
/** * @module bowling_analysis/utils/SchemaValidator * @description Schema validation for bowling analysis pipeline */ const { validateBiasData, validateKeypointData, validateReferenceData } = require('../../utils/validation'); class SchemaValidator { constructor(options = {}) { this.options = { debug: false, ...options }; } /** * Validate pipeline input data * @param {Object} data Input data object * @param {string} stage Pipeline stage name * @returns {boolean} Validation result */ validateStageInput(data, stage) { try { switch (stage) { case 'FILE_LOADER': return this._validateFileLoaderInput(data); case 'KEYPOINT_PROCESSOR': return validateKeypointData(data); case 'METRICS_CALCULATOR': return this._validateMetricsInput(data); case 'EVENT_DETECTOR': return this._validateEventDetectorInput(data); case 'BIAS_CALCULATOR': return validateBiasData(data); case 'ANALYSIS_GENERATOR': return this._validateAnalysisInput(data); case 'FILE_SAVER': return this._validateFileOutput(data); default: console.warn(`Unknown pipeline stage: ${stage}`); return false; } } catch (error) { if (this.options.debug) { console.error(`Validation error for stage ${stage}:`, error); } return false; } } /** * Validate pipeline output data * @param {Object} data Output data object * @param {string} stage Pipeline stage name * @returns {boolean} Validation result */ validateStageOutput(data, stage) { try { switch (stage) { case 'FILE_LOADER': return this._validateFileLoaderOutput(data); case 'KEYPOINT_PROCESSOR': return this._validateProcessedKeypoints(data); case 'METRICS_CALCULATOR': return this._validateMetricsOutput(data); case 'EVENT_DETECTOR': return this._validateEventDetectorOutput(data); case 'BIAS_CALCULATOR': return validateBiasData(data); case 'ANALYSIS_GENERATOR': return this._validateAnalysisOutput(data); case 'FILE_SAVER': return this._validateSavedFile(data); default: console.warn(`Unknown pipeline stage: ${stage}`); return false; } } catch (error) { if (this.options.debug) { console.error(`Validation error for stage ${stage}:`, error); } return false; } } /** * Validate event sequence * @param {Object} events Event data * @returns {boolean} Validation result */ validateEventSequence(events) { if (!events || typeof events !== 'object') return false; const { backFootLanding, frontFootLanding, releasePoint } = events; // Check if we have all required events if (!backFootLanding || !frontFootLanding || !releasePoint) { return false; } // Validate sequence: backFootLanding < frontFootLanding < releasePoint return ( backFootLanding.frameIndex < frontFootLanding.frameIndex && frontFootLanding.frameIndex < releasePoint.frameIndex ); } // Private validation methods _validateFileLoaderInput(data) { return data && (data.filePath || data.buffer); } _validateFileLoaderOutput(data) { return data && Array.isArray(data.frames) && data.frames.length > 0; } _validateProcessedKeypoints(data) { return data && Array.isArray(data) && data.length > 0; } _validateMetricsInput(data) { return data && Array.isArray(data.keypoints) && data.keypoints.length > 0; } _validateMetricsOutput(data) { return data && data.metrics && data.timeSeries; } _validateEventDetectorInput(data) { return data && data.metrics && data.timeSeries; } _validateEventDetectorOutput(data) { return data && data.events && typeof data.events === 'object'; } _validateAnalysisInput(data) { return data && data.metrics && data.events; } _validateAnalysisOutput(data) { return data && data.analysis && typeof data.analysis === 'object'; } _validateFileOutput(data) { return data && (data.metrics || data.events || data.analysis); } _validateSavedFile(data) { return data && data.path && data.success; } } module.exports = SchemaValidator;