Skip to main content

Endpoint Flow

How a request travels from frontend to backend. Two flavors: persistence calls (Firebase Functions, sync) and chat calls (Cloud Run, streaming SSE).

Persistence calls (Firebase Functions)

Example: a manager creates a scheduled report.

Key files:

  • Router mount: functions/modules/ai-memory/endpoints/apis/router.ts
  • Sub-router: functions/modules/ai-memory/endpoints/apis/ai-memory.router.ts
  • Auth middleware: functions/shared/middleware/auth.middleware.ts
  • Company scope: functions/shared/middleware/company-scope.middleware.ts
  • Request context: functions/shared/infrastructure/request-context-from-token.ts

Notable: the RTDB write always commits; the Temporal call is best-effort. The handler returns temporalScheduled: false plus temporalError if Temporal was unreachable, but the task is still persisted. See MIA Task Lifecycle for reconciliation.

Chat calls (Cloud Run, streaming SSE)

Example: a user asks Mia "what was labor cost last week?"

Key files:

  • Entrypoint: functions/pivotAiAgent/index.ts (chatHandler, mounted at /api/chat + /api/chat-async)
  • Intent: functions/pivotAiAgent/intent.ts
  • Tool loop: functions/pivotAiAgent/pipeline.ts
  • Dispatcher: functions/pivotAiAgent/tools/index.ts:192 (executeTool)
  • URL builder: functions/pivotAiAgent/tools/_endpoints.ts (getFunctionsUrl, authHeaders)
  • Workflows: functions/pivotAiAgent/temporal/workflows.ts

Streaming protocol: SSE with Anthropic's content-block delta shape interleaved with custom event types — see Agent SDK: Streaming.

Exceptions to "tool → internal endpoint"

Two categories, only one of which is intentional:

Intentional — external API calls:

  • web_search, get_weather, lookup_pivot_help hit public third-party APIs (Brave, Open-Meteo, KB). No Pivot auth.

Tech debt — Admin-SDK fallbacks for RTDB paths without an endpoint:

  • create_shift writes WeeklySchedule/{cid}/{date} via Firebase REST ?auth=. Schedule module has no "create published shift" endpoint yet. File carries a TODO(refacto-endpoint) comment.
  • Onboarding tools (create_company, complete_onboarding, etc.) use endpoints for everything that has one (company create, patch, employee create); they only fall back to Admin SDK for onboarding-specific paths that aren't on the public API — AIOnboardingSessions/, Users/{uid}/signupPhase, Companies/{cid}/businessProfile, etc. The createCompany.ts source comment makes this explicit.

See Agent SDK: exceptions for the full breakdown.

A fetch interceptor in functions/pivotAiAgent/firebase.ts patches globalThis.fetch so RTDB-hostname URLs automatically use the Admin SDK when service-account credentials are present — this makes the stopgap Admin-SDK writes work transparently without explicit branching in each tool.

Why two runtimes?

Firebase Functions has a 9-minute execution ceiling and no native streaming. The data path can run 5–30 seconds and the chat path is SSE-streamed — both incompatible. Cloud Run gives us streaming + longer execution; Firebase Functions stays the right tool for short CRUD over RTDB.