From 0eca2b1e68562295a45a3637dc411d54469d9f95 Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Sun, 15 Feb 2026 19:06:10 +0300 Subject: [PATCH] feat: start develop a comment logic --- .../internal/handlers/comments_handlers.go | 72 +++++++++++++++++++ backend/internal/handlers/post_handlers.go | 1 + .../repositories/comments_repository.go | 1 + backend/internal/repositories/interface.go | 3 + .../internal/repositories/post_repository.go | 22 ++++-- backend/internal/storage/migrations.go | 13 +++- backend/internal/storage/models.go | 28 ++++++++ 7 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 backend/internal/handlers/comments_handlers.go create mode 100644 backend/internal/repositories/comments_repository.go diff --git a/backend/internal/handlers/comments_handlers.go b/backend/internal/handlers/comments_handlers.go new file mode 100644 index 0000000..963ba6b --- /dev/null +++ b/backend/internal/handlers/comments_handlers.go @@ -0,0 +1,72 @@ +package handlers + +import ( + "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/logger" + "github.com/gin-gonic/gin" +) + +type CommentsHandlers struct { + logger *logger.Logger +} + +func NewCommentsHandlers() *CommentsHandlers { + return &CommentsHandlers{logger: logger.New(false)} +} + +// GetAllComments godoc +// @Summary Get all comments +// @Description Get all comments +// @Tags comments +// @Accept json +// @Produce json +// @Success 200 {object} models.SuccessResponse{data=[]storage.Comment} +// @Failure 404 {object} models.ErrorResponse "No Comment found" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Router /comments [get] +func (h *CommentsHandlers) GetAllComments(c *gin.Context) { +} + +// GetCommentsOfPost godoc +// @Summary Get comments of post +// @Description Get comments of post +// @Tags comments +// @Accept json +// @Produce json +// @Param id path int true "Post ID" +// @Success 200 {object} models.SuccessResponse{data=[]storage.Comment} +// @Failure 404 {object} models.ErrorResponse "No Comment found" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Router /posts/{id}/comments [get] +func (h *CommentsHandlers) GetCommentsOfPost(c *gin.Context) { +} + +// CreateComment godoc +// @Summary Create comment +// @Description Create new comment +// @Tags comments +// @Accept json +// @Produce json +// @Param comment body storage.CommentCreate true "Comment data" +// @Security Bearer +// @Success 200 {object} models.SuccessResponse{data=storage.Comment} +// @Failure 400 {object} models.ErrorResponse "Invalid request" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Router /comments [post] +func (h *CommentsHandlers) CreateComment(c *gin.Context) { +} + +// DeleteComment godoc +// @Summary Delete comment +// @Description Delete comment +// @Tags admin +// @Security Bearer +// @Accept json +// @Produce json +// @Param id path int true "Comment ID" +// @Success 200 {object} models.SuccessResponse{data=storage.Comment} +// @Failure 400 {object} models.ErrorResponse "Invalid ID format" +// @Failure 404 {object} models.ErrorResponse "Comment not found" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Router admin/comments/{id} [delete] +func (h *CommentsHandlers) DeleteComment(c *gin.Context) { +} diff --git a/backend/internal/handlers/post_handlers.go b/backend/internal/handlers/post_handlers.go index 8b07f28..fa3696e 100644 --- a/backend/internal/handlers/post_handlers.go +++ b/backend/internal/handlers/post_handlers.go @@ -110,6 +110,7 @@ func (h *PostHandlers) CreatePost(c *gin.Context) { post := storage.Post{ Title: req.Title, Content: req.Content, + Tags: req.Tags, } if err := h.repo.Create(c.Request.Context(), post); err != nil { diff --git a/backend/internal/repositories/comments_repository.go b/backend/internal/repositories/comments_repository.go new file mode 100644 index 0000000..3f43206 --- /dev/null +++ b/backend/internal/repositories/comments_repository.go @@ -0,0 +1 @@ +package repositories diff --git a/backend/internal/repositories/interface.go b/backend/internal/repositories/interface.go index 9ad3de9..d57478c 100644 --- a/backend/internal/repositories/interface.go +++ b/backend/internal/repositories/interface.go @@ -22,3 +22,6 @@ type AuthRepository interface { IsRegistered(ctx context.Context, github_id int) (bool, error) GetUserByGithubID(ctx context.Context, githubID int) (*storage.User, error) } + +type CommentRepository interface { +} diff --git a/backend/internal/repositories/post_repository.go b/backend/internal/repositories/post_repository.go index 475fc5a..cf2b814 100644 --- a/backend/internal/repositories/post_repository.go +++ b/backend/internal/repositories/post_repository.go @@ -70,9 +70,10 @@ func (p *postRepository) GetByID(ctx context.Context, id int) (storage.PostReq, func (p *postRepository) Create(ctx context.Context, post storage.Post) error { query, err := p.db.Exec( - "INSERT INTO posts(title, content) VALUES(?, ?)", + "INSERT INTO posts(title, content) VALUES(?, ?, ?)", post.Title, post.Content, + post.Tags, ) if err != nil { return err @@ -94,7 +95,10 @@ func (p *postRepository) Update(ctx context.Context, id int, post storage.Post) updates = append(updates, "title = ?") args = append(args, post.Title) } - + if post.Tags != "" { + updates = append(updates, "tags = ?") + args = append(args, post.Tags) + } if post.Content != "" { updates = append(updates, "content = ?") args = append(args, post.Content) @@ -145,7 +149,7 @@ func (p *postRepository) IsExist(ctx context.Context, id int) bool { func (p *postRepository) GetAllAdmin(ctx context.Context) ([]storage.PostReq, error) { result := []storage.PostReq{} - rows, err := p.db.Query("SELECT id, title, content FROM posts") + rows, err := p.db.Query("SELECT id, title, content, tags, CREATED_AT FROM posts") if err != nil { p.logger.Error(err.Error()) return nil, err @@ -154,14 +158,18 @@ func (p *postRepository) GetAllAdmin(ctx context.Context) ([]storage.PostReq, er var title string var content string var id int - err := rows.Scan(&id, &title, &content) + var tags string + var createdAt string + err := rows.Scan(&id, &title, &content, &tags, &createdAt) if err != nil { p.logger.Error("error scan: " + err.Error()) } result = append(result, storage.PostReq{ - ID: id, - Title: title, - Content: content, + ID: id, + Title: title, + Content: content, + Tags: tags, + CreatedAt: createdAt, }) } return result, nil diff --git a/backend/internal/storage/migrations.go b/backend/internal/storage/migrations.go index 2255d23..b2cf42a 100644 --- a/backend/internal/storage/migrations.go +++ b/backend/internal/storage/migrations.go @@ -7,7 +7,8 @@ CREATE TABLE IF NOT EXISTS posts( published BOOLEAN DEFAULT 0, content TEXT NOT NULL, CREATED_AT DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME + updated_at DATETIME, + tags TEXT ); CREATE TABLE IF NOT EXISTS users( @@ -17,4 +18,14 @@ CREATE TABLE IF NOT EXISTS users( github_login TEXT, avatar_url TEXT ); + +CREATE TABLE IF NOT EXISTS comments( + id INTEGER PRIMARY KEY AUTOINCREMENT, + post_id INTEGER NOT NULL, + user_id INTEGER, + content TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (post_id) REFERENCES posts(id), + FOREIGN KEY (user_id) REFERENCES users(id) +); ` diff --git a/backend/internal/storage/models.go b/backend/internal/storage/models.go index 85af2b5..2f157cf 100644 --- a/backend/internal/storage/models.go +++ b/backend/internal/storage/models.go @@ -1,11 +1,13 @@ package storage +// Post type Post struct { ID int `db:"id" json:"id"` Title string `db:"title" json:"title"` Published bool `db:"published" json:"published"` Content string `db:"content" json:"content"` CreatedAt string `db:"created_at" json:"created_at"` + Tags string `db:"tags" json:"tags"` } type PostReq struct { @@ -13,14 +15,17 @@ type PostReq struct { Title string `db:"title" json:"title"` Content string `db:"content" json:"content"` CreatedAt string `db:"created" json:"created_at"` + Tags string `db:"tags" json:"tags"` } type PostCreate struct { Title string `db:"title" json:"title"` Published bool `db:"published" json:"published"` Content string `db:"content" json:"content"` + Tags string `db:"tags" json:"tags"` } +// User type User struct { ID int `db:"id" json:"id"` Email string `db:"email" json:"email"` @@ -35,3 +40,26 @@ type UserReg struct { GithubLogin string `json:"login"` AvatarURL string `json:"avatar_url"` } + +// Comment +type Comment struct { + ID int `db:"id" json:"id"` + PostID int `db:"post_id" json:"post_id"` + UserID int `db:"user_id" json:"user_id"` + Content string `db:"content" json:"content"` + CreatedAt string `db:"created_at" json:"created_at"` +} + +type CommentReq struct { + ID int `db:"id" json:"id"` + PostID int `db:"post_id" json:"post_id"` + UserID int `db:"user_id" json:"user_id"` + Content string `db:"content" json:"content"` + CreatedAt string `db:"created_at" json:"created_at"` +} + +type CommentCreate struct { + PostID int `db:"post_id" json:"post_id"` + UserID int `db:"user_id" json:"user_id"` + Content string `db:"content" json:"content"` +}