@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
1,271 lines • 40.6 kB
JavaScript
/**
* 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