initialize method
Inicializa con configuración local, luego intenta obtener remote
Implementation
Future<void> initialize({
required ObslyConfig localConfig,
required String apiKey,
required String instanceURL,
String? remoteConfigURL,
String? appVersion,
String? appName,
String? userId,
String? release,
bool? proEnv,
}) async {
if (_isInitialized) {
ObslyLogger.warn('ConfigController already initialized');
return;
}
try {
// 1. Aplicar configuración local con defaults (validada)
ObslyLogger.debug(
'Local config enableScreenshotOnUi: ${localConfig.enableScreenshotOnUi}');
_currentConfig = ObslyConfig.withDefaults(
enableScreenshotOnUi: localConfig.enableScreenshotOnUi,
requestBlacklist: localConfig.requestBlacklist,
requestBodyWhitelist: localConfig.requestBodyWhitelist,
requestHeadersWhitelist: localConfig.requestHeadersWhitelist,
rageClick: localConfig.rageClick,
anonymization:
localConfig.anonymization, // 🔥 FIX: Pass anonymization config!
enableCrashes: localConfig.enableCrashes,
enableLifeCycleLog: localConfig.enableLifeCycleLog,
enableRequestLog: localConfig.enableRequestLog,
enableTagger: localConfig.enableTagger,
enablePerformance: localConfig.enablePerformance,
enableMetrics: localConfig.enableMetrics,
enableUI: localConfig.enableUI,
automaticViewDetection: localConfig.automaticViewDetection,
sessionMaxLengthMins: localConfig.sessionMaxLengthMins,
bufferSize: localConfig.bufferSize,
captureConsole: localConfig.captureConsole,
captureBodyOnError: localConfig.captureBodyOnError,
messengerInterval: localConfig.messengerInterval,
enableDebugTools: localConfig.enableDebugTools,
obslyTools: localConfig.obslyTools,
rateLimits: localConfig.rateLimits,
enableRateLimit: localConfig.enableRateLimit,
).validate();
ObslyLogger.debug(
'[PIIFILT] ConfigController final anonymization config: ${_currentConfig!.anonymization != null}');
if (_currentConfig!.anonymization?.piiFilterRules != null) {
ObslyLogger.debug(
'[PIIFILT] ConfigController final PII rules count: ${_currentConfig!.anonymization!.piiFilterRules!.length}');
for (final rule in _currentConfig!.anonymization!.piiFilterRules!) {
ObslyLogger.debug(
'[PIIFILT] Final rule: ${rule.name} (${rule.id})');
}
}
// Initialize tracking for local config (all parameters are local or default)
_initializeLocalConfigTracking(localConfig);
await _storeCurrentConfig();
ObslyLogger.debug('Local config applied');
// 2. Validar integridad de la caché antes de usarla
final cacheValid = await _validateCacheIntegrity();
if (!cacheValid) {
ObslyLogger.debug(
'Cache integrity validation failed - will fetch from server');
}
// 3. Intentar obtener remote config o usar caché
final shouldFetch = cacheValid ? await _shouldFetchRemoteConfig() : true;
ObslyLogger.debug(
'Should fetch remote config: $shouldFetch (cache valid: $cacheValid)');
if (shouldFetch) {
ObslyLogger.debug('Fetching remote config from server...');
final remoteConfig = await _fetchRemoteConfig(
apiKey: apiKey,
instanceURL: instanceURL,
remoteConfigURL: remoteConfigURL,
appVersion: appVersion ?? 'unknown',
proEnv: proEnv ?? false,
);
if (remoteConfig != null) {
// 3. Remote config SOBREESCRIBE local config, manteniendo defaults
_updateRemoteConfigStatus(
wasRequested: true,
isCached: false,
lastFetched: DateTime.now(),
fetchSuccessful: true,
);
_currentConfig =
_mergeWithDefaults(_currentConfig!, remoteConfig).validate();
await _storeCurrentConfig();
// Almacenar remote config y timestamp de forma atómica
try {
await _storeRemoteConfigWithTimestamp(remoteConfig);
ObslyLogger.debug('Remote config stored in cache successfully');
} catch (e) {
ObslyLogger.warn('Failed to store remote config in cache: $e');
// Continue anyway - we still have the config in memory
}
// 4. Fetch obsly_tools si están disponibles
await _fetchObslyToolsIfAvailable(apiKey);
ObslyLogger.debug('Remote config applied and overwrote local config');
} else {
ObslyLogger.warn('Failed to fetch remote config from server');
_updateRemoteConfigStatus(
wasRequested: true,
fetchSuccessful: false,
fetchError: 'Failed to fetch remote config',
);
// Si el fetch falla, intentar usar caché existente como fallback
ObslyLogger.debug(
'Attempting to use cached remote config as fallback...');
final cachedRemote = await _loadRemoteConfigFromCache();
if (cachedRemote != null) {
final cacheTimestamp = await _getCacheTimestamp();
ObslyLogger.debug(
'Using expired cache as fallback due to network failure');
_updateRemoteConfigStatus(
wasRequested: true,
isCached: true,
lastCacheTime: cacheTimestamp,
fetchSuccessful: false,
fetchError: 'Using expired cache due to network failure',
);
_currentConfig =
_mergeWithDefaults(_currentConfig!, cachedRemote).validate();
await _storeCurrentConfig();
// Fetch obsly_tools si están disponibles en caché
await _fetchObslyToolsIfAvailable(apiKey);
}
}
} else {
ObslyLogger.debug('Using cached remote config (cache is valid)');
final cachedRemote = await _loadRemoteConfigFromCache();
if (cachedRemote != null) {
final cacheTimestamp = await _getCacheTimestamp();
_updateRemoteConfigStatus(
wasRequested: true,
isCached: true,
lastCacheTime: cacheTimestamp,
fetchSuccessful: true,
);
_currentConfig =
_mergeWithDefaults(_currentConfig!, cachedRemote).validate();
await _storeCurrentConfig();
// Fetch obsly_tools si están disponibles en caché
await _fetchObslyToolsIfAvailable(apiKey);
ObslyLogger.debug('Cached remote config applied successfully');
} else {
ObslyLogger.warn(
'Cache indicated as valid but no cached config found - forcing fetch');
// El timestamp indica que hay caché, pero no se encontró el config
// Esto puede indicar corrupción de datos - forzar fetch
final remoteConfig = await _fetchRemoteConfig(
apiKey: apiKey,
instanceURL: instanceURL,
remoteConfigURL: remoteConfigURL,
appVersion: appVersion ?? 'unknown',
proEnv: proEnv ?? false,
);
if (remoteConfig != null) {
_updateRemoteConfigStatus(
wasRequested: true,
isCached: false,
lastFetched: DateTime.now(),
fetchSuccessful: true,
);
_currentConfig =
_mergeWithDefaults(_currentConfig!, remoteConfig).validate();
await _storeCurrentConfig();
await _storeRemoteConfigWithTimestamp(remoteConfig);
await _fetchObslyToolsIfAvailable(apiKey);
ObslyLogger.debug('Remote config recovered after cache corruption');
} else {
_updateRemoteConfigStatus(
wasRequested: true,
fetchSuccessful: false,
fetchError: 'Cache corruption detected and server fetch failed',
);
}
}
}
_isInitialized = true;
ObslyLogger.log('ConfigController initialized with final config');
} catch (e) {
ObslyLogger.error('Error initializing ConfigController: $e');
// En caso de error, usar solo configuración local
_currentConfig = localConfig.validate();
_isInitialized = true;
}
}