Skip to content

feat(rls): Phase 1 #3 — CompanyMission RLS + callsite fixes#131

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

feat(rls): Phase 1 #3 — CompanyMission RLS + callsite fixes#131
webdevcom01-cell merged 1 commit into
mainfrom
feat/rls-phase1-companymission

Conversation

@webdevcom01-cell
Copy link
Copy Markdown
Owner

Summary

  • Migration 20260528000000_rls_phase1_companymission: enables RLS + FORCE on CompanyMission, adds composite index on (organizationId, id), SELECT/INSERT/UPDATE/DELETE policies for app_user, grants to app_user + admin_user
  • Wraps prisma.companyMission.findUnique in GET /api/mission with withOrgContext
  • Wraps prisma.companyMission.upsert in POST/PUT /api/mission with withOrgContext
  • Wraps getMissionForOrg() in src/lib/goals/goal-context.ts with withOrgContext (explicit organizationId required — function is called from BullMQ/heartbeat workers where ALS is empty; withTenant() would break there)

RLS_ENFORCEMENT_ENABLED=false — all withOrgContext wrapping is a no-op until the flag is flipped after all 14 migrations land.

Callsite audit

Grep verified: exactly 3 callsites for companyMission. outside generated code. No workers or crons call prisma.companyMission directly.

Test plan

  • pnpm precheck — TS ✅ vitest ✅ ESLint ✅ (4119 tests, 307 files)
  • CI green on this PR
  • DB smoke test (post-merge): SELECT COUNT(*) FROM "CompanyMission" as app_user without app.current_org_id set — must return 0 rows
  • DB smoke test: set app.current_org_id to a valid org ID — must return that org's mission only
  • Verify GET /api/mission?orgId=<id> and POST /api/mission still work with flag off

🤖 Generated with Claude Code

- Migration 20260528000000: enable RLS + FORCE on CompanyMission,
  composite index on (organizationId, id), SELECT/INSERT/UPDATE/DELETE
  policies for app_user, grants to app_user + admin_user
- Wrap prisma.companyMission.findUnique in GET /api/mission with withOrgContext
- Wrap prisma.companyMission.upsert in POST/PUT /api/mission with withOrgContext
- Wrap getMissionForOrg() in goal-context.ts with withOrgContext (explicit
  orgId required — called from BullMQ/heartbeat workers where ALS is empty)

RLS_ENFORCEMENT_ENABLED=false; wrapping is a no-op until flag flip.
@webdevcom01-cell webdevcom01-cell added the e2e Run E2E tests on this PR label May 23, 2026
@webdevcom01-cell webdevcom01-cell merged commit 254a256 into main May 23, 2026
6 of 12 checks passed
@webdevcom01-cell webdevcom01-cell deleted the feat/rls-phase1-companymission branch May 23, 2026 21:14
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