Fas 1a: analytics tracker, ingestion endpoint, admin dashboards
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Typed event builders for the product analytics taxonomy.
|
||||
* Each builder returns a plain AnalyticsEvent ready for batching.
|
||||
*/
|
||||
import type { ProductAnalyticsEventName } from "@app/shared-types";
|
||||
import type { AnalyticsEvent } from "./types.js";
|
||||
|
||||
function builder(name: ProductAnalyticsEventName) {
|
||||
return (props?: {
|
||||
occurredAt?: string;
|
||||
anonymousId?: string;
|
||||
sessionId?: string;
|
||||
householdId?: string;
|
||||
appVersion?: string;
|
||||
platform?: "ios" | "android" | "web";
|
||||
locale?: string;
|
||||
experimentVariant?: string;
|
||||
properties?: Record<string, unknown>;
|
||||
}): AnalyticsEvent => ({ name, ...props });
|
||||
}
|
||||
|
||||
// Acquisition & onboarding
|
||||
export const appInstalled = builder("app_installed");
|
||||
export const appFirstOpen = builder("app_first_open");
|
||||
export const onboardingStarted = builder("onboarding_started");
|
||||
export const onboardingStepCompleted = builder("onboarding_step_completed");
|
||||
export const onboardingSkipped = builder("onboarding_skipped");
|
||||
export const accountCreated = builder("account_created");
|
||||
export const householdCreated = builder("household_created");
|
||||
export const householdJoined = builder("household_joined");
|
||||
export const allergySetupCompleted = builder("allergy_setup_completed");
|
||||
export const cameraPermissionResult = builder("camera_permission_result");
|
||||
export const notificationPermissionResult = builder("notification_permission_result");
|
||||
|
||||
// Inventory
|
||||
export const scanStarted = builder("scan_started");
|
||||
export const scanUploaded = builder("scan_uploaded");
|
||||
export const scanProcessingCompleted = builder("scan_processing_completed");
|
||||
export const scanProcessingFailed = builder("scan_processing_failed");
|
||||
export const scanReviewOpened = builder("scan_review_opened");
|
||||
export const scanItemConfirmed = builder("scan_item_confirmed");
|
||||
export const scanItemCorrected = builder("scan_item_corrected");
|
||||
export const scanItemRemoved = builder("scan_item_removed");
|
||||
export const scanCompleted = builder("scan_completed");
|
||||
export const inventoryItemAdded = builder("inventory_item_added");
|
||||
export const inventoryItemConsumed = builder("inventory_item_consumed");
|
||||
export const inventoryItemDiscarded = builder("inventory_item_discarded");
|
||||
export const inventoryReconciliationStarted = builder("inventory_reconciliation_started");
|
||||
export const inventoryReconciliationCompleted = builder("inventory_reconciliation_completed");
|
||||
export const inventoryConflictCreated = builder("inventory_conflict_created");
|
||||
export const inventoryConflictResolved = builder("inventory_conflict_resolved");
|
||||
|
||||
// Recipes & cooking
|
||||
export const recommendationsViewed = builder("recommendations_viewed");
|
||||
export const recommendationOpened = builder("recommendation_opened");
|
||||
export const recipeSaved = builder("recipe_saved");
|
||||
export const cookingSessionStarted = builder("cooking_session_started");
|
||||
export const cookingSessionCompleted = builder("cooking_session_completed");
|
||||
export const cookingSessionCancelled = builder("cooking_session_cancelled");
|
||||
export const leftoversCreated = builder("leftovers_created");
|
||||
export const substitutionConfirmed = builder("substitution_confirmed");
|
||||
|
||||
// Shopping
|
||||
export const shoppingItemAdded = builder("shopping_item_added");
|
||||
export const shoppingItemChecked = builder("shopping_item_checked");
|
||||
export const shoppingListShared = builder("shopping_list_shared");
|
||||
export const receiptScanned = builder("receipt_scanned");
|
||||
export const purchaseImported = builder("purchase_imported");
|
||||
|
||||
// Household
|
||||
export const householdInviteSent = builder("household_invite_sent");
|
||||
export const householdInviteAccepted = builder("household_invite_accepted");
|
||||
export const secondMemberFirstAction = builder("second_member_first_action");
|
||||
|
||||
// Subscription
|
||||
export const paywallViewed = builder("paywall_viewed");
|
||||
export const trialStarted = builder("trial_started");
|
||||
export const trialCancelled = builder("trial_cancelled");
|
||||
export const subscriptionStarted = builder("subscription_started");
|
||||
export const subscriptionRenewed = builder("subscription_renewed");
|
||||
export const subscriptionGracePeriod = builder("subscription_grace_period");
|
||||
export const subscriptionCancelled = builder("subscription_cancelled");
|
||||
export const subscriptionExpired = builder("subscription_expired");
|
||||
export const entitlementRestored = builder("entitlement_restored");
|
||||
|
||||
// Feedback
|
||||
export const feedbackSubmitted = builder("feedback_submitted");
|
||||
export const incorrectInventoryReported = builder("incorrect_inventory_reported");
|
||||
export const badRecommendationReported = builder("bad_recommendation_reported");
|
||||
export const supportContactStarted = builder("support_contact_started");
|
||||
Reference in New Issue
Block a user