Skip to main content
← Back to list
01Issue
FeatureOpenSwamp Club
AssigneesNone

Refactor: move telemetry track() calls from route handlers to application services

Opened by stack72 · 4/9/2026· GitHub #254

Context

From the DDD analysis of #253 (comment).

Problem

Telemetry track() calls live in route handlers — the HTTP adapter layer. This is consistent across the codebase (confirm.ts, [...path].ts, _middleware.ts, lib/auth.ts), but from a DDD standpoint the application service is the more principled location.

Route handlers are HTTP adapters. Application services represent use cases. "After successfully creating a collective, record that it happened" is part of the use case, not part of HTTP adaptation.

Concrete risks of the current pattern

  • If a use case is ever invoked from a non-HTTP path (background job, CLI tool, service-to-service call), route-level telemetry gets silently skipped.
  • Telemetry for the same domain operation is scattered across route files rather than co-located with the use case logic.
  • Some telemetry requires pre-command lookups (e.g., findMemberById before member removal to capture data that won't exist after deletion). In app services, this data is often already available as part of the orchestration flow.

Current state

Today each app service is called from exactly one route, so the practical risk is zero. This is a code organization improvement, not a bug fix.

Proposal

Move track() calls from route handlers into application services (or have app services return enough context for a thin telemetry call at the boundary). This would:

  1. Co-locate telemetry with the use case it observes
  2. Eliminate pre-command lookups that exist solely for telemetry enrichment
  3. Ensure telemetry fires regardless of how the use case is invoked

Scope

  • lib/app/collective-commands.ts — all collective lifecycle events (#253)
  • routes/api/v1/extensions/confirm.tsextension_published
  • routes/api/v1/extensions/[...path].tsextension_pulled
  • lib/auth.ts — auth events (these are already in BetterAuth hooks, which is analogous to app-service-level placement)

Open question

Should app services call track() directly, or emit structured data that the caller dispatches? Direct calls are simpler; structured data keeps the app layer free of infrastructure imports. Could also be addressed by #255 (domain events).

  • #253 — Collective lifecycle telemetry (implements the route-level pattern)
  • #255 — Domain events infrastructure
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

4/9/2026, 4:44:12 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.