Problem
ProductUsageEvent is currently string/Map based, so event names, workflow/result values, and parameters are not tied to the documented analytics catalog. That leaves privacy-sensitive analytics rules dependent on manual discipline at each call site.
Evidence
lib/domain/entities/product_usage_event.dart defines name, workflow, and result as raw Strings and parameters as Map<String, Object>, then spreads the map into Firebase parameters.
lib/core/services/product_analytics_service.dart only gates collection and forwards event.name plus event.toAnalyticsParameters(...); it does not validate the event against the catalog.
lib/domain/use-cases/track_product_usage_event_use_case.dart catches tracking failures but does not reject unknown events, unknown parameters, forbidden fields, or invalid value categories.
docs/Analytics-Event-Catalog.md says optional parameters must be allowlisted per event and forbids identifiers, user-authored content, raw exceptions, and arbitrary maps, but this is only documentation.
lib/presentation/schedule_create/bloc/schedule_form_bloc.dart manually builds schedule_created with string keys and runtime-derived values instead of using a typed event factory.
- Existing tests assert one happy-path
schedule_created event but not catalog enforcement.
Proposed direction
Introduce a typed analytics event catalog in code and route Product Usage Event construction through it. Prefer event-specific factories or sealed/enum-backed definitions for known event names, workflows, results, and allowed parameter keys.
Put validation in TrackProductUsageEventUseCase or a dedicated catalog validator before the Firebase service seam, so feature BLoCs cannot accidentally emit undocumented parameters or forbidden data.
Acceptance criteria
ProductUsageEvent can no longer be created with arbitrary event names, workflow/result strings, or free-form parameter keys without passing catalog validation.
schedule_created is built through a typed factory/helper that owns preparation_mode, preparation_step_count, and minutes_until_schedule.
- Unknown event names, non-allowlisted parameters, arbitrary nested maps, and forbidden sensitive fields are rejected or stripped before reaching
ProductAnalyticsService.
- The docs catalog and in-code catalog are kept in sync through tests or a single source of truth.
- Unit tests cover valid
schedule_created, unknown event rejection, unknown parameter rejection, forbidden field rejection, and the existing disabled-collection path.
Source: Codex codebase audit on 2026-06-28.
Problem
ProductUsageEventis currently string/Mapbased, so event names, workflow/result values, and parameters are not tied to the documented analytics catalog. That leaves privacy-sensitive analytics rules dependent on manual discipline at each call site.Evidence
lib/domain/entities/product_usage_event.dartdefinesname,workflow, andresultas rawStrings andparametersasMap<String, Object>, then spreads the map into Firebase parameters.lib/core/services/product_analytics_service.dartonly gates collection and forwardsevent.nameplusevent.toAnalyticsParameters(...); it does not validate the event against the catalog.lib/domain/use-cases/track_product_usage_event_use_case.dartcatches tracking failures but does not reject unknown events, unknown parameters, forbidden fields, or invalid value categories.docs/Analytics-Event-Catalog.mdsays optional parameters must be allowlisted per event and forbids identifiers, user-authored content, raw exceptions, and arbitrary maps, but this is only documentation.lib/presentation/schedule_create/bloc/schedule_form_bloc.dartmanually buildsschedule_createdwith string keys and runtime-derived values instead of using a typed event factory.schedule_createdevent but not catalog enforcement.Proposed direction
Introduce a typed analytics event catalog in code and route Product Usage Event construction through it. Prefer event-specific factories or sealed/enum-backed definitions for known event names, workflows, results, and allowed parameter keys.
Put validation in
TrackProductUsageEventUseCaseor a dedicated catalog validator before the Firebase service seam, so feature BLoCs cannot accidentally emit undocumented parameters or forbidden data.Acceptance criteria
ProductUsageEventcan no longer be created with arbitrary event names, workflow/result strings, or free-form parameter keys without passing catalog validation.schedule_createdis built through a typed factory/helper that ownspreparation_mode,preparation_step_count, andminutes_until_schedule.ProductAnalyticsService.schedule_created, unknown event rejection, unknown parameter rejection, forbidden field rejection, and the existing disabled-collection path.Source: Codex codebase audit on 2026-06-28.