-
-
Notifications
You must be signed in to change notification settings - Fork 302
M:M User and Group Relationship #1174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Introduced `default_group_id` field in the User model to manage user group defaults. - Updated user creation and update logic to utilize the new default group ID. - Implemented a many-to-many relationship between users and groups via a new `user_groups` junction table. - Refactored relevant queries and middleware to support tenant-based access using the default group.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying homebox-docs with
|
| Latest commit: |
24a49dd
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6e78f314.homebox-docs.pages.dev |
| Branch Preview URL: | https://mk-multi-groups.homebox-docs.pages.dev |
# Conflicts: # backend/internal/data/repo/repo_items_test.go
frontend/stores/collection.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure about having this be a store, might be better not to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure on this one either, I'm no vue expert.
| > | ||
| <Command :ignore-filter="true"> | ||
| <CommandGroup> | ||
| <CommandItem as-child value="collection-settings"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
settings should prob be below create and join
What type of PR is this?
What this PR does / why we need it:
Summary
This migration converts the User-Group relationship from 1:M (one group per user) to M:M (users can belong to multiple groups) while introducing multi-tenant support via the
X-Tenantheader.Schema Changes
1. User Entity (
backend/internal/data/ent/schema/user.go)Removed:
GroupMixin{ref: "users"}from Mixin sliceAdded:
default_group_idfield (UUID, optional, nullable) - tracks user's primary tenantedge.To("groups", Group.Type)2. Group Entity (
backend/internal/data/ent/schema/group.go)Changed:
owned("users", User.Type)edge.To("users", User.Type)Database Migrations
SQLite3 Migration (
20251226000000_user_group_m2m.sql)user_groupswith composite primary keygroup_usersvalues to junction tabledefault_group_idto users tabledefault_group_idfrom current groupgroup_usersforeign key columnRollback:
group_usersforeign keydefault_group_idas fallbackPostgreSQL Migration (
20251226000000_user_group_m2m.sql)Equivalent migration with PostgreSQL-specific syntax:
CASCADEandNO ACTIONfor FK constraintsusers_groups_usersSET NULLCode Changes
1. Repository Layer (
backend/internal/data/repo/repo_users.go)UserCreate struct:
UserOut struct:
Query updates:
GetOneID():.WithGroups()instead of.WithGroup()GetOneEmail():.WithGroups()instead of.WithGroup()GetAll():.WithGroups()instead of.WithGroup()GetOneOIDC():.WithGroups()instead of.WithGroup()Create methods:
SetDefaultGroupID(usr.DefaultGroupID)instead ofSetGroupID().AddGroupIDs(usr.DefaultGroupID)2. Services Layer
service_user.go:
DefaultGroupIDinstead ofGroupIDDefaultGroupIDfor creating default labels/locationsservice_group.go:
3. Context Management (
backend/internal/core/services/contexts.go)Context struct:
New functions:
UseTenantCtx(ctx)- retrieves active tenant from contextSetTenantCtx(ctx, tenantID)- sets active tenant in contextContextTenant- context key for tenant4. Middleware (
backend/app/api/middleware.go)New mwTenant middleware:
X-Tenantheader (optional)DefaultGroupIDif header not providedRoute integration:
5. API Handlers
Updated references from
GroupID/GroupNametoDefaultGroupID:v1_ctrl_items.go: CSV importv1_ctrl_reporting.go: Bill of materials exportdemo.go: Demo setup CSV importUsage
Default Behavior (No X-Tenant Header)
All requests use the user's
DefaultGroupIDas the active tenant.curl -H "Authorization: Bearer TOKEN" \ https://api.example.com/api/v1/groups/statisticsMulti-Tenant Requests (With X-Tenant Header)
Explicitly switch to a different tenant group.
Response codes:
400- Invalid X-Tenant UUID format403- User not member of requested tenant200- Success (tenant switched)Backward Compatibility
✅ Existing clients continue working without modification:
X-Tenantheader automatically use user'sDefaultGroupIDTesting Recommendations
Migration Safety:
Multi-Tenant Features:
Backward Compatibility:
Default Group:
Generated Code
After running
go generate ./...inbackend/internal/data:DefaultGroupIDfieldAddGroupIDs(),QueryGroups(), etc.AddUserIDs(),QueryUsers(), etc.Which issue(s) this PR fixes:
Implements part of #760
Special notes for your reviewer:
Still working on this.
Testing
Will need to validate tenant switching works properly, users can't force a tenant they don't belong to, etc.