summaryrefslogtreecommitdiff
path: root/shrine/services/functions.go
diff options
context:
space:
mode:
Diffstat (limited to 'shrine/services/functions.go')
-rw-r--r--shrine/services/functions.go141
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