feat(tenancy): implement multi tenancy#3
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13daec3b2f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| orgId, | ||
| orgRole, | ||
| orgPermissions, | ||
| orgPlan: normalizeOrganizationBillingPlan(orgPlanClaim), |
There was a problem hiding this comment.
Require org plan claim for Convex entitlement checks
requireOrganizationContext silently normalizes a missing plan claim to free, so any deployment where the Convex JWT template only includes org id/role/permissions will under-entitle paid organizations in Convex logic. That causes Organizations workspaces to be treated as free for limits in convex/files.ts and convex/chat.ts even when Clerk billing is configured, which is a production-facing quota regression; this should fail fast when the plan claim is absent (or resolve the plan from a trusted source) instead of defaulting silently.
Useful? React with 👍 / 👎.
| const { isLoaded, orgId } = useAuth(); | ||
| const hasOrganizationContext = isLoaded && Boolean(orgId); | ||
|
|
||
| useSyncUser(hasOrganizationContext); |
There was a problem hiding this comment.
Keep user sync active before org context is selected
Gating useSyncUser on hasOrganizationContext introduces a race in first-time onboarding: after selecting/creating an organization, onboarding mutations can run before the background user sync creates the Convex users document, which makes updateOnboardingStep/completeOnboarding fail with User not found. This is user-visible on slower networks and should be avoided by syncing as soon as auth is loaded (or by creating the user record inside onboarding mutations).
Useful? React with 👍 / 👎.
This pull request introduces multi-tenancy support for Shipr, enabling organization-scoped data isolation and plan-based limits for chat and file features. The changes refactor the backend to enforce tenant boundaries, update rate limits and quotas based on organization plans, and add role-based access control. The
.env.exampleand backend logic are updated to support configurable limits for free and organization plans.Multi-tenancy and organization-scoped data isolation:
convex/chat.tsandconvex/files.tsto enforce organization boundaries for chat threads, messages, and files, replacing user-centric ownership checks with organization-centric checks (requireOrganizationThread,requireOrganizationFile). All relevant queries and mutations now operate within the active organization context. [1] [2]requireOrgPermission) for chat and file operations, ensuring only authorized users can perform actions based on their organization role. [1] [2]Plan-based configurable limits and quotas:
.env.exampleto define separate rate limits and quotas for free and organization plans, covering chat message/thread limits, file size/count limits, and image upload rate limits. [1] [2]getChatHistoryLimitsForPlanandgetFileStorageLimitsForPlan. [1] [2]API and identifier changes:
listOrganizationChatThreads,getOrganizationFiles), and updated data models to useorgIdandcreatedByUserIdinstead ofuserId. [1] [2]Documentation and guidance:
README.mdto describe the multi-tenant variant, including tenant boundaries, backend isolation, billing scope, and deployment guidance. Added references to/docs/multi-tenancy.mdfor further details.Security and validation improvements: