UNPKG

@simonecoelhosfo/optimizely-mcp-server

Version:

Optimizely MCP Server for AI assistants with integrated CLI tools

1,271 lines 40.6 kB
/** * FieldLocalityResolver - Knows WHERE fields actually live in the database * * CRITICAL: This resolver prevents unnecessary JOINs by understanding field locations * Example: environment_key lives in flag_environments, NOT environments table */ import { getLogger } from '../../logging/Logger.js'; export class FieldLocalityResolver { logger = getLogger(); /** * CRITICAL: This mapping tells us where fields ACTUALLY live * This prevents JOIN explosions by knowing the true field locations */ FIELD_PRIMARY_LOCATIONS = { // PROJECT FIELDS 'project_id': { table: 'projects', entity: 'projects', isJoinTable: false }, 'account_id': { table: 'projects', entity: 'projects', isJoinTable: false }, 'platform': { table: 'projects', entity: 'projects', isJoinTable: false }, 'is_flags_enabled': { table: 'projects', entity: 'projects', isJoinTable: false }, 'confidence_threshold': { table: 'projects', entity: 'projects', isJoinTable: false }, 'dcp_service_id': { table: 'projects', entity: 'projects', isJoinTable: false }, 'is_classic': { table: 'projects', entity: 'projects', isJoinTable: false }, 'socket_token': { table: 'projects', entity: 'projects', isJoinTable: false }, 'third_party_platform': { table: 'projects', entity: 'projects', isJoinTable: false }, 'web_snippet': { table: 'projects', entity: 'projects', isJoinTable: false }, // ENVIRONMENT FIELDS 'environment_key': { table: 'flag_environments', // CRITICAL: NOT environments table! entity: 'flag_environments', isJoinTable: true, alternativeLocations: [{ table: 'environments', requiresJoin: true, joinPath: ['flags', 'flag_environments', 'environments'] }, { table: 'rules', requiresJoin: false, joinPath: [] }] }, 'environment_name': { table: 'environments', entity: 'environments', isJoinTable: false, alternativeLocations: [{ table: 'rules', // Also stored in rules requiresJoin: false, joinPath: [] }] }, 'is_primary': { table: 'environments', entity: 'environments', isJoinTable: false }, 'priority': { table: 'environments', entity: 'environments', isJoinTable: false }, // FLAG FIELDS (Feature Experimentation) 'flag_key': { table: 'flags', entity: 'flags', isJoinTable: false, alternativeLocations: [{ table: 'flag_environments', requiresJoin: false, joinPath: [] }, { table: 'variations', requiresJoin: false, joinPath: [] }, { table: 'rules', requiresJoin: false, joinPath: [] }] }, 'flag_id': { table: 'flags', entity: 'flags', isJoinTable: false }, 'flag_name': { table: 'flags', entity: 'flags', isJoinTable: false, alternativeLocations: [{ table: 'rules', requiresJoin: false, joinPath: [] }] }, 'urn': { table: 'flags', entity: 'flags', isJoinTable: false, alternativeLocations: [{ table: 'rules', requiresJoin: false, joinPath: [] }, { table: 'rulesets', requiresJoin: false, joinPath: [] }] }, 'created_by_user_email': { table: 'flags', entity: 'flags', isJoinTable: false }, 'outlier_filtering_enabled': { table: 'flags', entity: 'flags', isJoinTable: false }, 'revision': { table: 'flags', entity: 'flags', isJoinTable: false, alternativeLocations: [{ table: 'rulesets', requiresJoin: false, joinPath: [] }] }, // FLAG_ENVIRONMENTS FIELDS (Rulesets) 'enabled': { table: 'flag_environments', entity: 'flag_environments', isJoinTable: true, alternativeLocations: [{ table: 'rules', requiresJoin: false, joinPath: [] }, { table: 'rulesets', requiresJoin: false, joinPath: [] }] }, 'rules_summary': { table: 'flag_environments', entity: 'flag_environments', isJoinTable: true }, // VARIATION FIELDS 'variation_key': { table: 'variations', entity: 'variations', isJoinTable: false, alternativeLocations: [{ table: 'rules', // In rules.variations JSON requiresJoin: false, joinPath: [] }] }, 'variation_id': { table: 'variations', entity: 'variations', isJoinTable: false }, 'variables': { table: 'variations', entity: 'variations', isJoinTable: false }, 'feature_enabled': { table: 'variations', entity: 'variations', isJoinTable: false }, 'variable_values': { table: 'variations', entity: 'variations', isJoinTable: false }, // VARIABLE DEFINITION FIELDS 'default_value': { table: 'variable_definitions', entity: 'flags', // Variable definitions belong to flags isJoinTable: false }, 'variable_type': { table: 'variable_definitions', entity: 'flags', // Variable definitions belong to flags isJoinTable: false }, // RULE FIELDS 'rule_id': { table: 'rules', entity: 'rules', isJoinTable: false }, 'rule_key': { table: 'rules', entity: 'rules', isJoinTable: false }, 'rule_type': { table: 'rules', entity: 'rules', isJoinTable: false }, 'percentage_included': { table: 'rules', entity: 'rules', isJoinTable: false }, 'distribution_mode': { table: 'rules', entity: 'rules', isJoinTable: false }, 'allow_list': { table: 'rules', entity: 'rules', isJoinTable: false }, 'deployed_variation_key': { table: 'rules', entity: 'rules', isJoinTable: false }, 'outcome': { table: 'rules', entity: 'rules', isJoinTable: false }, 'layer_experiment_id': { table: 'rules', entity: 'rules', isJoinTable: false }, 'fetch_results_ui_url': { table: 'rules', entity: 'rules', isJoinTable: false }, // EXPERIMENT FIELDS (Web Experimentation only) 'experiment_id': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'experiment_key': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'campaign_id': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'allocation_policy': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'holdback': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'campaigns', requiresJoin: false, joinPath: [] }] }, 'traffic_allocation': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'multivariate_traffic_policy': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'page_ids': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'url_targeting': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'campaigns', requiresJoin: false, joinPath: [] }] }, 'whitelist': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'schedule': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'earliest': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'campaigns', requiresJoin: false, joinPath: [] }] }, 'latest': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'campaigns', requiresJoin: false, joinPath: [] }] }, // EXPERIMENT RESULTS FIELDS (Performance/Visitor Data) // Critical: These fields are NOT in experiments table! // Updated based on actual JSON structure 'visitors': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Maps to JSON_EXTRACT(data_json, '$.reach.total_count') }, 'total_visitors': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Maps to JSON_EXTRACT(data_json, '$.reach.total_count') }, 'visitor_count': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Maps to JSON_EXTRACT(data_json, '$.reach.total_count') }, 'confidence': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Maps to JSON_EXTRACT(data_json, '$.stats_config.confidence_level') }, 'confidence_level': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Maps to JSON_EXTRACT(data_json, '$.stats_config.confidence_level') }, 'unique_conversions': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false // Complex: Maps to JSON_EXTRACT(data_json, '$.metrics[0].results.*.samples') }, 'baseline_visitors': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'baseline_count': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'treatment_visitors': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'treatment_count': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'use_stats_engine': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'stats_engine_version': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'start_time': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'last_update': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, // JSON fields in results_json 'conversion_rate': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'conversions': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'lift': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'statistical_significance': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'winner': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, 'winning_variation': { table: 'experiment_results', entity: 'experiment_results', isJoinTable: false }, // CAMPAIGN FIELDS (Web Experimentation) 'experiment_priorities': { table: 'campaigns', entity: 'campaigns', isJoinTable: false }, // PAGE FIELDS (Web Experimentation) 'page_id': { table: 'pages', entity: 'pages', isJoinTable: false }, 'page_key': { table: 'pages', entity: 'pages', isJoinTable: false }, 'edit_url': { table: 'pages', entity: 'pages', isJoinTable: false }, 'activation_type': { table: 'pages', entity: 'pages', isJoinTable: false }, 'activation_code': { table: 'pages', entity: 'pages', isJoinTable: false }, 'page_type': { table: 'pages', entity: 'pages', isJoinTable: false }, 'conditions': { table: 'pages', entity: 'pages', isJoinTable: false, alternativeLocations: [{ table: 'audiences', requiresJoin: false, joinPath: [] }] }, // AUDIENCE FIELDS 'audience_id': { table: 'audiences', entity: 'audiences', isJoinTable: false }, 'audience_conditions': { table: 'rules', // FIXED: Primary location is rules table entity: 'rules', // FIXED: Primary entity is rules isJoinTable: false, alternativeLocations: [{ table: 'audiences', // MOVED: audiences as alternative (uses 'conditions' field) requiresJoin: false, joinPath: [] }, { table: 'experiments', requiresJoin: false, joinPath: [] }] }, 'segmentation': { table: 'audiences', entity: 'audiences', isJoinTable: false }, 'experiment_count': { table: 'audiences', entity: 'audiences', isJoinTable: false }, // ATTRIBUTE FIELDS 'attribute_id': { table: 'attributes', entity: 'attributes', isJoinTable: false }, 'attribute_key': { table: 'attributes', entity: 'attributes', isJoinTable: false }, 'condition_type': { table: 'attributes', entity: 'attributes', isJoinTable: false }, // EVENT FIELDS 'event_id': { table: 'events', entity: 'events', isJoinTable: false }, 'event_key': { table: 'events', entity: 'events', isJoinTable: false }, 'event_type': { table: 'events', entity: 'events', isJoinTable: false }, 'category': { table: 'events', entity: 'events', isJoinTable: false, alternativeLocations: [{ table: 'pages', requiresJoin: false, joinPath: [] }] }, 'event_properties': { table: 'events', entity: 'events', isJoinTable: false }, 'config': { table: 'events', entity: 'events', isJoinTable: false }, 'is_editable': { table: 'events', entity: 'events', isJoinTable: false }, // GROUP FIELDS 'group_id': { table: 'groups', entity: 'groups', isJoinTable: false, alternativeLocations: [{ table: 'rules', requiresJoin: false, joinPath: [] }] }, 'entities': { table: 'groups', entity: 'groups', isJoinTable: false }, 'group_remaining_traffic_allocation': { table: 'rules', entity: 'rules', isJoinTable: false }, // EXTENSION FIELDS (Web Experimentation) 'extension_id': { table: 'extensions', entity: 'extensions', isJoinTable: false }, 'extension_type': { table: 'extensions', entity: 'extensions', isJoinTable: false }, 'implementation': { table: 'extensions', entity: 'extensions', isJoinTable: false }, 'fields': { table: 'extensions', entity: 'extensions', isJoinTable: false }, // WEBHOOK FIELDS (Web Experimentation) 'webhook_id': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, 'url': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, 'event_types': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, 'active': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, 'headers': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, 'secret': { table: 'webhooks', entity: 'webhooks', isJoinTable: false }, // COLLABORATOR FIELDS (Web Experimentation) 'user_id': { table: 'collaborators', entity: 'collaborators', isJoinTable: false }, 'email': { table: 'collaborators', entity: 'collaborators', isJoinTable: false }, 'role': { table: 'collaborators', entity: 'collaborators', isJoinTable: false, alternativeLocations: [{ table: 'flags', requiresJoin: false, joinPath: [] }, { table: 'rulesets', requiresJoin: false, joinPath: [] }] }, 'permissions_json': { table: 'collaborators', entity: 'collaborators', isJoinTable: false }, 'invited_at': { table: 'collaborators', entity: 'collaborators', isJoinTable: false }, 'last_seen_at': { table: 'collaborators', entity: 'collaborators', isJoinTable: false }, // LIST ATTRIBUTE FIELDS (Web Experimentation) 'list_attribute_id': { table: 'list_attributes', entity: 'list_attributes', isJoinTable: false }, 'key_field': { table: 'list_attributes', entity: 'list_attributes', isJoinTable: false }, 'list_type': { table: 'list_attributes', entity: 'list_attributes', isJoinTable: false }, 'list_content': { table: 'list_attributes', entity: 'list_attributes', isJoinTable: false }, // COMMON STATUS FIELDS 'status': { table: '*', // Multiple entities have this entity: 'experiments', // Default to experiments isJoinTable: false, alternativeLocations: [{ table: 'projects', requiresJoin: false, joinPath: [] }, { table: 'campaigns', requiresJoin: false, joinPath: [] }, { table: 'rules', requiresJoin: false, joinPath: [] }, { table: 'rulesets', requiresJoin: false, joinPath: [] }] }, // FLAG-SPECIFIC STATUS FIELDS (flags table has no status column - use archived or enabled) 'flag_status': { table: 'flags', entity: 'flags', isJoinTable: false, alternativeLocations: [{ table: 'flag_environments', requiresJoin: true, joinPath: ['flags', 'flag_environments'] }] }, // COMMON NAME FIELDS 'name': { table: '*', // Almost every entity has this entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'description': { table: '*', // Many entities have this entity: 'flags', // Will be resolved based on context isJoinTable: false }, // COMMON KEY FIELDS 'key': { table: '*', // Many entities have a key field entity: 'flags', // Will be resolved based on context isJoinTable: false }, // COMMON TIME FIELDS 'created': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'created_time': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'created_at': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'modified': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'updated_time': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, 'last_modified': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, // COMMON ID FIELDS 'id': { table: '*', entity: 'flags', // Will be resolved based on context isJoinTable: false }, // COMMON TYPE FIELDS 'type': { table: '*', // rules, campaigns, experiments, etc. entity: 'flags', // Will be resolved based on context isJoinTable: false }, // METRIC FIELDS 'metrics': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'rules', requiresJoin: false, joinPath: [] }, { table: 'campaigns', requiresJoin: false, joinPath: [] }] }, // VARIATION COUNT (special handling) 'variation_count': { table: 'COMPUTED', // This is computed, not stored entity: 'flags', isJoinTable: false }, // VARIATIONS FIELDS (for counting and aggregation) 'variations': { table: 'variations', entity: 'variations', isJoinTable: false }, // ROLLOUTS FIELDS (for percentage and traffic allocation) 'rollouts': { table: 'rules', // Rollouts are stored in rules table entity: 'rules', isJoinTable: false }, // FLAGS FIELDS (for counting flags in queries like "which environments have >100 flags") 'flags': { table: 'flags', entity: 'flags', isJoinTable: false }, // WEIGHT FIELDS 'weight': { table: 'variations', // For Web experiments entity: 'variations', isJoinTable: false }, // CHANGE FIELDS 'changes': { table: 'experiments', entity: 'experiments', isJoinTable: false, alternativeLocations: [{ table: 'campaigns', requiresJoin: false, joinPath: [] }] }, // ACTION FIELDS 'actions': { table: 'variations', // Web experiment variations entity: 'variations', isJoinTable: false }, // SDK FIELDS 'sdks': { table: 'projects', entity: 'projects', isJoinTable: false }, // DATA JSON FIELDS (for complex queries) 'data_json': { table: '*', // Every entity has this entity: 'flags', // Will be resolved based on context isJoinTable: false }, // SYNC METADATA 'synced_at': { table: '*', // Every entity has this entity: 'flags', // Will be resolved based on context isJoinTable: false }, // FEATURE FLAGS SPECIFIC 'feature_id': { table: 'experiments', // Feature tests entity: 'experiments', isJoinTable: false }, 'feature_key': { table: 'experiments', entity: 'experiments', isJoinTable: false }, 'feature_name': { table: 'experiments', entity: 'experiments', isJoinTable: false }, // RESULTS TOKEN 'results_token': { table: 'experiments', entity: 'experiments', isJoinTable: false }, // COMMENT FIELDS 'comment': { table: 'rules', entity: 'rules', isJoinTable: false }, // DELIVER FIELDS 'deliver': { table: 'rules', // For targeted_delivery rules entity: 'rules', isJoinTable: false }, // DEPLOYED FIELDS 'deployed_td_rule_audience_conditions': { table: 'rules', entity: 'rules', isJoinTable: false }, 'deployed_td_rule_key': { table: 'rules', entity: 'rules', isJoinTable: false }, 'deployed_td_rule_percentage_included': { table: 'rules', entity: 'rules', isJoinTable: false }, // RULESET SPECIFIC FIELDS 'rule_priorities': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'default_variation_key': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'default_variation_name': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'disable_url': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'enable_url': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'fetch_default_variation_url': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'fetch_flag_url': { table: 'rulesets', entity: 'rulesets', isJoinTable: false }, 'update_url': { table: 'rulesets', entity: 'rulesets', isJoinTable: false, alternativeLocations: [{ table: 'flags', requiresJoin: false, joinPath: [] }] }, // URL FIELDS 'archive_url': { table: 'flags', entity: 'flags', isJoinTable: false }, 'unarchive_url': { table: 'flags', entity: 'flags', isJoinTable: false }, 'delete_url': { table: 'flags', entity: 'flags', isJoinTable: false }, // A/B TEST RELATED FIELDS 'AB': { table: 'rules', entity: 'rules', isJoinTable: false, alternativeLocations: [{ table: 'experiments', requiresJoin: false, joinPath: [] }] }, 'a_b': { table: 'rules', entity: 'rules', isJoinTable: false }, }; /** * Enhanced Field Mappings for Deep JSON Analytics * * These mappings handle complex operations that require JSON iteration, * aggregation across dynamic keys, and context-aware filtering. */ ENHANCED_FIELD_MAPPINGS = { // CONVERSION ANALYTICS - requires dynamic key iteration 'unique_conversions': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics[0].results', aggregation: 'SUM(json_extract(value, "$.samples"))', requiresIteration: true, contextFilters: ['json_extract(experiment_results.data_json, "$.metrics[0].aggregator") = "unique"'], iterationSource: '$.metrics[0].results' }, 'total_conversions': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics[0].results', aggregation: 'SUM(json_extract(value, "$.samples"))', requiresIteration: true, contextFilters: ['json_extract(experiment_results.data_json, "$.metrics[0].aggregator") = "total"'], iterationSource: '$.metrics[0].results' }, 'conversion_rate': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics[0].results', aggregation: 'AVG(json_extract(value, "$.rate"))', requiresIteration: true, iterationSource: '$.metrics[0].results' }, // METRICS COUNT - Special handling for COUNT(metrics) queries 'metrics': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics', countCondition: 'json_array_length(experiment_results.data_json, \'$.metrics\')', requiresIteration: false }, // EVENT PROPERTY FILTERING - nested condition handling 'event_category': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics[0].event_properties.filter.conditions[*].value', requiresIteration: true, contextFilters: ['json_extract(experiment_results.data_json, "$.metrics[0].event_properties.filter.conditions[0].name") = "category"'], iterationSource: '$.metrics[0].event_properties.filter.conditions' }, // CONFIDENCE INTERVALS - array handling 'confidence_interval': { table: 'experiment_results', entity: 'experiment_results', jsonPath: '$.metrics[0].results', aggregation: 'json_extract(value, "$.lift.confidence_interval")', requiresIteration: true, iterationSource: '$.metrics[0].results' } }; /** * Resolve where a field actually lives based on query context */ resolveFieldLocality(field, queryIntent, primaryEntity) { const normalizedField = this.normalizeFieldName(field); const location = this.FIELD_PRIMARY_LOCATIONS[normalizedField]; if (!location) { // Unknown field - assume it's on the primary entity return { field: normalizedField, primaryLocation: primaryEntity, requiresJoin: false, isJsonPath: field.includes('.') || field.includes('['), confidence: 0.5 }; } // Handle fields that should resolve to the primary entity let resolvedEntity = location.entity; let resolvedTable = location.table; if (location.table === '*') { // This field exists on many entities, use the primary entity resolvedEntity = primaryEntity; // CRITICAL FIX: Handle fields that don't exist on specific entities if (normalizedField === 'status' && (primaryEntity === 'flags' || primaryEntity === 'flag')) { // flags table has no status column - use archived instead, or check flag_environments.enabled return { field: 'archived', // Convert status to archived for flags primaryLocation: 'flags', requiresJoin: false, isJsonPath: false, confidence: 0.8 }; } // FIXED: Prevent double pluralization (flags -> flagss) if (primaryEntity.endsWith('s') && !primaryEntity.endsWith('ss') && !primaryEntity.endsWith('us')) { resolvedTable = primaryEntity; // Already plural } else { resolvedTable = primaryEntity + 's'; // Add pluralization } } // For COUNT queries, prefer join tables if available if (queryIntent.type === 'count' && location.isJoinTable) { return { field: normalizedField, primaryLocation: location.table, requiresJoin: false, // Can query join table directly! isJsonPath: false, confidence: 0.95 }; } // For LIST/DETAIL queries, check if we need a JOIN const requiresJoin = resolvedEntity !== primaryEntity; return { field: normalizedField, primaryLocation: resolvedTable, requiresJoin, isJsonPath: false, confidence: 0.9 }; } /** * Check if a field has enhanced mapping for deep JSON analytics */ hasEnhancedMapping(field) { const normalizedField = this.normalizeFieldName(field); return normalizedField in this.ENHANCED_FIELD_MAPPINGS; } /** * Get enhanced mapping for a field that requires complex JSON operations */ getEnhancedMapping(field) { const normalizedField = this.normalizeFieldName(field); return this.ENHANCED_FIELD_MAPPINGS[normalizedField] || null; } /** * Check if a field operation requires JSON iteration (dynamic key aggregation) */ requiresJsonIteration(field) { const mapping = this.getEnhancedMapping(field); return mapping?.requiresIteration || false; } /** * Get the COUNT condition for a field (handles COUNT(metrics) -> json_array_length) */ getCountCondition(field) { const mapping = this.getEnhancedMapping(field); return mapping?.countCondition || null; } /** * Resolve multiple fields and build a locality map */ resolveFieldsLocality(fields, queryIntent, primaryEntity) { const localityMap = new Map(); for (const field of fields) { const locality = this.resolveFieldLocality(field, queryIntent, primaryEntity); localityMap.set(field, locality); this.logger.debug(`Field locality resolved: ${field} -> ${locality.primaryLocation} (requiresJoin: ${locality.requiresJoin})`); } return localityMap; } /** * Check if a field exists in a specific table */ isFieldInTable(field, table) { const normalizedField = this.normalizeFieldName(field); const location = this.FIELD_PRIMARY_LOCATIONS[normalizedField]; if (!location) return false; // Check primary location if (location.table === table || location.table === '*') { return true; } // Check alternative locations if (location.alternativeLocations) { return location.alternativeLocations.some(alt => alt.table === table); } return false; } /** * Get the optimal table for aggregating by a field */ getOptimalTableForAggregation(field, aggregationType) { const normalizedField = this.normalizeFieldName(field); const location = this.FIELD_PRIMARY_LOCATIONS[normalizedField]; if (!location) return null; // For COUNT operations, prefer join tables if (aggregationType === 'count' && location.isJoinTable) { return location.table; } return location.table; } /** * Normalize field names to handle variations */ normalizeFieldName(field) { // Remove table prefixes const withoutPrefix = field.includes('.') ? field.split('.').pop() : field; // Common normalizations const normalizations = { 'environment': 'environment_key', 'flag': 'flag_key', 'experiment': 'experiment_key', 'variation': 'variation_key', 'audience': 'audience_id', 'event': 'event_key', 'created_at': 'created', 'updated_at': 'modified', 'is_enabled': 'enabled', // A/B test related normalizations 'A/B': 'AB', 'a/b': 'AB', 'AB_test': 'AB', 'ab_test': 'AB', 'percentage': 'percentage_included', 'traffic': 'traffic_allocation' }; return normalizations[withoutPrefix] || withoutPrefix; } } //# sourceMappingURL=FieldLocalityResolver.js.map