diff --git a/api/common.go b/api/common.go index 3fccfdad..85d22909 100644 --- a/api/common.go +++ b/api/common.go @@ -3,8 +3,16 @@ package pnd import ( "encoding/json" "net/http" + + "github.com/google/uuid" ) +type CursorPaginatedView[T interface{}] struct { + Items []T `json:"items"` + Prev uuid.NullUUID `json:"prev"` + Next uuid.NullUUID `json:"next"` +} + type PaginatedView[T interface{}] struct { Page int `json:"page"` Size int `json:"size"` @@ -32,7 +40,12 @@ func (l *PaginatedView[T]) CalcLastPage() { } } -func writePayload(w http.ResponseWriter, headers map[string]string, payload interface{}, statusCode int) error { +func writePayload( + w http.ResponseWriter, + headers map[string]string, + payload interface{}, + statusCode int, +) error { setHeaders(w, headers) w.WriteHeader(statusCode) diff --git a/cmd/server/handler/event_handler.go b/cmd/server/handler/event_handler.go new file mode 100644 index 00000000..681cb9f5 --- /dev/null +++ b/cmd/server/handler/event_handler.go @@ -0,0 +1,158 @@ +package handler + +import ( + "fmt" + "net/http" + + "github.com/google/uuid" + "github.com/labstack/echo/v4" + pnd "github.com/pet-sitter/pets-next-door-api/api" + "github.com/pet-sitter/pets-next-door-api/internal/domain/event" + "github.com/pet-sitter/pets-next-door-api/internal/service" +) + +type EventHandler struct { + authService service.AuthService +} + +func NewEventHandler(authService service.AuthService) *EventHandler { + return &EventHandler{ + authService: authService, + } +} + +func generateDummyEvent() event.ListView { + return event.ListView{ + ID: uuid.New(), + } +} + +// FindEvents godoc +// @Summary 이벤트를 조회합니다. +// @Description +// @Tags events +// @Accept json +// @Produce json +// @Param author_id query string false "작성자 ID" +// @Param page query int false "페이지 번호" default(1) +// @Param size query int false "페이지 사이즈" default(20) +// @Success 200 {object} pnd.CursorPaginatedView[event.ListView] +// @Router /events [get] +func (h *EventHandler) FindEvents(c echo.Context) error { + return c.JSON( + http.StatusOK, + pnd.CursorPaginatedView[event.ListView]{Items: []event.ListView{generateDummyEvent()}}, + ) +} + +// FindEventByID godoc +// @Summary ID로 이벤트를 조회합니다. +// @Description +// @Tags events +// @Produce json +// @Param id path int true "이벤트 ID" +// @Success 200 {object} event.DetailView +// @Router /events [get] +func (h *EventHandler) FindEventByID(c echo.Context) error { + id, err := pnd.ParseIDFromPath(c, "id") + if err != nil { + return c.JSON(err.StatusCode, err) + } + + res := event.DetailView{ + ID: id, + } + + return c.JSON(http.StatusOK, res) +} + +// CreateEvent godoc +// @Summary 이벤트를 생성합니다. +// @Description +// @Tags events +// @Accept json +// @Produce json +// @Param request body event.CreateRequest true "이벤트 생성 요청" +// @Security FirebaseAuth +// @Success 201 {object} event.DetailView +// @Router /events [post] +func (h *EventHandler) CreateEvent(c echo.Context) error { + foundUser, err := h.authService.VerifyAuthAndGetUser( + c.Request().Context(), + c.Request().Header.Get("Authorization"), + ) + if err != nil { + return c.JSON(err.StatusCode, err) + } + uid := foundUser.FirebaseUID + + var reqBody event.CreateRequest + if err := pnd.ParseBody(c, &reqBody); err != nil { + return c.JSON(err.StatusCode, err) + } + + fmt.Println(reqBody, uid) + // TODO: Implement create event logic + + return c.JSON(http.StatusCreated, event.DetailView{ID: uuid.New()}) +} + +// UpdateEvent godoc +// @Summary 이벤트를 수정합니다. +// @Description +// @Tags events +// @Accept json +// @Produce json +// @Security FirebaseAuth +// @Param request body event.UpdateRequest true "이벤트 수정 요청" +// @Success 200 +// @Router /events [put] +func (h *EventHandler) UpdateEvent(c echo.Context) error { + foundUser, err := h.authService.VerifyAuthAndGetUser( + c.Request().Context(), + c.Request().Header.Get("Authorization"), + ) + if err != nil { + return c.JSON(err.StatusCode, err) + } + uid := foundUser.FirebaseUID + + var reqBody event.UpdateRequest + if err := pnd.ParseBody(c, &reqBody); err != nil { + return c.JSON(err.StatusCode, err) + } + + fmt.Println(reqBody, uid) + // TODO: Implement update event logic + + return c.JSON(http.StatusOK, nil) +} + +// DeleteEvent godoc +// @Summary 이벤트를 삭제합니다. +// @Description +// @Tags events +// @Security FirebaseAuth +// @Param id path int true "이벤트 ID" +// @Success 200 +// @Router /events/{id} [delete] +func (h *EventHandler) DeleteEvent(c echo.Context) error { + foundUser, err := h.authService.VerifyAuthAndGetUser( + c.Request().Context(), + c.Request().Header.Get("Authorization"), + ) + if err != nil { + return c.JSON(err.StatusCode, err) + } + uid := foundUser.FirebaseUID + + id, err := pnd.ParseIDFromPath(c, "id") + if err != nil { + return c.JSON(err.StatusCode, err) + } + + fmt.Println(id, uid) + // TODO: Implement delete event logic + + return c.JSON(http.StatusOK, nil) +} diff --git a/cmd/server/router.go b/cmd/server/router.go index 6476801e..a8671372 100644 --- a/cmd/server/router.go +++ b/cmd/server/router.go @@ -65,6 +65,7 @@ func NewRouter(app *firebaseinfra.FirebaseApp) (*echo.Echo, error) { sosPostHandler := handler.NewSOSPostHandler(*sosPostService, authService) conditionHandler := handler.NewConditionHandler(*conditionService) chatHandler := handler.NewChatHandler(authService, *chatService) + eventHandler := handler.NewEventHandler(authService) // // InMemoryStateManager는 클라이언트와 채팅방의 상태를 메모리에 저장하고 관리합니다. // // 이 메서드는 단순하고 빠르며 테스트 목적으로 적합합니다. @@ -143,6 +144,15 @@ func NewRouter(app *firebaseinfra.FirebaseApp) (*echo.Echo, error) { postAPIGroup.GET("/sos/conditions", conditionHandler.FindConditions) } + eventAPIGroup := apiRouteGroup.Group("/events") + { + eventAPIGroup.GET("", eventHandler.FindEvents) + eventAPIGroup.GET("/:id", eventHandler.FindEventByID) + eventAPIGroup.POST("", eventHandler.CreateEvent) + eventAPIGroup.PUT("/:id", eventHandler.UpdateEvent) + eventAPIGroup.DELETE("/:id", eventHandler.DeleteEvent) + } + upgrader := wschat.NewDefaultUpgrader() wsServerV2 := wschat.NewWSServer(upgrader, authService, *mediaService) diff --git a/internal/domain/event/request.go b/internal/domain/event/request.go new file mode 100644 index 00000000..1f0ba664 --- /dev/null +++ b/internal/domain/event/request.go @@ -0,0 +1,5 @@ +package event + +type CreateRequest struct{} + +type UpdateRequest struct{} diff --git a/internal/domain/event/view.go b/internal/domain/event/view.go new file mode 100644 index 00000000..9be9bb8d --- /dev/null +++ b/internal/domain/event/view.go @@ -0,0 +1,12 @@ +package event + +import "github.com/google/uuid" + +type DetailView struct { + ID uuid.UUID `json:"id"` +} + +type ListView struct { + ID uuid.UUID `json:"id"` +} +