Decoupling generic infrastructure from app-specific business tracking using an inheritance-based service architecture.
A common pitfall in web/app development is mixing generic tracking infrastructure (e.g., ad revenue, standard IAP, app open events) with application-specific business logic (e.g., chat_message_sent, image_studio_download, auth_error_code).
The Extension Layer Pattern separates these concerns by:
starter_kit) generic and reusable.AppAnalyticsEvents)Centralizes all app-specific event names as static const strings, preventing typos and providing a single source of truth for the dashboard naming convention.
Example:
abstract class AppAnalyticsEvents {
static const String chatMessageSent = 'chat_message_sent';
static const String chatModelSwitched = 'chat_model_switched';
static const String imageGenerationStarted = 'image_generation_started';
}
AppAnalyticsService)Inherits from the base AnalyticsService. It wraps the generic logEvent with high-level, business-specific methods.
Core Benefits:
Map<String, dynamic> in Blocs or Screens.Example:
class AppAnalyticsService extends AnalyticsService {
AppAnalyticsService(super.bloc);
static final AppAnalyticsService instance = AppAnalyticsService(StarterKit.analyticsBloc);
// Business Logic Methods
void logChatMessageSent({
required String modelId,
required bool hasAttachment,
}) => logEvent(AppAnalyticsEvents.chatMessageSent, parameters: {
'model_id': modelId,
'model_provider': _inferProvider(modelId),
'has_attachment': hasAttachment,
'platform': Platform.operatingSystem,
});
static String _inferProvider(String modelId) =>
modelId.startsWith('gpt') ? 'openai' : 'other';
}
starter_kit) exports its base AnalyticsService and AnalyticsBloc.AppAnalyticsEvents with all required constants.AppAnalyticsService extending the base. Add a singleton instance.logEvent calls in Blocs with typed calls from AppAnalyticsService.instance.AppAnalyticsEvents constants.latency_ms or total_tokens) should be handled cleanly with logic like if (val != null) 'key': val.ad_impression and iap_success without any extra code.logRetentionEvent method for user lifecycle milestones (D1, D3, D7) — these often require separate dashboards in tools like Firebase/PostHog.AnalyticsService as they are universal across most apps.AppAnalyticsEvents dictionary createdAppAnalyticsService extends AnalyticsServicelogEvent calls exist in the presentation layer