Analytics Architecture Optimization
Current State
The analytics pipeline uses envelopeBuilder.ts for transforming events to CDM format. This was originally designed for batch processing with local database storage and network retry logic.
Inefficiency
We're now using envelopeBuilder for single-event transformation, which creates overhead:
- Full Envelope Construction: Builds complete envelope structure (originator, originatorContext, events array) for every single event
- Wasted Data: We only extract
events[0]and discard originator/originatorContext - Batch Sequence Numbering: Implements sequence numbering for batches, but we send events individually
- StoredAnalyticsEvent Abstraction: Database storage format no longer needed (HP Jarvis SDK handles persistence)
Why This Works Anyway
✅ Transformation logic is proven and working - All CDM mapping rules are correct
✅ Maintains adapter pattern - All API-specific logic stays in adapter folder
✅ No functional issues - Just wasted CPU cycles building/discarding unused data
✅ Acceptable performance - Overhead is minor for typical event volumes
Optimization Opportunity
Goal
Create a single-event CDM transformer that keeps the proven transformation logic but removes batch-processing overhead.
Proposed Architecture
// New: electron/src/main/analytics/adapter/cdmEventBuilder.ts
export interface CDMEventConfig {
appName: string;
appVersion: string;
}
export function buildCDMEvent(
event: InternalEvent,
config: CDMEventConfig
): CDMEventPayload | null {
// Extract transformation logic from envelopeBuilder.ts:
// - Action derivation (deriveAction)
// - View hierarchy building (buildViewHierarchy)
// - Control name generation (getControlName)
// - Action aux params (buildActionAuxParams)
// - Event detail construction
//
// Skip:
// - Envelope wrapper (originator, originatorContext)
// - Batch sequence numbering
// - Array iteration (single event only)
return {
version: '1.1.0',
dateTime: toIso(event.ts),
eventDetailType: SIMPLE_UI_EVENT_DETAIL_TYPE,
eventDetail: buildEventDetail(...),
eventCategory: 'telemetry',
sequenceNumber: 0, // HP Jarvis SDK may handle this
sequenceNumberGlobal: 0,
};
}
Migration Path
Phase 1: Extract & Test
- Create
cdmEventBuilder.tswith core transformation logic - Add comprehensive unit tests matching envelopeBuilder test coverage
- Run tests comparing output:
buildCDMEvent(event)vsbuildTelemetryEnvelope([event]).events[0]
Phase 2: Switch & Monitor
- Update
nativeAnalytics.tsto usebuildCDMEventinstead ofbuildTelemetryEnvelope - Add debug logging to compare outputs during canary rollout
- Monitor for any transformation discrepancies
Phase 3: Cleanup
- Mark
envelopeBuilder.tsas deprecated (keep for reference) - Update architecture documentation
- Remove StoredAnalyticsEvent abstraction if no longer needed
Benefits
- Performance: ~30-50% faster event processing (estimate, needs profiling)
- Clarity: Simpler code path - "transform event to CDM" vs "build batch envelope → extract event"
- Maintenance: Easier to understand single-event transformer vs batch logic
- Memory: Less object allocation per event
Risks
- Regression: Could introduce subtle transformation bugs
- Testing: Need comprehensive coverage to ensure parity
- Time: Non-trivial extraction and validation effort
Decision
Status: Deferred (documented as TODO)
Rationale: Current architecture works correctly after recent refactoring. Focus on stability and delivery.
Trigger: Revisit if performance profiling shows analytics as bottleneck, or when major analytics changes needed.
Related Files
electron/src/main/services/nativeAnalytics.ts- See TODO comment inpublishEvent()electron/src/main/analytics/adapter/envelopeBuilder.ts- Current transformerelectron/src/main/analytics/adapter/preDbAdapter.ts- Still needed for filtering/enrichment
References
- Original discussion: Architecture review 2025-11-20
- Branch:
feat/HPCH-659-jarvis-data-collection - Related: Adapter pattern refactoring (appName/appVersion consolidation)