diff --git a/pkg/internal/database/migrator.go b/pkg/internal/database/migrator.go index 3ca2a14..3bb6b6f 100644 --- a/pkg/internal/database/migrator.go +++ b/pkg/internal/database/migrator.go @@ -14,6 +14,7 @@ var AutoMaintainRange = []any{ &models.Subscription{}, &models.Poll{}, &models.PollAnswer{}, + &models.PostFlag{}, } func RunMigration(source *gorm.DB) error { diff --git a/pkg/internal/http/api/flags_api.go b/pkg/internal/http/api/flags_api.go new file mode 100644 index 0000000..417b264 --- /dev/null +++ b/pkg/internal/http/api/flags_api.go @@ -0,0 +1,50 @@ +package api + +import ( + "strconv" + "strings" + + "git.solsynth.dev/hypernet/interactive/pkg/internal/database" + "git.solsynth.dev/hypernet/interactive/pkg/internal/models" + "git.solsynth.dev/hypernet/interactive/pkg/internal/services" + "git.solsynth.dev/hypernet/nexus/pkg/nex/sec" + authm "git.solsynth.dev/hypernet/passport/pkg/authkit/models" + "github.com/gofiber/fiber/v2" +) + +func createFlag(c *fiber.Ctx) error { + if err := sec.EnsureGrantedPerm(c, "FlagPost", true); err != nil { + return err + } + user := c.Locals("user").(authm.Account) + + id := c.Params("postId") + + var item models.Post + var err error + + tx := services.FilterPostDraft(database.C) + + if numericId, paramErr := strconv.Atoi(id); paramErr == nil { + item, err = services.GetPost(tx, uint(numericId)) + } else { + segments := strings.Split(id, ":") + if len(segments) != 2 { + return fiber.NewError(fiber.StatusBadRequest, "invalid post id, must be a number or a string with two segment divided by a colon") + } + area := segments[0] + alias := segments[1] + item, err = services.GetPostByAlias(tx, alias, area) + } + + if err != nil { + return fiber.NewError(fiber.StatusNotFound, err.Error()) + } + + flag, err := services.NewFlag(item, user.ID) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } + + return c.JSON(flag) +} diff --git a/pkg/internal/http/api/index.go b/pkg/internal/http/api/index.go index f6e80ba..34b99a0 100644 --- a/pkg/internal/http/api/index.go +++ b/pkg/internal/http/api/index.go @@ -62,6 +62,7 @@ func MapAPIs(app *fiber.App, baseURL string) { posts.Get("/drafts", listDraftPost) posts.Get("/:postId", getPost) posts.Get("/:postId/insight", getPostInsight) + posts.Get("/:postId/flag", createFlag) posts.Post("/:postId/react", reactPost) posts.Post("/:postId/pin", pinPost) posts.Delete("/:postId", deletePost) diff --git a/pkg/internal/models/flags.go b/pkg/internal/models/flags.go new file mode 100644 index 0000000..13a9f88 --- /dev/null +++ b/pkg/internal/models/flags.go @@ -0,0 +1,10 @@ +package models + +import "git.solsynth.dev/hypernet/nexus/pkg/nex/cruda" + +type PostFlag struct { + cruda.BaseModel + + PostID uint `json:"post_id"` + AccountID uint `json:"account_id"` +} diff --git a/pkg/internal/models/posts.go b/pkg/internal/models/posts.go index 3c0baee..7719e54 100644 --- a/pkg/internal/models/posts.go +++ b/pkg/internal/models/posts.go @@ -38,6 +38,7 @@ type Post struct { Categories []Category `json:"categories" gorm:"many2many:post_categories"` Reactions []Reaction `json:"reactions"` Replies []Post `json:"replies" gorm:"foreignKey:ReplyID"` + Flags []PostFlag `json:"flags" gorm:"foreignKey:PostID"` ReplyID *uint `json:"reply_id"` RepostID *uint `json:"repost_id"` ReplyTo *Post `json:"reply_to" gorm:"foreignKey:ReplyID"` diff --git a/pkg/internal/services/flags.go b/pkg/internal/services/flags.go new file mode 100644 index 0000000..c29d5f7 --- /dev/null +++ b/pkg/internal/services/flags.go @@ -0,0 +1,23 @@ +package services + +import ( + "fmt" + + "git.solsynth.dev/hypernet/interactive/pkg/internal/database" + "git.solsynth.dev/hypernet/interactive/pkg/internal/models" +) + +func NewFlag(post models.Post, account uint) (models.PostFlag, error) { + var flag models.PostFlag + if err := database.C.Where("post_id = ? AND account_id = ?", post.ID, account).Error; err == nil { + return flag, fmt.Errorf("flag already exists") + } + flag = models.PostFlag{ + PostID: post.ID, + AccountID: account, + } + if err := database.C.Save(&flag).Error; err != nil { + return flag, err + } + return flag, nil +}