Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-42Done

1.3.6 Project isolation E2E + direct-DB RLS test

Estimate: 16m · Depends on: 1.3.2, 1.3.4

The Story-closing test that proves project-level multi-tenancy is structural, mirroring 1.2.7's two-layer approach. (1) E2E (Playwright, @smoke): user A in workspace A cannot see or act on workspace B's projects — switching the active workspace shows only that workspace's projects, and any project-scoped Server Action / endpoint operating on a foreign project is refused (cross-tenant returns 404, not 403, per the Story AC and 1.2.7's anti-enumeration rule). (2) Direct-DB (Vitest, SET LOCAL ROLE prodect_app): a transaction without the app.workspace_id GUC sees zero project rows; with workspace A's GUC sees only A's projects; cross-workspace UPDATE affects zero rows; INSERT for a non-matching workspace is denied.

Reuse, don't reinvent: the E2E helpers (db-reset, email-capture), the signUp helper, and the rate-limit env-gate (E2E_DISABLE_RATE_LIMIT, already on main per finding #9) from 1.2.6/1.2.7. The RLS test reuses the SET LOCAL ROLE prodect_app harness from tests/multi-tenant-rls.test.ts.

Acceptance criteria

  • tests/e2e/project-isolation.spec.ts (@smoke): the project switcher shows only the active workspace's projects; a cross-tenant project-scoped action returns 404 (not 403, not 200). Passes locally + CI, no flakes (verify with --repeat-each).
  • tests/project-rls.test.ts: no-GUC → zero project rows; workspace-A GUC → only A's projects; cross-workspace UPDATE → 0 rows; cross-workspace INSERT → RLS denial (42501) — all under prodect_app.
  • Cascade re-verified: deleting a workspace removes its projects (and their future work items by extension).
  • All quality gates green; prior suites stay green.

Context refs

  • tests/e2e/multi-tenant-isolation.spec.ts + tests/multi-tenant-rls.test.ts from 1.2.7 — the exact two-layer patterns to mirror
  • tests/e2e/_helpers/{db-reset,email-capture}.ts + tests/e2e/workspace-flows.spec.ts's signUp helper
  • playwright.config.ts — the E2E_DISABLE_RATE_LIMIT env-gate (finding #9)
  • PRODECT_FINDINGS.md #5 (RLS inert under superuser) — why the role switch is mandatory