Skip to content

Conversation

@roncodes
Copy link
Member

@roncodes roncodes commented Feb 9, 2026

Overview

This PR adds analytics-agnostic event tracking to core Fleetbase services using the universe service's built-in Evented system. Events are emitted using dot notation naming convention and can be consumed by any analytics provider (e.g., PostHog in the internals engine).

Changes

CRUD Service (addon/services/crud.js)

  • Added universe service injection
  • Added _triggerResourceEvent() helper method to emit both generic and specific events
  • Emit resource.deleted and {model_name}.deleted events after successful deletion
  • Emit resource.bulk_action event for bulk operations
  • Emit resource.imported and {model_name}.imported events after successful import

Resource Action Service (addon/services/resource-action.js)

  • Added universe service injection
  • Added _triggerResourceEvent() helper method
  • Emit resource.created and {model_name}.created events in createTask
  • Emit resource.updated and {model_name}.updated events in updateTask
  • Emit appropriate events in saveTask based on whether record is new or existing
  • Emit resource.deleted and {model_name}.deleted events in deleteTask

Session Service (addon/services/session.js)

  • Added universe service injection
  • Added sessionStartTime tracked property for duration calculation
  • Emit session.initialized event when user session is loaded
  • Emit session.terminated event with session duration when user logs out

Event Naming Convention

All events use dot notation following existing Fleetbase patterns:

  • Generic events: resource.{action} (e.g., resource.created, resource.updated, resource.deleted)
  • Specific events: {model_name}.{action} (e.g., order.created, vehicle.updated, driver.deleted)
  • Session events: session.{action} (e.g., session.initialized, session.terminated)

Event Payloads

Event Payload
resource.created (model)
resource.updated (model)
resource.deleted (model)
resource.imported (modelName, response, files)
resource.bulk_action (verb, selected, firstModel)
session.initialized (user, organization)
session.terminated (user, sessionDuration)

Usage Example

In the internals engine (or any other consumer), subscribe to these events:

// In an initializer
const universe = appInstance.lookup('service:universe');
const posthog = appInstance.lookup('service:posthog');

// Listen for generic resource creation
universe.on('resource.created', (model) => {
  const modelName = getModelName(model);
  posthog.trackEvent(`${modelName}_created`, { id: model.id });
});

// Listen for specific order creation
universe.on('order.created', (order) => {
  posthog.trackEvent('order_created', {
    order_id: order.id,
    // ... other properties
  });
});

// Listen for session events
universe.on('session.initialized', (user, organization) => {
  posthog.identify(user.id, {
    email: user.email,
    company: organization.name
  });
});

Benefits

Analytics-agnostic: No PostHog or analytics-specific code in core
Non-breaking: Events are optional, existing functionality unchanged
Extensible: Can be used for webhooks, audit logs, or any analytics provider
Consistent naming: Follows existing Fleetbase dot notation convention
Dual events: Both generic (resource.created) and specific (order.created) events for flexibility

Testing

Tested locally by:

  1. Subscribing to events in console
  2. Verifying events fire on CRUD operations
  3. Confirming both generic and specific events are emitted
  4. Validating session events fire on login/logout

Next Steps

  • Add similar events to ember-ui components (buttons, modals, forms)
  • Implement analytics listener in internals engine
  • Add router transition events

Manus AI added 2 commits February 8, 2026 21:13
- Add analytics event triggering to crud service (delete, bulk actions, import)
- Add analytics event triggering to resource-action service (create, update, delete)
- Add session analytics events (initialized, terminated with duration)
- Emit both generic (resource.created) and specific (order.created) events
- Use dot notation naming convention for all events
- Non-breaking changes, events are optional and don't affect existing functionality
- Add resource.exported and {model}.exported events to crud service export method
- Remove incorrect session tracking from session service (was in wrong place)
- Session events should be tracked via current-user service's existing 'user.loaded' event
- Current-user service already extends Evented and triggers 'user.loaded' on lines 72 and 99

The current-user service is the proper place for user/session lifecycle events since it:
1. Already extends Evented mixin
2. Already triggers 'user.loaded' event when user is authenticated
3. Is called by session.loadCurrentUser() and session.promiseCurrentUser()
4. Has access to user and organization data

For logout/session termination tracking, consumers should subscribe to ember-simple-auth's
'invalidationSucceeded' event or add a 'user.logout' event to current-user service.
@roncodes roncodes changed the base branch from main to dev-v0.3.11 February 10, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant