""" Additional validators for schema validation """ import re VALID_INTERVALS = ['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1w', '1mo', '3mo'] def validate_interval_field(cls, v): """Validate interval format""" if v not in VALID_INTERVALS: raise ValueError(f"Invalid interval: {v}. Valid intervals: {', '.join(VALID_INTERVALS)}") return v def validate_period_field(cls, v): """Validate period format""" if v: from app.utils.date_utils import validate_period_format if not validate_period_format(v): raise ValueError(f"Invalid period format: {v}. Expected format: Nd/Nm/Ny (e.g., 1d, 3m, 2y)") return v def validate_quarters_field(cls, v): """Validate quarter format""" if v: for quarter in v: if not re.match(r'^\d{4}Q[1-4]$', quarter): raise ValueError(f"Invalid quarter format: {quarter}. Expected format: YYYYQN (e.g., 2020Q1)") return v def validate_time_approaches(cls, v, values): """Ensure one of dates, quarters, or period is provided""" quarters = values.get('quarters') period = values.get('period') # Count non-None approaches approaches = [bool(v), bool(quarters), bool(period)] provided_count = sum(approaches) if provided_count == 0: raise ValueError("One of start_date/end_date, quarters, or period must be provided") if provided_count > 1: raise ValueError("Cannot specify multiple time approaches - use one of: date range, quarters, or period") return v def validate_end_date_field(cls, v, values): """Validate end_date if using date-based approach""" start_date = values.get('start_date') quarters = values.get('quarters') period = values.get('period') if not quarters and not period: # Using date-based approach if not v: raise ValueError("end_date is required when using date range approach") if start_date and v < start_date: raise ValueError("end_date must be on or after start_date") return v