Skip to content

Commit

Permalink
feat: add GET Search Feed Name API
Browse files Browse the repository at this point in the history
  • Loading branch information
slowhigh committed Jun 4, 2024
1 parent 0d52c0e commit 38f5e0b
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 29 deletions.
6 changes: 5 additions & 1 deletion cmd/server/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions infra/database/repository/feed_repo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package repository

import (
"fmt"
"strings"

"github.com/team-nerd-planet/api-server/infra/database"
"github.com/team-nerd-planet/api-server/internal/entity"
)

type FeedRepo struct {
db *database.Database
}

func NewFeedRepo(db *database.Database) entity.FeedRepo {
return &FeedRepo{
db: db,
}
}

// FindAll implements entity.FeedRepo.
func (fr *FeedRepo) FindAll(keyword *string) ([]entity.Feed, error) {
var (
feeds []entity.Feed
where = make([]string, 0)
param = make([]interface{}, 0)
)

if keyword != nil {
where = append(where, "name LIKE ?")
param = append(param, fmt.Sprintf("%s%%", *keyword))
}

err := fr.db.
Where(strings.Join(where, " AND "), param...).
Order("name").
Find(&feeds).Error

return feeds, err
}
2 changes: 1 addition & 1 deletion infra/database/repository/item_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (clr *ItemRepo) CountView(company *string, companySizes *[]entity.CompanySi

if company != nil {
where = append(where, "feed_name LIKE ?")
param = append(param, fmt.Sprintf("%%%s%%", *company))
param = append(param, fmt.Sprintf("%s%%", *company))
}

if companySizes != nil {
Expand Down
1 change: 1 addition & 0 deletions infra/infra.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ var InfraSet = wire.NewSet(
repository.NewJobTagRepo,
repository.NewSkillTagRepo,
repository.NewSubscriptionRepo,
repository.NewFeedRepo,
)
39 changes: 39 additions & 0 deletions infra/router/handler/feed_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package handler

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/team-nerd-planet/api-server/infra/router/util"
"github.com/team-nerd-planet/api-server/internal/controller/rest"
"github.com/team-nerd-planet/api-server/internal/controller/rest/dto/feed_dto"
)

// SearchFeedName
//
// @Summary Search Feed Name
// @Description search feed's name
// @Tags feed
// @Schemes http
// @Accept json
// @Produce json
// @Param name_keyword query string false "회사 이름 검색 키워드"
// @Success 200 {object} []feed_dto.SearchRes
// @Failure 400 {object} util.HTTPError
// @Failure 500 {object} util.HTTPError
// @Router /v1/feed/search [get]
func SearchFeedName(c *gin.Context, ctrl rest.FeedController) {
req, err := util.ValidateQuery[feed_dto.SearchReq](c)
if err != nil {
util.NewError(c, http.StatusBadRequest, err)
return
}

res, ok := ctrl.Search(*req)
if !ok {
util.NewError(c, http.StatusInternalServerError)
return
}

c.JSON(http.StatusOK, res)
}
1 change: 0 additions & 1 deletion infra/router/handler/item_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
// @Param page query int true "페이지"
// @Success 200 {object} dto.Paginated[[]item_dto.FindAllItemRes]
// @Failure 400 {object} util.HTTPError
// @Failure 404 {object} util.HTTPError
// @Failure 500 {object} util.HTTPError
// @Router /v1/item [get]
func ListItems(c *gin.Context, ctrl rest.ItemController) {
Expand Down
25 changes: 18 additions & 7 deletions infra/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ type Router struct {
conf *config.Config
}

func NewRouter(conf *config.Config, itemCtrl rest.ItemController, tagCtrl rest.TagController, subscriptionCtrl rest.SubscriptionController) Router {
func NewRouter(
conf *config.Config,
itemCtrl rest.ItemController,
tagCtrl rest.TagController,
subscriptionCtrl rest.SubscriptionController,
feedCtrl rest.FeedController,
) Router {
if conf.Rest.Mode == "release" {
gin.SetMode(gin.ReleaseMode)
}
Expand All @@ -39,20 +45,25 @@ func NewRouter(conf *config.Config, itemCtrl rest.ItemController, tagCtrl rest.T

item := v1.Group("/item")
{
item.GET("/", cache.CachePage(s, time.Hour, func(c *gin.Context) { handler.ListItems(c, itemCtrl) }))
item.GET("/", cache.CachePage(s, time.Hour, func(ctx *gin.Context) { handler.ListItems(ctx, itemCtrl) }))
}

tag := v1.Group("/tag")
{
tag.GET("/job", cache.CachePage(s, time.Hour, func(c *gin.Context) { handler.ListJobTags(c, tagCtrl) }))
tag.GET("/skill", cache.CachePage(s, time.Hour, func(c *gin.Context) { handler.ListSkillTags(c, tagCtrl) }))
tag.GET("/job", cache.CachePage(s, time.Hour, func(ctx *gin.Context) { handler.ListJobTags(ctx, tagCtrl) }))
tag.GET("/skill", cache.CachePage(s, time.Hour, func(ctx *gin.Context) { handler.ListSkillTags(ctx, tagCtrl) }))
}

subscription := v1.Group("/subscription")
{
subscription.POST("/apply", func(c *gin.Context) { handler.Apply(c, subscriptionCtrl) })
subscription.GET("/approve", func(c *gin.Context) { handler.ApproveGet(c, subscriptionCtrl) })
subscription.POST("/approve", func(c *gin.Context) { handler.Approve(c, subscriptionCtrl) })
subscription.POST("/apply", func(ctx *gin.Context) { handler.Apply(ctx, subscriptionCtrl) })
subscription.GET("/approve", func(ctx *gin.Context) { handler.ApproveGet(ctx, subscriptionCtrl) })
subscription.POST("/approve", func(ctx *gin.Context) { handler.Approve(ctx, subscriptionCtrl) })
}

feed := v1.Group("/feed")
{
feed.GET("/search", func(ctx *gin.Context) { handler.SearchFeedName(ctx, feedCtrl) })
}
}

Expand Down
7 changes: 6 additions & 1 deletion internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ import (
"github.com/team-nerd-planet/api-server/internal/controller/rest"
)

var ControllerSet = wire.NewSet(rest.NewItemController, rest.NewTagController, rest.NewSubscriptionController)
var ControllerSet = wire.NewSet(
rest.NewItemController,
rest.NewTagController,
rest.NewSubscriptionController,
rest.NewFeedController,
)
25 changes: 25 additions & 0 deletions internal/controller/rest/dto/feed_dto/search_dto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package feed_dto

import "github.com/team-nerd-planet/api-server/internal/entity"

type SearchReq struct {
NameKeyword string `form:"name_keyword" binding:"min=1"` // 회사 이름 검색어
}

type SearchRes struct {
ID uint `json:"id"`
Name string `json:"name"`
}

func NewSearchRes(feeds []entity.Feed) []SearchRes {
res := make([]SearchRes, len(feeds))

for i, feed := range feeds {
res[i] = SearchRes{
ID: feed.ID,
Name: feed.Name,
}
}

return res
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ type ApproveReq struct {

type ApproveRes struct {
Ok bool `json:"ok"` // 구독 인증 결과
}
}
27 changes: 27 additions & 0 deletions internal/controller/rest/feed_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package rest

import (
"github.com/team-nerd-planet/api-server/internal/controller/rest/dto/feed_dto"
"github.com/team-nerd-planet/api-server/internal/usecase/feed"
)

type FeedController struct {
feedUcase feed.FeedUsecase
}

func NewFeedController(feedUsecase feed.FeedUsecase) FeedController {
return FeedController{
feedUcase: feedUsecase,
}
}

func (fc FeedController) Search(req feed_dto.SearchReq) ([]feed_dto.SearchRes, bool) {
res := make([]feed_dto.SearchRes, 0)

feeds, ok := fc.feedUcase.FindAll(&req.NameKeyword)
if !ok {
return res, false
}

return feed_dto.NewSearchRes(*feeds), true
}
4 changes: 4 additions & 0 deletions internal/entity/feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ type Feed struct {
RssID uint `gorm:"column:rss_id;type:int8;not null"`
Items []Item `gorm:"foreignKey:FeedID"`
}

type FeedRepo interface {
FindAll(keyword *string) ([]Feed, error)
}
27 changes: 27 additions & 0 deletions internal/usecase/feed/feed_ucase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package feed

import (
"log/slog"

"github.com/team-nerd-planet/api-server/internal/entity"
)

type FeedUsecase struct {
feedRepo entity.FeedRepo
}

func NewFeedUsecase(feedRepo entity.FeedRepo) FeedUsecase {
return FeedUsecase{
feedRepo: feedRepo,
}
}

func (fu FeedUsecase) FindAll(keyword *string) (*[]entity.Feed, bool) {
feeds, err := fu.feedRepo.FindAll(keyword)
if err != nil {
slog.Error(err.Error(), "error", err)
return nil, false
}

return &feeds, true
}
9 changes: 8 additions & 1 deletion internal/usecase/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package usecase

import (
"github.com/google/wire"
"github.com/team-nerd-planet/api-server/internal/usecase/feed"
"github.com/team-nerd-planet/api-server/internal/usecase/item"
"github.com/team-nerd-planet/api-server/internal/usecase/subscription"
"github.com/team-nerd-planet/api-server/internal/usecase/tag"
)

var UsecaseSet = wire.NewSet(item.NewItemUsecase, tag.NewJobTagUsecase, tag.NewSkillTagUsecase, subscription.NewSubscriptionUsecase)
var UsecaseSet = wire.NewSet(
item.NewItemUsecase,
tag.NewJobTagUsecase,
tag.NewSkillTagUsecase,
subscription.NewSubscriptionUsecase,
feed.NewFeedUsecase,
)
63 changes: 57 additions & 6 deletions third_party/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,52 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/v1/feed/search": {
"get": {
"description": "search feed's name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"feed"
],
"summary": "Search Feed Name",
"parameters": [
{
"type": "string",
"description": "회사 이름 검색 키워드",
"name": "name_keyword",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/github_com_team-nerd-planet_api-server_internal_controller_rest_dto_feed_dto.SearchRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/github_com_team-nerd-planet_api-server_infra_router_util.HTTPError"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/github_com_team-nerd-planet_api-server_infra_router_util.HTTPError"
}
}
}
}
},
"/v1/item": {
"get": {
"description": "list items",
Expand Down Expand Up @@ -93,12 +139,6 @@ const docTemplate = `{
"$ref": "#/definitions/github_com_team-nerd-planet_api-server_infra_router_util.HTTPError"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/github_com_team-nerd-planet_api-server_infra_router_util.HTTPError"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
Expand Down Expand Up @@ -327,6 +367,17 @@ const docTemplate = `{
}
}
},
"github_com_team-nerd-planet_api-server_internal_controller_rest_dto_feed_dto.SearchRes": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"github_com_team-nerd-planet_api-server_internal_controller_rest_dto_item_dto.FindAllItemRes": {
"type": "object",
"properties": {
Expand Down
Loading

0 comments on commit 38f5e0b

Please sign in to comment.