Merged
Conversation
Implement multi-tenancy support to scope projects by organization: - Add tenant_id field to Project model (default: "taskflow") - Create get_tenant_id() function with JWT → header → default priority - Update all 5 project endpoints with tenant filtering - Per-tenant slug uniqueness (same slug allowed across tenants) - Return 404 for cross-tenant access (prevents enumeration) - Include tenant_id in all audit log entries Tests: 5 new tests, 61 total passing Files modified: - models/project.py: Added tenant_id field - auth.py: Added get_tenant_id(), updated CurrentUser - schemas/project.py: Added tenant_id to ProjectRead - routers/projects.py: Tenant filtering on all endpoints - tests/test_multitenancy.py: New comprehensive test suite Specs: specs/009-multi-tenancy/ (spec.md, plan.md, tasks.md) PHRs: history/prompts/multi-tenancy/ (4 records) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive documentation explaining: - Tenant = namespace (which projects exist) - Membership = access (which projects you can use) - Principle of least privilege: same-org users don't auto-see all projects - User workflow: create own projects, get invited to others - Access matrix for all scenarios 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes: - Rename default tenant from "taskflow" to "taskflow-default-org-id" - Fix ensure_default_project to explicitly set tenant_id from user context - Fix slug collision check to be per-tenant (not global) - Pass request to ensure_user_setup for proper tenant extraction - Update spec and tests for new default tenant name Bug fixes: - Default project was not setting tenant_id explicitly (relied on model default) - Slug collision check was global, should be per-tenant 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implement #20
After review, multi-tenancy is much simpler than originally scoped:
Changes Required (API only - 4 files)
models/project.pytenant_id: str = Field(index=True)schemas/project.pytenant_idto create/read schemasauth.pytenant_idfrom JWT OR use default"taskflow"routers/projects.py.where(Project.tenant_id == tenant_id)to all queriesWhy Other Components Don't Need Changes
project_id→ inherit tenant boundarySimplified Strategy
Use a default tenant (
"taskflow") for all users initially. This avoids SSO changes and org-switching complexity.Estimated Time: 30-45 minutes