Skip to content

feat(rls): Phase 1 #8 — HeartbeatContext RLS + callsite fixes#136

Merged
webdevcom01-cell merged 1 commit into
mainfrom
feat/rls-phase1-heartbeatcontext
May 24, 2026
Merged

feat(rls): Phase 1 #8 — HeartbeatContext RLS + callsite fixes#136
webdevcom01-cell merged 1 commit into
mainfrom
feat/rls-phase1-heartbeatcontext

Conversation

@webdevcom01-cell
Copy link
Copy Markdown
Owner

Summary

  • Migration 20260602000000_rls_phase1_heartbeatcontext: TENANT_DIRECT RLS on HeartbeatContext (SELECT/INSERT/UPDATE/DELETE policies + composite organizationId, id index)
  • Hot path batch optimization (context-manager.ts): new processContextForRun(agentId, organizationId) combines prune-expired + read-active + build-prompt into one withOrgContext transaction — 1 SET call instead of 3. Required because this table has the highest write frequency of any Phase 1 table (one upsert per heartbeat cycle per agent)
  • BullMQ worker (heartbeat-worker.ts): replaces the three separate pruneContext / getContext / buildContextPrompt calls with processContextForRun(agentId, organizationId) using explicit organizationId from job.data — ALS is empty in BullMQ workers
  • Individual functions (getContext, setContext, deleteContext, pruneContext, buildContextPrompt): all gain organizationId param and wrap their queries in withOrgContext — used by route callsites
  • Route (/api/agents/[agentId]/heartbeat/context): GET and DELETE fetch organizationId via agent lookup; POST is unchanged (setContext handles it internally via body's organizationId)

ALS context per callsite

Callsite Org ID source Treatment
context/route.ts GET agent lookup passed to getContext
context/route.ts POST body (organizationId) setContext wraps internally
context/route.ts DELETE agent lookup withOrgContext direct
heartbeat-worker.ts job.data.organizationId processContextForRun (batch)

Test plan

  • pnpm precheck — 4/4 pass (TypeScript, vitest 4119 tests, lucide mocks, ESLint) ✅
  • CI green
  • E2E: existing JWTSessionError flake is pre-existing — ignore
  • After merge: apply migration to Railway prod DB
  • Flag-on smoke: trigger a heartbeat job — confirm no 42501 on prune/get/build path; confirm context rows visible in GET /api/agents/:id/heartbeat/context

RLS state after this PR

Phase 1: 8/14 live — OrganizationMember, Invitation, CompanyMission, Department, Goal, AgentPermissionGrant, HeartbeatConfig, HeartbeatContext

🤖 Generated with Claude Code

Migration 20260602000000: TENANT_DIRECT RLS on HeartbeatContext.
Hot path: processContextForRun() batches prune+get+buildPrompt into one
withOrgContext transaction (1 SET instead of 3) for the BullMQ worker.
Worker uses explicit organizationId from job.data (ALS empty in workers).
Individual functions updated with organizationId param for route callsites.
@webdevcom01-cell webdevcom01-cell added the e2e Run E2E tests on this PR label May 24, 2026
@webdevcom01-cell webdevcom01-cell merged commit 7220ca6 into main May 24, 2026
6 of 12 checks passed
@webdevcom01-cell webdevcom01-cell deleted the feat/rls-phase1-heartbeatcontext branch May 24, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e2e Run E2E tests on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant