Merge pull request #1178 from trheyi/main
Refactor settings handling in user invitation, member, and team APIs
This commit is contained in:
commit
110abd5161
4 changed files with 141 additions and 82 deletions
|
|
@ -194,28 +194,20 @@ func GinInvitationCreate(c *gin.Context) {
|
|||
"expiry": req.Expiry,
|
||||
}
|
||||
|
||||
// Add send_email setting from top-level field
|
||||
if req.SendEmail != nil {
|
||||
if invitationData["settings"] == nil {
|
||||
invitationData["settings"] = make(map[string]interface{})
|
||||
}
|
||||
if settings, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
settings["send_email"] = *req.SendEmail
|
||||
}
|
||||
// Prepare settings
|
||||
settings := &InvitationSettings{}
|
||||
if req.Settings != nil {
|
||||
settings = req.Settings
|
||||
}
|
||||
|
||||
// Add other settings if provided
|
||||
if req.Settings != nil {
|
||||
if invitationData["settings"] == nil {
|
||||
invitationData["settings"] = req.Settings
|
||||
} else {
|
||||
// Merge settings
|
||||
if existingSettings, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
for k, v := range req.Settings {
|
||||
existingSettings[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add send_email from top-level field (for backward compatibility)
|
||||
if req.SendEmail != nil {
|
||||
settings.SendEmail = *req.SendEmail
|
||||
}
|
||||
|
||||
// Add settings to invitation data
|
||||
if settings.SendEmail || settings.Locale != "" {
|
||||
invitationData["settings"] = settings
|
||||
}
|
||||
|
||||
// Call business logic
|
||||
|
|
@ -734,8 +726,11 @@ func invitationCreate(ctx context.Context, userID, teamID string, invitationData
|
|||
|
||||
// Check send_email requirement early
|
||||
shouldSendEmail := false
|
||||
if settings, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
shouldSendEmail = toBool(settings["send_email"])
|
||||
if settings, ok := invitationData["settings"].(*InvitationSettings); ok && settings != nil {
|
||||
shouldSendEmail = settings.SendEmail
|
||||
} else if settingsMap, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
// Fallback for map format (for backward compatibility)
|
||||
shouldSendEmail = toBool(settingsMap["send_email"])
|
||||
}
|
||||
|
||||
// If send_email is true, email must be provided
|
||||
|
|
@ -987,8 +982,13 @@ func getInvitationExpiry(invitationData maps.MapStrAny) (time.Duration, error) {
|
|||
// Get team config expiry (from global config)
|
||||
// Try to get locale from invitation data settings
|
||||
locale := "en"
|
||||
if settings, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
if loc := toString(settings["locale"]); loc != "" {
|
||||
if settings, ok := invitationData["settings"].(*InvitationSettings); ok && settings != nil {
|
||||
if settings.Locale != "" {
|
||||
locale = settings.Locale
|
||||
}
|
||||
} else if settingsMap, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
// Fallback for map format (for backward compatibility)
|
||||
if loc := toString(settingsMap["locale"]); loc != "" {
|
||||
locale = loc
|
||||
}
|
||||
}
|
||||
|
|
@ -1020,8 +1020,13 @@ func sendInvitationEmail(ctx context.Context, email, inviterName, teamName, toke
|
|||
|
||||
// Get locale from invitation data settings
|
||||
locale := "en"
|
||||
if settings, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
if loc := toString(settings["locale"]); loc != "" {
|
||||
if settings, ok := invitationData["settings"].(*InvitationSettings); ok && settings != nil {
|
||||
if settings.Locale != "" {
|
||||
locale = settings.Locale
|
||||
}
|
||||
} else if settingsMap, ok := invitationData["settings"].(map[string]interface{}); ok {
|
||||
// Fallback for map format (for backward compatibility)
|
||||
if loc := toString(settingsMap["locale"]); loc != "" {
|
||||
locale = loc
|
||||
}
|
||||
}
|
||||
|
|
@ -1094,8 +1099,15 @@ func mapToInvitationResponse(data maps.MapStr) InvitationResponse {
|
|||
|
||||
// Add settings if available
|
||||
if settings, ok := data["settings"]; ok {
|
||||
if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
invitation.Settings = settingsMap
|
||||
if invSettings, ok := settings.(*InvitationSettings); ok {
|
||||
invitation.Settings = invSettings
|
||||
} else if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
// Convert map to InvitationSettings
|
||||
invSettings := &InvitationSettings{
|
||||
SendEmail: toBool(settingsMap["send_email"]),
|
||||
Locale: toString(settingsMap["locale"]),
|
||||
}
|
||||
invitation.Settings = invSettings
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -797,8 +797,28 @@ func mapToMemberResponse(data maps.MapStr) MemberResponse {
|
|||
|
||||
// Add settings if available
|
||||
if settings, ok := data["settings"]; ok {
|
||||
if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
member.Settings = settingsMap
|
||||
if memSettings, ok := settings.(*MemberSettings); ok {
|
||||
member.Settings = memSettings
|
||||
} else if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
// Convert map to MemberSettings (for backward compatibility)
|
||||
memSettings := &MemberSettings{
|
||||
Notifications: toBool(settingsMap["notifications"]),
|
||||
}
|
||||
// Handle permissions array
|
||||
if perms, ok := settingsMap["permissions"]; ok {
|
||||
if permsSlice, ok := perms.([]interface{}); ok {
|
||||
permissions := make([]string, 0, len(permsSlice))
|
||||
for _, p := range permsSlice {
|
||||
if permStr, ok := p.(string); ok {
|
||||
permissions = append(permissions, permStr)
|
||||
}
|
||||
}
|
||||
memSettings.Permissions = permissions
|
||||
} else if permsStrSlice, ok := perms.([]string); ok {
|
||||
memSettings.Permissions = permsStrSlice
|
||||
}
|
||||
}
|
||||
member.Settings = memSettings
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -818,8 +818,15 @@ func mapToTeamDetailResponse(data maps.MapStr) TeamDetailResponse {
|
|||
|
||||
// Add settings if available
|
||||
if settings, ok := data["settings"]; ok {
|
||||
if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
team.Settings = settingsMap
|
||||
if teamSettings, ok := settings.(*TeamSettings); ok {
|
||||
team.Settings = teamSettings
|
||||
} else if settingsMap, ok := settings.(map[string]interface{}); ok {
|
||||
// Convert map to TeamSettings (for backward compatibility)
|
||||
teamSettings := &TeamSettings{
|
||||
Theme: toString(settingsMap["theme"]),
|
||||
Visibility: toString(settingsMap["visibility"]),
|
||||
}
|
||||
team.Settings = teamSettings
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,26 @@ const (
|
|||
UserInfoSourceAccessToken = "access_token" // Extract user info from access token response
|
||||
)
|
||||
|
||||
// ==== Settings Types ====
|
||||
|
||||
// TeamSettings represents team-specific settings
|
||||
type TeamSettings struct {
|
||||
Theme string `json:"theme,omitempty"` // Team UI theme (e.g., "light", "dark")
|
||||
Visibility string `json:"visibility,omitempty"` // Team visibility (e.g., "public", "private")
|
||||
}
|
||||
|
||||
// MemberSettings represents member-specific settings
|
||||
type MemberSettings struct {
|
||||
Notifications bool `json:"notifications,omitempty"` // Whether to receive notifications
|
||||
Permissions []string `json:"permissions,omitempty"` // Custom permissions (e.g., ["read", "write"])
|
||||
}
|
||||
|
||||
// InvitationSettings represents invitation-specific settings
|
||||
type InvitationSettings struct {
|
||||
SendEmail bool `json:"send_email,omitempty"` // Whether to send invitation email
|
||||
Locale string `json:"locale,omitempty"` // Locale for email template
|
||||
}
|
||||
|
||||
// ==== Team API Types ====
|
||||
|
||||
// TeamResponse represents a team in API responses
|
||||
|
|
@ -222,40 +242,40 @@ type TeamResponse struct {
|
|||
type TeamDetailResponse struct {
|
||||
TeamResponse
|
||||
// Add additional fields that are only included in detailed responses
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
Settings *TeamSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// CreateTeamRequest represents the request to create a team
|
||||
type CreateTeamRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Settings *TeamSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateTeamRequest represents the request to update a team
|
||||
type UpdateTeamRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Settings *TeamSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// ==== Member API Types ====
|
||||
|
||||
// MemberResponse represents a team member in API responses
|
||||
type MemberResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
UserID string `json:"user_id"`
|
||||
MemberType string `json:"member_type"`
|
||||
RoleID string `json:"role_id"`
|
||||
Status string `json:"status"`
|
||||
InvitedBy string `json:"invited_by,omitempty"`
|
||||
InvitedAt string `json:"invited_at,omitempty"`
|
||||
JoinedAt string `json:"joined_at,omitempty"`
|
||||
LastActivity string `json:"last_activity,omitempty"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ID int64 `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
UserID string `json:"user_id"`
|
||||
MemberType string `json:"member_type"`
|
||||
RoleID string `json:"role_id"`
|
||||
Status string `json:"status"`
|
||||
InvitedBy string `json:"invited_by,omitempty"`
|
||||
InvitedAt string `json:"invited_at,omitempty"`
|
||||
JoinedAt string `json:"joined_at,omitempty"`
|
||||
LastActivity string `json:"last_activity,omitempty"`
|
||||
Settings *MemberSettings `json:"settings,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// MemberDetailResponse represents detailed member information
|
||||
|
|
@ -267,38 +287,38 @@ type MemberDetailResponse struct {
|
|||
|
||||
// CreateMemberRequest represents the request to add a member directly
|
||||
type CreateMemberRequest struct {
|
||||
UserID string `json:"user_id" binding:"required"`
|
||||
MemberType string `json:"member_type,omitempty"` // "user" or "robot"
|
||||
RoleID string `json:"role_id" binding:"required"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
UserID string `json:"user_id" binding:"required"`
|
||||
MemberType string `json:"member_type,omitempty"` // "user" or "robot"
|
||||
RoleID string `json:"role_id" binding:"required"`
|
||||
Settings *MemberSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMemberRequest represents the request to update a member
|
||||
type UpdateMemberRequest struct {
|
||||
RoleID string `json:"role_id,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
LastActivity string `json:"last_activity,omitempty"`
|
||||
RoleID string `json:"role_id,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Settings *MemberSettings `json:"settings,omitempty"`
|
||||
LastActivity string `json:"last_activity,omitempty"`
|
||||
}
|
||||
|
||||
// ==== Invitation API Types ====
|
||||
|
||||
// InvitationResponse represents a team invitation in API responses
|
||||
type InvitationResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
UserID string `json:"user_id"`
|
||||
MemberType string `json:"member_type"`
|
||||
RoleID string `json:"role_id"`
|
||||
Status string `json:"status"`
|
||||
InvitedBy string `json:"invited_by"`
|
||||
InvitedAt string `json:"invited_at"`
|
||||
InvitationToken string `json:"invitation_token,omitempty"`
|
||||
InvitationExpiresAt string `json:"invitation_expires_at,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ID int64 `json:"id"`
|
||||
TeamID string `json:"team_id"`
|
||||
UserID string `json:"user_id"`
|
||||
MemberType string `json:"member_type"`
|
||||
RoleID string `json:"role_id"`
|
||||
Status string `json:"status"`
|
||||
InvitedBy string `json:"invited_by"`
|
||||
InvitedAt string `json:"invited_at"`
|
||||
InvitationToken string `json:"invitation_token,omitempty"`
|
||||
InvitationExpiresAt string `json:"invitation_expires_at,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Settings *InvitationSettings `json:"settings,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// InvitationDetailResponse represents detailed invitation information
|
||||
|
|
@ -311,14 +331,14 @@ type InvitationDetailResponse struct {
|
|||
|
||||
// CreateInvitationRequest represents the request to send a team invitation
|
||||
type CreateInvitationRequest struct {
|
||||
UserID string `json:"user_id,omitempty"` // Optional for unregistered users
|
||||
Email string `json:"email,omitempty"` // Email address (if not provided, will be read from user profile when user_id is provided)
|
||||
MemberType string `json:"member_type,omitempty"` // "user" or "robot"
|
||||
RoleID string `json:"role_id" binding:"required"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Expiry string `json:"expiry,omitempty"` // Custom expiry duration (e.g., "1d", "8h"), defaults to team config
|
||||
SendEmail *bool `json:"send_email,omitempty"` // Whether to send email (defaults to false)
|
||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||
UserID string `json:"user_id,omitempty"` // Optional for unregistered users
|
||||
Email string `json:"email,omitempty"` // Email address (if not provided, will be read from user profile when user_id is provided)
|
||||
MemberType string `json:"member_type,omitempty"` // "user" or "robot"
|
||||
RoleID string `json:"role_id" binding:"required"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Expiry string `json:"expiry,omitempty"` // Custom expiry duration (e.g., "1d", "8h"), defaults to team config
|
||||
SendEmail *bool `json:"send_email,omitempty"` // Whether to send email (defaults to false)
|
||||
Settings *InvitationSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// ==== Team Configuration Types ====
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue