diff options
Diffstat (limited to 'shrine/services/functions.go')
| -rw-r--r-- | shrine/services/functions.go | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/shrine/services/functions.go b/shrine/services/functions.go new file mode 100644 index 0000000..f502ff6 --- /dev/null +++ b/shrine/services/functions.go @@ -0,0 +1,141 @@ +package services + +import ( + "fmt" + "shrine/enums" + "shrine/messages" + "shrine/models" + "shrine/repositories" + "shrine/types/hypertext" + "shrine/types/letter" + "shrine/types/ticket" + "shrine/utils/sanitize" + "strings" +) + +func ResolveUser(username string) (*models.User, *hypertext.ServiceError) { + citizen, err := repositories.FindUserByUsername(username) + if err != nil { + return nil, fail(enums.NotFound, messages.UserNotFound) + } + return citizen, nil +} + +func mapRegistrationError(err error) *hypertext.ServiceError { + if strings.Contains(err.Error(), "users.username") { + return fail(enums.Conflict, messages.UsernameAlreadyExists) + } + if strings.Contains(err.Error(), "users.email") { + return fail(enums.Conflict, messages.EmailAlreadyExists) + } + return fail(enums.BadRequest, err.Error()) +} + +func assembleLetterResponse(record *models.Letter, viewerID uint) letter.LetterResponse { + participants := repositories.GetLetterParticipants(record.ID) + lastMessage := repositories.GetLastMessage(record.ID) + viewer, _ := repositories.GetParticipantRecord(record.ID, viewerID) + + var unread bool + if viewer != nil && lastMessage != nil { + unread = viewer.LastReadAt == nil || lastMessage.CreatedAt.After(*viewer.LastReadAt) + } + + var lastMessageResponse *letter.MessageResponse + if lastMessage != nil { + response := lastMessage.ToResponse() + lastMessageResponse = &response + } + + return letter.LetterResponse{ + Ref: record.Ref, + Title: computeTitle(record, participants, viewerID), + IsSystem: record.IsSystem, + SystemRef: record.SystemRef, + Participants: buildParticipantResponses(participants), + LastMessage: lastMessageResponse, + Unread: unread, + UpdatedAt: record.UpdatedAt, + } +} + +func computeTitle(record *models.Letter, participants []models.LetterParticipant, viewerID uint) string { + if record.Title != "" { + return record.Title + } + + if record.IsSystem { + return "System Message" + } + + var others []string + for _, participant := range participants { + if participant.UserID != viewerID { + others = append(others, participant.User.DisplayName) + } + } + + switch len(others) { + case 0: + return "Empty Conversation" + case 1: + return others[0] + case 2: + return fmt.Sprintf("%s and %s", others[0], others[1]) + default: + return fmt.Sprintf("%s, %s, and %d others", others[0], others[1], len(others)-2) + } +} + +func buildParticipantResponses(participants []models.LetterParticipant) []letter.ParticipantResponse { + responses := make([]letter.ParticipantResponse, len(participants)) + for index, participant := range participants { + responses[index] = participant.ToResponse() + } + return responses +} + +func buildMessageResponses(letterMessages []models.LetterMessage) []letter.MessageResponse { + responses := make([]letter.MessageResponse, len(letterMessages)) + for index, message := range letterMessages { + responses[index] = message.ToResponse() + } + return responses +} + +func resolveLetter(ref string, userID uint) (*models.Letter, *hypertext.ServiceError) { + record, err := repositories.FindLetterByRef(ref) + if err != nil { + return nil, fail(enums.NotFound, messages.LetterNotFound) + } + + if !repositories.IsLetterParticipant(record.ID, userID) { + return nil, fail(enums.NotFound, messages.LetterNotFound) + } + + return record, nil +} + +func resolveTicket(ref string) (*models.Ticket, *hypertext.ServiceError) { + record, err := repositories.FindTicketByRef(ref) + if err != nil { + return nil, fail(enums.NotFound, messages.TicketNotFound) + } + return record, nil +} + +func sanitizeRequiredBody(body string) (string, *hypertext.ServiceError) { + sanitized := sanitize.HTML(body) + if sanitized == "" { + return "", fail(enums.BadRequest, messages.MessageBodyRequired) + } + return sanitized, nil +} + +func buildTicketMessageResponses(ticketMessages []models.TicketMessage) []ticket.MessageResponse { + responses := make([]ticket.MessageResponse, len(ticketMessages)) + for index, message := range ticketMessages { + responses[index] = message.ToResponse() + } + return responses +}
\ No newline at end of file |
