bowling-analysis-system
Version:
A comprehensive system for analyzing bowling techniques using video processing and metrics calculation
154 lines (134 loc) • 4.53 kB
JavaScript
/**
* @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;