feat: roles SPA Users, Profile, API keys, Activity

This commit is contained in:
Florian Sylvain committed 2026-10-28 00:10:15 +01:00
1 parent 3db490a615
commit 34dffe222f
98 files changed
+4957 -434

No files matched your search

@@ -4,6 +4,7 @@ import (
"RenewCMS/internal/domain/invite"
"RenewCMS/internal/domain/role"
"RenewCMS/internal/domain/user"
"errors"
"sort"
"time"
)
@@ -19,34 +20,67 @@ type ListUsersAndInvitesUseCase struct {
roles role.Repository
}
type RoleAssigner struct {
ID uint32 `json:"id"`
Name string `json:"name"`
}
func newRoleAssigner(account user.User) *RoleAssigner {
return &RoleAssigner{ID: account.ID, Name: account.NameOrUsername()}
}
func resolveRoleAssigner(users user.Repository, id uint32) (*RoleAssigner, error) {
if id == 0 {
return nil, nil
}
found, err := users.Get(id)
if errors.Is(err, user.ErrUserNotFound) {
return nil, nil
}
if err != nil {
return nil, err
}
return newRoleAssigner(found), nil
}
type DirectoryEntry struct {
ID uint32
Kind string
Username string
DisplayName string
Email string
Role *RoleRef
Status string
CreatedAt time.Time
ID uint32
Kind string
Username string
DisplayName string
Email string
Role *RoleRef
RoleAssignedBy *RoleAssigner
Status string
CreatedAt time.Time
}
func NewListUsersAndInvitesUseCase(userRepository user.Repository, inviteRepository invite.Repository, roles role.Repository) *ListUsersAndInvitesUseCase {
return &ListUsersAndInvitesUseCase{userRepository, inviteRepository, roles}
}
func userEntry(account user.User, found *RoleRef) DirectoryEntry {
func userEntry(account user.User, found *RoleRef, assigner *RoleAssigner) DirectoryEntry {
return DirectoryEntry{
ID: account.ID,
Kind: EntryKindUser,
Username: account.Username,
DisplayName: account.DisplayName,
Email: account.Email,
Role: found,
Status: string(invite.StatusAccepted),
CreatedAt: account.CreatedAt,
ID: account.ID,
Kind: EntryKindUser,
Username: account.Username,
DisplayName: account.DisplayName,
Email: account.Email,
Role: found,
RoleAssignedBy: assigner,
Status: string(invite.StatusAccepted),
CreatedAt: account.CreatedAt,
}
}
func assignerAmong(loaded map[uint32]user.User, id uint32) *RoleAssigner {
found, present := loaded[id]
if id == 0 || !present {
return nil
}
return newRoleAssigner(found)
}
func (g *ListUsersAndInvitesUseCase) ListUsersAndInvites() ([]DirectoryEntry, error) {
refs, err := roleRefsByID(g.roles)
if err != nil {
@@ -55,8 +89,13 @@ func (g *ListUsersAndInvitesUseCase) ListUsersAndInvites() ([]DirectoryEntry, er
now := time.Now()
entries := []DirectoryEntry{}
for _, existingUser := range g.userRepository.GetAll() {
entries = append(entries, userEntry(existingUser, lookupRoleRef(refs, existingUser.RoleID)))
users := g.userRepository.GetAll()
loaded := make(map[uint32]user.User, len(users))
for _, existingUser := range users {
loaded[existingUser.ID] = existingUser
}
for _, existingUser := range users {
entries = append(entries, userEntry(existingUser, lookupRoleRef(refs, existingUser.RoleID), assignerAmong(loaded, existingUser.RoleAssignedByID)))
}
for _, existingInvite := range g.inviteRepository.GetAll() {