Skip to content

Commit

Permalink
feat: api to get memo by discord id (#743)
Browse files Browse the repository at this point in the history
* feat: api to get memo by discord id

* feat: api to get memo by discord id
  • Loading branch information
namnhce authored Aug 29, 2024
1 parent 013241f commit 181bc98
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 5 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
github.com/jackc/pgtype v1.14.0
github.com/jinzhu/now v1.1.5
github.com/joho/godotenv v1.5.1
github.com/k0kubun/pp/v3 v3.2.0
github.com/k0kubun/pp v3.0.1+incompatible
github.com/lib/pq v1.10.9
github.com/matoous/go-nanoid v1.5.0
github.com/patrickmn/go-cache v2.1.0+incompatible
Expand Down Expand Up @@ -129,6 +129,7 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -485,8 +485,10 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/k0kubun/pp/v3 v3.2.0 h1:h33hNTZ9nVFNP3u2Fsgz8JXiF5JINoZfFq4SvKJwNcs=
github.com/k0kubun/pp/v3 v3.2.0/go.mod h1:ODtJQbQcIRfAD3N+theGCV1m/CBxweERz2dapdz1EwA=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
Expand Down
1 change: 1 addition & 0 deletions pkg/handler/memologs/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ type IHandler interface {
List(c *gin.Context)
Sync(c *gin.Context)
ListOpenPullRequest(c *gin.Context)
ListByDiscordID(c *gin.Context)
}
35 changes: 35 additions & 0 deletions pkg/handler/memologs/memo_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package memologs

import (
"context"
"errors"
"net/http"
"strconv"
"time"
Expand Down Expand Up @@ -234,3 +235,37 @@ func (h *handler) ListOpenPullRequest(c *gin.Context) {

c.JSON(http.StatusOK, view.CreateResponse[any](memoprs, nil, nil, nil, "ok"))
}

func (h *handler) ListByDiscordID(c *gin.Context) {
l := h.logger.Fields(
logger.Fields{
"handler": "memologs",
"method": "ListByDiscordID",
},
)

discordID := c.Query("discordID")
if discordID == "" {
l.Error(errors.New("discordID is required"), "discordID is required")
c.JSON(http.StatusBadRequest, view.CreateResponse[any](nil, nil, nil, nil, "discordID is required"))
return
}

memoLogs, err := h.store.MemoLog.List(h.repo.DB(), memolog.ListFilter{
DiscordID: discordID,
})
if err != nil {
l.Error(err, "failed to get memologs")
c.JSON(http.StatusInternalServerError, view.CreateResponse[any](nil, nil, err, nil, ""))
return
}

discordMemoRank, err := h.store.MemoLog.GetRankByDiscordID(h.repo.DB(), discordID)
if err != nil {
l.Error(err, "failed to get rank by discord id")
c.JSON(http.StatusInternalServerError, view.CreateResponse[any](nil, nil, err, nil, ""))
return
}

c.JSON(http.StatusOK, view.CreateResponse[any](view.ToMemoLogByDiscordID(memoLogs, discordMemoRank), nil, nil, nil, ""))
}
6 changes: 6 additions & 0 deletions pkg/model/memo_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ type MemoLog struct {
AuthorMemoUsernames []string `json:"-" gorm:"-"`
}

type DiscordAccountMemoRank struct {
DiscordID string
TotalMemos int
Rank int
}

func (MemoLog) BeforeCreate(db *gorm.DB) error {
return db.SetupJoinTable(&MemoLog{}, "Authors", &MemoAuthor{})
}
1 change: 1 addition & 0 deletions pkg/routes/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ func loadV1Routes(r *gin.Engine, h *handler.Handler, repo store.DBRepo, s *store
memoGroup.POST("", amw.WithAuth, h.MemoLog.Create)
memoGroup.POST("/sync", amw.WithAuth, h.MemoLog.Sync)
memoGroup.GET("", amw.WithAuth, h.MemoLog.List)
memoGroup.GET("/discords", amw.WithAuth, h.MemoLog.ListByDiscordID)
memoGroup.GET("/prs", amw.WithAuth, h.MemoLog.ListOpenPullRequest)
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/routes/v1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,12 @@ func Test_loadV1Routes(t *testing.T) {
Handler: "github.com/dwarvesf/fortress-api/pkg/handler/memologs.IHandler.ListOpenPullRequest-fm",
},
},
"/api/v1/memos/discords": {
"GET": {
Method: "GET",
Handler: "github.com/dwarvesf/fortress-api/pkg/handler/memologs.IHandler.ListByDiscordID-fm",
},
},
"/api/v1/public/community-nfts/:id": {
"GET": {
Method: "GET",
Expand Down
1 change: 1 addition & 0 deletions pkg/store/memolog/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ type IStore interface {
Create(db *gorm.DB, b []model.MemoLog) ([]model.MemoLog, error)
GetLimitByTimeRange(db *gorm.DB, start, end *time.Time, limit int) ([]model.MemoLog, error)
List(db *gorm.DB, filter ListFilter) ([]model.MemoLog, error)
GetRankByDiscordID(db *gorm.DB, discordID string) (*model.DiscordAccountMemoRank, error)
}
59 changes: 57 additions & 2 deletions pkg/store/memolog/memo_log.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package memolog

import (
"fmt"
"time"

"gorm.io/gorm"
Expand All @@ -27,8 +28,9 @@ func (s *store) GetLimitByTimeRange(db *gorm.DB, start, end *time.Time, limit in

// ListFilter is a filter for List function
type ListFilter struct {
From *time.Time
To *time.Time
From *time.Time
To *time.Time
DiscordID string
}

// List gets all memo logs
Expand All @@ -42,5 +44,58 @@ func (s *store) List(db *gorm.DB, filter ListFilter) ([]model.MemoLog, error) {
query = query.Where("published_at <= ?", *filter.To)
}

if filter.DiscordID != "" {
query = query.Joins("JOIN memo_authors ma ON ma.memo_log_id = memo_logs.id").
Joins("JOIN discord_accounts da ON da.id = ma.discord_account_id AND da.discord_id = ?", filter.DiscordID)
}

return logs, query.Find(&logs).Error
}

func (s *store) GetRankByDiscordID(db *gorm.DB, discordID string) (*model.DiscordAccountMemoRank, error) {
query := `
WITH memo_count AS (
SELECT
da.discord_id,
COUNT(ml.id) AS total_memos
FROM
public.memo_authors ma
JOIN
public.memo_logs ml ON ma.memo_log_id = ml.id
JOIN
public.discord_accounts da ON ma.discord_account_id = da.id
WHERE
ml.deleted_at IS NULL
GROUP BY
da.discord_id
),
ranked_memos AS (
SELECT
discord_id,
total_memos,
RANK() OVER (ORDER BY total_memos DESC) AS rank
FROM
memo_count
)
SELECT
rm.discord_id,
rm.total_memos,
rm.rank
FROM
ranked_memos rm
WHERE
rm.discord_id = ?
`
var memoRank model.DiscordAccountMemoRank
result := db.Raw(query, discordID).Scan(&memoRank)

if result.Error != nil {
return nil, result.Error
}

if result.RowsAffected == 0 {
return nil, fmt.Errorf("no records found for discord_id: %s", discordID)
}

return &memoRank, nil
}
72 changes: 72 additions & 0 deletions pkg/view/memo.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ type MemoLogAuthor struct {
MemoUsername string `json:"memoUsername"`
}

// AuthorRanking is the rank of the discord account
type AuthorRanking struct {
DiscordID string `json:"discordID"`
TotalMemos int `json:"totalMemos"`
Rank int `json:"rank"`
}

// MemoLogsResponse response for memo logs
type MemoLogsResponse struct {
Data []MemoLog `json:"data"`
Expand Down Expand Up @@ -67,3 +74,68 @@ func ToMemoLog(memoLogs []model.MemoLog) []MemoLog {

return rs
}

// MemoLogByDiscordIDResponse response for memo logs
type MemoLogByDiscordIDResponse struct {
Data MemoLogsByDiscordID `json:"data"`
} // @name MemoLogByDiscordIDResponse

type MemoLogsByDiscordID struct {
MemoLogs []MemoLog `json:"memoLogs"`
Rank AuthorRanking `json:"rank"`
} // @name MemoLogsByDiscordID

// ToMemoLogByDiscordID ...
func ToMemoLogByDiscordID(memoLogs []model.MemoLog, discordMemoRank *model.DiscordAccountMemoRank) MemoLogsByDiscordID {
rs := make([]MemoLog, 0)
for _, memoLog := range memoLogs {
authors := make([]MemoLogAuthor, 0)
for _, author := range memoLog.Authors {
var employeeID string
if author.Employee != nil {
employeeID = author.Employee.ID.String()
}

rank := &AuthorRanking{}
if discordMemoRank != nil {
rank.DiscordID = discordMemoRank.DiscordID
rank.TotalMemos = discordMemoRank.TotalMemos
rank.Rank = discordMemoRank.Rank
}

authors = append(authors, MemoLogAuthor{
EmployeeID: employeeID,
GithubUsername: author.GithubUsername,
DiscordID: author.DiscordID,
PersonalEmail: author.PersonalEmail,
DiscordUsername: author.DiscordUsername,
MemoUsername: author.MemoUsername,
})
}

rs = append(rs, MemoLog{
ID: memoLog.ID.String(),
Title: memoLog.Title,
URL: memoLog.URL,
Authors: authors,
Description: memoLog.Description,
PublishedAt: memoLog.PublishedAt,
Reward: memoLog.Reward,
Category: memoLog.Category,
})
}

authorRank := AuthorRanking{}
if discordMemoRank != nil {
authorRank = AuthorRanking{
DiscordID: discordMemoRank.DiscordID,
TotalMemos: discordMemoRank.TotalMemos,
Rank: discordMemoRank.Rank,
}
}

return MemoLogsByDiscordID{
MemoLogs: rs,
Rank: authorRank,
}
}

0 comments on commit 181bc98

Please sign in to comment.