From badc2543eaa319657ecc97453fbdca58679ecb87 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 30 Apr 2026 23:26:09 +0300 Subject: fix: permissions matrix UI now returns proper shape from backend The frontend admin.js expects {sets, users, permissions} but ListPermissions returned a flat []SetPermission slice. - Add PermissionsMatrix struct with JSON tags - Update AdminService.ListPermissions to return *PermissionsMatrix - Update mocks and all call sites to match new signature - Update tests to assert the new matrix shape --- internal/api/handlers_more_test.go | 2 +- internal/api/handlers_test.go | 2 +- internal/service/admin.go | 13 +++++++++++-- internal/service/admin_test.go | 7 +++++-- internal/service/mock.go | 4 ++-- internal/service/mock_test.go | 2 +- internal/service/service.go | 9 ++++++++- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/internal/api/handlers_more_test.go b/internal/api/handlers_more_test.go index 13c57cf..b162fa8 100644 --- a/internal/api/handlers_more_test.go +++ b/internal/api/handlers_more_test.go @@ -1583,7 +1583,7 @@ func TestServer_AdminListPermissions(t *testing.T) { var as service.AdminService if !tt.svcNil { as = &service.MockAdminService{ - ListPermissionsFunc: func(ctx context.Context) ([]model.SetPermission, error) { return nil, tt.svcErr }, + ListPermissionsFunc: func(ctx context.Context) (*service.PermissionsMatrix, error) { return nil, tt.svcErr }, } } srv := newTestServer(t, store, nil, sm, cfg, nil, as, nil, nil) diff --git a/internal/api/handlers_test.go b/internal/api/handlers_test.go index e65b854..b5ca9c7 100644 --- a/internal/api/handlers_test.go +++ b/internal/api/handlers_test.go @@ -1148,7 +1148,7 @@ func TestServer_AdminRoutes(t *testing.T) { return &model.User{ID: 2, Username: username, IsAdmin: isAdmin}, nil }, DeleteUserFunc: func(ctx context.Context, id int64) error { return nil }, - ListPermissionsFunc: func(ctx context.Context) ([]model.SetPermission, error) { return nil, nil }, + ListPermissionsFunc: func(ctx context.Context) (*service.PermissionsMatrix, error) { return nil, nil }, GrantPermissionFunc: func(ctx context.Context, setID, userID int64, role model.Role) error { return nil }, RevokePermissionFunc: func(ctx context.Context, setID, userID int64) error { return nil }, } diff --git a/internal/service/admin.go b/internal/service/admin.go index fe0d508..afccc78 100644 --- a/internal/service/admin.go +++ b/internal/service/admin.go @@ -74,12 +74,17 @@ func (s *adminService) DeleteUser(ctx context.Context, id int64) error { return s.store.DeleteUser(ctx, id) } -func (s *adminService) ListPermissions(ctx context.Context) ([]model.SetPermission, error) { +func (s *adminService) ListPermissions(ctx context.Context) (*PermissionsMatrix, error) { sets, err := s.store.ListSets(ctx) if err != nil { return nil, fmt.Errorf("list sets: %w", err) } + users, err := s.store.ListUsers(ctx) + if err != nil { + return nil, fmt.Errorf("list users: %w", err) + } + var perms []model.SetPermission for _, set := range sets { setPerms, err := s.store.ListPermissionsBySet(ctx, set.ID) @@ -89,7 +94,11 @@ func (s *adminService) ListPermissions(ctx context.Context) ([]model.SetPermissi perms = append(perms, setPerms...) } - return perms, nil + return &PermissionsMatrix{ + Sets: sets, + Users: users, + Permissions: perms, + }, nil } func (s *adminService) GrantPermission(ctx context.Context, setID, userID int64, role model.Role) error { diff --git a/internal/service/admin_test.go b/internal/service/admin_test.go index d6dbfeb..afacc3a 100644 --- a/internal/service/admin_test.go +++ b/internal/service/admin_test.go @@ -205,8 +205,11 @@ func TestAdminService_ListPermissions(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - if len(perms) != 2 { - t.Fatalf("expected 2 permissions, got %d", len(perms)) + if perms == nil || len(perms.Permissions) != 2 { + t.Fatalf("expected 2 permissions, got %+v", perms) + } + if len(perms.Sets) != 2 { + t.Fatalf("expected 2 sets, got %d", len(perms.Sets)) } } diff --git a/internal/service/mock.go b/internal/service/mock.go index d41ebce..0fe7735 100644 --- a/internal/service/mock.go +++ b/internal/service/mock.go @@ -176,7 +176,7 @@ type MockAdminService struct { ListUsersFunc func(ctx context.Context) ([]model.User, error) CreateUserFunc func(ctx context.Context, username, password string, isAdmin bool) (*model.User, error) DeleteUserFunc func(ctx context.Context, id int64) error - ListPermissionsFunc func(ctx context.Context) ([]model.SetPermission, error) + ListPermissionsFunc func(ctx context.Context) (*PermissionsMatrix, error) GrantPermissionFunc func(ctx context.Context, setID, userID int64, role model.Role) error RevokePermissionFunc func(ctx context.Context, setID, userID int64) error } @@ -211,7 +211,7 @@ func (m *MockAdminService) DeleteUser(ctx context.Context, id int64) error { } return nil } -func (m *MockAdminService) ListPermissions(ctx context.Context) ([]model.SetPermission, error) { +func (m *MockAdminService) ListPermissions(ctx context.Context) (*PermissionsMatrix, error) { if m.ListPermissionsFunc != nil { return m.ListPermissionsFunc(ctx) } diff --git a/internal/service/mock_test.go b/internal/service/mock_test.go index 796de58..2e5b98e 100644 --- a/internal/service/mock_test.go +++ b/internal/service/mock_test.go @@ -130,7 +130,7 @@ func TestMockAdminService_WithFuncs(t *testing.T) { ListUsersFunc: func(ctx context.Context) ([]model.User, error) { return nil, nil }, CreateUserFunc: func(ctx context.Context, username, password string, isAdmin bool) (*model.User, error) { return nil, nil }, DeleteUserFunc: func(ctx context.Context, id int64) error { return nil }, - ListPermissionsFunc: func(ctx context.Context) ([]model.SetPermission, error) { return nil, nil }, + ListPermissionsFunc: func(ctx context.Context) (*PermissionsMatrix, error) { return nil, nil }, GrantPermissionFunc: func(ctx context.Context, setID, userID int64, role model.Role) error { return nil }, RevokePermissionFunc: func(ctx context.Context, setID, userID int64) error { return nil }, } diff --git a/internal/service/service.go b/internal/service/service.go index 467aaf6..72c7de7 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -43,7 +43,7 @@ type AdminService interface { ListUsers(ctx context.Context) ([]model.User, error) CreateUser(ctx context.Context, username, password string, isAdmin bool) (*model.User, error) DeleteUser(ctx context.Context, id int64) error - ListPermissions(ctx context.Context) ([]model.SetPermission, error) + ListPermissions(ctx context.Context) (*PermissionsMatrix, error) GrantPermission(ctx context.Context, setID, userID int64, role model.Role) error RevokePermission(ctx context.Context, setID, userID int64) error } @@ -53,6 +53,13 @@ type ProgressService interface { UpdateProgress(ctx context.Context, sessionID string, userID, mediaID int64, position float64) error } +// PermissionsMatrix is the shape returned by ListPermissions. +type PermissionsMatrix struct { + Sets []model.Set `json:"sets"` + Users []model.User `json:"users"` + Permissions []model.SetPermission `json:"permissions"` +} + // FileResult contains info for serving a file. type FileResult struct { Path string -- cgit v1.2.3