diff --git a/management/server/store/sql_store.go b/management/server/store/sql_store.go index c785cf6b7..6b560f395 100644 --- a/management/server/store/sql_store.go +++ b/management/server/store/sql_store.go @@ -204,13 +204,30 @@ func (s *SqlStore) SaveAccount(ctx context.Context, account *types.Account) erro return result.Error } + // Save account without UsersG.Groups to avoid FK constraint violations + // (groups must exist before group_users can reference them) result = tx. Session(&gorm.Session{FullSaveAssociations: true}). + Omit("UsersG.Groups"). Clauses(clause.OnConflict{UpdateAll: true}). Create(account) if result.Error != nil { return result.Error } + + // Now save the user-group associations after both users and groups exist + for _, user := range account.UsersG { + if len(user.Groups) > 0 { + result = tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "group_id"}, {Name: "user_id"}}, + UpdateAll: true, + }).Create(&user.Groups) + if result.Error != nil { + return result.Error + } + } + } + return nil }) if err != nil { diff --git a/management/server/store/sql_store_test.go b/management/server/store/sql_store_test.go index 97aa81b12..2085f33ef 100644 --- a/management/server/store/sql_store_test.go +++ b/management/server/store/sql_store_test.go @@ -1365,6 +1365,7 @@ func TestSqlStore_CreateGroup(t *testing.T) { Peers: []string{}, Resources: []types.Resource{}, GroupPeers: []types.GroupPeer{}, + GroupUsers: []types.GroupUser{}, } err = store.CreateGroup(context.Background(), group) require.NoError(t, err) @@ -1389,6 +1390,7 @@ func TestSqlStore_CreateUpdateGroups(t *testing.T) { Peers: []string{}, Resources: []types.Resource{}, GroupPeers: []types.GroupPeer{}, + GroupUsers: []types.GroupUser{}, }, { ID: "group-2", @@ -1397,6 +1399,7 @@ func TestSqlStore_CreateUpdateGroups(t *testing.T) { Peers: []string{}, Resources: []types.Resource{}, GroupPeers: []types.GroupPeer{}, + GroupUsers: []types.GroupUser{}, }, } err = store.CreateGroups(context.Background(), accountID, groups) diff --git a/management/server/store/sqlstore_bench_test.go b/management/server/store/sqlstore_bench_test.go index 2284218ad..ea3f0d264 100644 --- a/management/server/store/sqlstore_bench_test.go +++ b/management/server/store/sqlstore_bench_test.go @@ -82,6 +82,7 @@ func (s *SqlStore) GetAccountSlow(ctx context.Context, accountID string) (*types for _, pat := range user.PATsG { user.PATs[pat.ID] = pat.Copy() } + user.LoadAutoGroups() account.Users[user.Id] = user.Copy() } account.UsersG = nil @@ -177,6 +178,7 @@ func (s *SqlStore) GetAccountGormOpt(ctx context.Context, accountID string) (*ty } if user.AutoGroups == nil { user.AutoGroups = []string{} + user.Groups = []*types.GroupUser{} } account.Users[user.Id] = user user.PATsG = nil