memo_organizer.go 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package v1
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "github.com/labstack/echo/v4"
  7. "github.com/usememos/memos/internal/util"
  8. "github.com/usememos/memos/store"
  9. )
  10. type MemoOrganizer struct {
  11. MemoID int32 `json:"memoId"`
  12. UserID int32 `json:"userId"`
  13. Pinned bool `json:"pinned"`
  14. }
  15. type UpsertMemoOrganizerRequest struct {
  16. Pinned bool `json:"pinned"`
  17. }
  18. func (s *APIV1Service) registerMemoOrganizerRoutes(g *echo.Group) {
  19. g.POST("/memo/:memoId/organizer", s.CreateMemoOrganizer)
  20. }
  21. // CreateMemoOrganizer godoc
  22. //
  23. // @Summary Organize memo (pin/unpin)
  24. // @Tags memo-organizer
  25. // @Accept json
  26. // @Produce json
  27. // @Param memoId path int true "ID of memo to organize"
  28. // @Param body body UpsertMemoOrganizerRequest true "Memo organizer object"
  29. // @Success 200 {object} store.Memo "Memo information"
  30. // @Failure 400 {object} nil "ID is not a number: %s | Malformatted post memo organizer request"
  31. // @Failure 401 {object} nil "Missing user in session | Unauthorized"
  32. // @Failure 404 {object} nil "Memo not found: %v"
  33. // @Failure 500 {object} nil "Failed to find memo | Failed to upsert memo organizer | Failed to find memo by ID: %v | Failed to compose memo response"
  34. // @Router /api/v1/memo/{memoId}/organizer [POST]
  35. func (s *APIV1Service) CreateMemoOrganizer(c echo.Context) error {
  36. ctx := c.Request().Context()
  37. memoID, err := util.ConvertStringToInt32(c.Param("memoId"))
  38. if err != nil {
  39. return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("memoId"))).SetInternal(err)
  40. }
  41. userID, ok := c.Get(userIDContextKey).(int32)
  42. if !ok {
  43. return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
  44. }
  45. memo, err := s.Store.GetMemo(ctx, &store.FindMemo{
  46. ID: &memoID,
  47. })
  48. if err != nil {
  49. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo").SetInternal(err)
  50. }
  51. if memo == nil {
  52. return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Memo not found: %v", memoID))
  53. }
  54. if memo.CreatorID != userID {
  55. return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
  56. }
  57. request := &UpsertMemoOrganizerRequest{}
  58. if err := json.NewDecoder(c.Request().Body).Decode(request); err != nil {
  59. return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post memo organizer request").SetInternal(err)
  60. }
  61. upsert := &store.MemoOrganizer{
  62. MemoID: memoID,
  63. UserID: userID,
  64. Pinned: request.Pinned,
  65. }
  66. _, err = s.Store.UpsertMemoOrganizer(ctx, upsert)
  67. if err != nil {
  68. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to upsert memo organizer").SetInternal(err)
  69. }
  70. memo, err = s.Store.GetMemo(ctx, &store.FindMemo{
  71. ID: &memoID,
  72. })
  73. if err != nil {
  74. return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to find memo by ID: %v", memoID)).SetInternal(err)
  75. }
  76. if memo == nil {
  77. return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Memo not found: %v", memoID))
  78. }
  79. memoResponse, err := s.convertMemoFromStore(ctx, memo)
  80. if err != nil {
  81. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
  82. }
  83. return c.JSON(http.StatusOK, memoResponse)
  84. }