fina autoamtiona adn billing and credits

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-04 15:54:15 +00:00
parent f8a9293196
commit 40dfe20ead
40 changed files with 5680 additions and 18 deletions

View File

@@ -0,0 +1,52 @@
"""
AI Validators Package
Shared validation logic for AI functions
"""
from .cluster_validators import validate_minimum_keywords, validate_keyword_selection
# The codebase also contains a module-level file `ai/validators.py` which defines
# common validator helpers (e.g. `validate_ids`). Because there is both a
# package directory `ai/validators/` and a module file `ai/validators.py`, Python
# will resolve `igny8_core.ai.validators` to the package and not the module file.
# To avoid changing many imports across the project, load the module file here
# and re-export the commonly used functions.
import importlib.util
import os
_module_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'validators.py'))
if os.path.exists(_module_path):
spec = importlib.util.spec_from_file_location('igny8_core.ai._validators_module', _module_path)
_validators_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(_validators_mod)
# Re-export commonly used functions from the module file
validate_ids = getattr(_validators_mod, 'validate_ids', None)
validate_keywords_exist = getattr(_validators_mod, 'validate_keywords_exist', None)
validate_cluster_limits = getattr(_validators_mod, 'validate_cluster_limits', None)
validate_cluster_exists = getattr(_validators_mod, 'validate_cluster_exists', None)
validate_tasks_exist = getattr(_validators_mod, 'validate_tasks_exist', None)
validate_api_key = getattr(_validators_mod, 'validate_api_key', None)
validate_model = getattr(_validators_mod, 'validate_model', None)
validate_image_size = getattr(_validators_mod, 'validate_image_size', None)
else:
# Module file missing - keep names defined if cluster validators provide them
validate_ids = None
validate_keywords_exist = None
validate_cluster_limits = None
validate_cluster_exists = None
validate_tasks_exist = None
validate_api_key = None
validate_model = None
validate_image_size = None
__all__ = [
'validate_minimum_keywords',
'validate_keyword_selection',
'validate_ids',
'validate_keywords_exist',
'validate_cluster_limits',
'validate_cluster_exists',
'validate_tasks_exist',
'validate_api_key',
'validate_model',
'validate_image_size',
]

View File

@@ -0,0 +1,105 @@
"""
Cluster-specific validators
Shared between auto-cluster function and automation pipeline
"""
import logging
from typing import Dict, List
logger = logging.getLogger(__name__)
def validate_minimum_keywords(
keyword_ids: List[int],
account=None,
min_required: int = 5
) -> Dict:
"""
Validate that sufficient keywords are available for clustering
Args:
keyword_ids: List of keyword IDs to cluster
account: Account object for filtering
min_required: Minimum number of keywords required (default: 5)
Returns:
Dict with 'valid' (bool) and 'error' (str) or 'count' (int)
"""
from igny8_core.modules.planner.models import Keywords
# Build queryset
queryset = Keywords.objects.filter(id__in=keyword_ids, status='new')
if account:
queryset = queryset.filter(account=account)
# Count available keywords
count = queryset.count()
# Validate minimum
if count < min_required:
return {
'valid': False,
'error': f'Insufficient keywords for clustering. Need at least {min_required} keywords, but only {count} available.',
'count': count,
'required': min_required
}
return {
'valid': True,
'count': count,
'required': min_required
}
def validate_keyword_selection(
selected_ids: List[int],
available_count: int,
min_required: int = 5
) -> Dict:
"""
Validate keyword selection (for frontend validation)
Args:
selected_ids: List of selected keyword IDs
available_count: Total count of available keywords
min_required: Minimum required
Returns:
Dict with validation result
"""
selected_count = len(selected_ids)
# Check if any keywords selected
if selected_count == 0:
return {
'valid': False,
'error': 'No keywords selected',
'type': 'NO_SELECTION'
}
# Check if enough selected
if selected_count < min_required:
return {
'valid': False,
'error': f'Please select at least {min_required} keywords. Currently selected: {selected_count}',
'type': 'INSUFFICIENT_SELECTION',
'selected': selected_count,
'required': min_required
}
# Check if enough available (even if not all selected)
if available_count < min_required:
return {
'valid': False,
'error': f'Not enough keywords available. Need at least {min_required} keywords, but only {available_count} exist.',
'type': 'INSUFFICIENT_AVAILABLE',
'available': available_count,
'required': min_required
}
return {
'valid': True,
'selected': selected_count,
'available': available_count,
'required': min_required
}