From 863d5dfe04b3ca557dfb18d7714fe6e38afb99a8 Mon Sep 17 00:00:00 2001 From: Ricardo Lopes Date: Tue, 27 Aug 2024 17:32:37 +0100 Subject: [PATCH] feat: #24 Adds filters for dates regardings accesses on /shorty/:id - closes #24 --- api/shortener.go | 8 ++++++-- docs/swagger.json | 14 ++++++++++++++ docs/swagger.yaml | 10 ++++++++++ service/shorty.go | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/api/shortener.go b/api/shortener.go index 209d169..a0f1b7a 100644 --- a/api/shortener.go +++ b/api/shortener.go @@ -41,6 +41,8 @@ func (h *shortenerHandler) Group() *string { // @Description retrieves full information for the give shortlink // @Param token header string false "Authorization token" // @Param id path string true "ShortLink ID" +// @Param from query string true "accesses from date 'YYYY-mm-dd'" +// @Param until query string true "accesses until date 'YYYY-mm-dd'" // @Success 200 {object} entity.Shorty "response" // @Failure 400 {object} response.FailureResponse "error" // @Failure 404 {object} response.FailureResponse "not found" @@ -54,7 +56,9 @@ func (h *shortenerHandler) GetLinkInformation(c *gin.Context) { ) } parsed := uuid.MustParse(id) - shorty, err := h.shortySvc.FindShortyByID(parsed) + from := c.Query("from") + until := c.Query("until") + shorty, err := h.shortySvc.FindShortyByID(parsed, from, until) if err != nil { c.JSON(http.StatusNotFound, "shorty not found") return @@ -157,7 +161,7 @@ func (h *shortenerHandler) EditLink(c *gin.Context) { return } - shorty, err := h.shortySvc.FindShortyByID(uuid.MustParse(id)) + shorty, err := h.shortySvc.FindShortyByID(uuid.MustParse(id), "", "") if err != nil { c.JSON(http.StatusNotFound, "shorty not found") return diff --git a/docs/swagger.json b/docs/swagger.json index 8abf1d4..aab0d48 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -149,6 +149,20 @@ "name": "id", "in": "path", "required": true + }, + { + "type": "string", + "description": "accesses from date 'YYYY-mm-dd'", + "name": "from", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "accesses until date 'YYYY-mm-dd'", + "name": "until", + "in": "query", + "required": true } ], "responses": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 1699cfd..076e729 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -265,6 +265,16 @@ paths: name: id required: true type: string + - description: accesses from date 'YYYY-mm-dd' + in: query + name: from + required: true + type: string + - description: accesses until date 'YYYY-mm-dd' + in: query + name: until + required: true + type: string responses: "200": description: response diff --git a/service/shorty.go b/service/shorty.go index 248ebee..5d8c56c 100644 --- a/service/shorty.go +++ b/service/shorty.go @@ -170,7 +170,7 @@ func (s *ShortyService) List(limit, offset int) ([]*entity.Shorty, error) { return shorties, nil } -func (s *ShortyService) FindShortyByID(id uuid.UUID) (*entity.Shorty, error) { +func (s *ShortyService) FindShortyByID(id uuid.UUID, from, until string) (*entity.Shorty, error) { m := &entity.Shorty{ ID: id, } @@ -179,6 +179,27 @@ func (s *ShortyService) FindShortyByID(id uuid.UUID) (*entity.Shorty, error) { return nil, err } + if from != "" && until != "" { + fromTime, err := time.Parse(time.DateOnly, from) + if err != nil { + return nil, err + } + + untilTime, err := time.Parse(time.DateTime, until+" 23:59:59") + if err != nil { + return nil, err + } + + sh := s.FindAllAccessesByShortyIDAndDateRange(id, &fromTime, &untilTime) + + m.ShortyAccesses = sh + + m.Visits = len(sh) + m.RedirectCount = CountRedirects(sh) + + return m, nil + } + sh := s.FindAllAccessesByShortyID(id) m.ShortyAccesses = sh @@ -216,6 +237,21 @@ func (s *ShortyService) FindAllAccessesByShortyID(id uuid.UUID) []entity.ShortyA return sh } +func (s *ShortyService) FindAllAccessesByShortyIDAndDateRange( + id uuid.UUID, + from, + until *time.Time, +) []entity.ShortyAccess { + var sh []entity.ShortyAccess + + _ = s.shortyAccessRepository.Database.Orm. + Model(&entity.ShortyAccess{}). + Where("shorty_id = ?", id). + Where("created_at BETWEEN ? AND ?", from, until).Scan(&sh) + + return sh +} + func CountRedirects(accesses []entity.ShortyAccess) int { var redirects int for _, access := range accesses {