Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9dce536a4b |
@@ -1,6 +0,0 @@
|
||||
.git
|
||||
docker-compose.yml
|
||||
data/
|
||||
Makefile
|
||||
.env
|
||||
docs/
|
||||
@@ -3,21 +3,18 @@ FROM golang:1.25.6 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
ENV CGO_ENABLED=0
|
||||
ENV GIN_MODE=release
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN go mod tidy
|
||||
RUN go build -ldflags "-s -w" -o backend ./cmd/main.go
|
||||
|
||||
|
||||
FROM alpine:3.23.0
|
||||
RUN adduser -D appuser && apk add --no-cache curl
|
||||
|
||||
COPY --from=builder /app/backend .
|
||||
RUN chown appuser:appuser ./backend
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
RUN apk add --no-cache curl
|
||||
HEALTHCHECK CMD curl --fail http://localhost:8080/health || exit 1
|
||||
CMD ["./backend"]
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
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) {
|
||||
}
|
||||
@@ -110,7 +110,6 @@ 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 {
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/logger"
|
||||
|
||||
"gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/storage"
|
||||
)
|
||||
|
||||
type commentsRepository struct {
|
||||
db *sql.DB
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewCommentsRepository(db *sql.DB) CommentRepository {
|
||||
return &commentsRepository{
|
||||
db: db,
|
||||
logger: logger.New(false),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commentsRepository) CreateComment(
|
||||
ctx context.Context,
|
||||
comment *storage.CommentCreate,
|
||||
) error {
|
||||
_, err := c.db.Exec(
|
||||
"INSERT INTO comments(content, post_id) VALUES(?, ?, ?)",
|
||||
comment.Content,
|
||||
comment.PostID,
|
||||
comment.UserID,
|
||||
)
|
||||
if err != nil {
|
||||
c.logger.Error("error insert: " + err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commentsRepository) GetAllComments(ctx context.Context) ([]storage.Comment, error) {
|
||||
var result []storage.Comment
|
||||
rows, err := c.db.Query("SELECT id, content, post_id, user_id, created_at FROM comments")
|
||||
if err != nil {
|
||||
c.logger.Error("error scan " + err.Error())
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var content string
|
||||
var postID int
|
||||
var userID int
|
||||
var createdAt string
|
||||
err := rows.Scan(&id, &content, &postID, &userID, &createdAt)
|
||||
if err != nil {
|
||||
c.logger.Error("error scan: " + err.Error())
|
||||
}
|
||||
result = append(result, storage.Comment{
|
||||
ID: id,
|
||||
Content: content,
|
||||
PostID: postID,
|
||||
UserID: userID,
|
||||
CreatedAt: createdAt,
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *commentsRepository) GetCommentsOfPost(
|
||||
ctx context.Context,
|
||||
id int,
|
||||
) ([]storage.Comment, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *commentsRepository) DeleteComment(ctx context.Context, id int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commentsRepository) UpdateComment(
|
||||
ctx context.Context,
|
||||
id int,
|
||||
comment *storage.Comment,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
@@ -22,11 +22,3 @@ type AuthRepository interface {
|
||||
IsRegistered(ctx context.Context, github_id int) (bool, error)
|
||||
GetUserByGithubID(ctx context.Context, githubID int) (*storage.User, error)
|
||||
}
|
||||
|
||||
type CommentRepository interface {
|
||||
CreateComment(ctx context.Context, comment *storage.CommentCreate) error
|
||||
GetAllComments(ctx context.Context) ([]storage.Comment, error)
|
||||
GetCommentsOfPost(ctx context.Context, id int) ([]storage.Comment, error)
|
||||
DeleteComment(ctx context.Context, id int) error
|
||||
UpdateComment(ctx context.Context, id int, comment *storage.Comment) error
|
||||
}
|
||||
|
||||
@@ -70,10 +70,9 @@ 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
|
||||
@@ -95,10 +94,7 @@ 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)
|
||||
@@ -149,7 +145,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, tags, CREATED_AT FROM posts")
|
||||
rows, err := p.db.Query("SELECT id, title, content FROM posts")
|
||||
if err != nil {
|
||||
p.logger.Error(err.Error())
|
||||
return nil, err
|
||||
@@ -158,9 +154,7 @@ func (p *postRepository) GetAllAdmin(ctx context.Context) ([]storage.PostReq, er
|
||||
var title string
|
||||
var content string
|
||||
var id int
|
||||
var tags string
|
||||
var createdAt string
|
||||
err := rows.Scan(&id, &title, &content, &tags, &createdAt)
|
||||
err := rows.Scan(&id, &title, &content)
|
||||
if err != nil {
|
||||
p.logger.Error("error scan: " + err.Error())
|
||||
}
|
||||
@@ -168,8 +162,6 @@ func (p *postRepository) GetAllAdmin(ctx context.Context) ([]storage.PostReq, er
|
||||
ID: id,
|
||||
Title: title,
|
||||
Content: content,
|
||||
Tags: tags,
|
||||
CreatedAt: createdAt,
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
|
||||
@@ -7,8 +7,7 @@ CREATE TABLE IF NOT EXISTS posts(
|
||||
published BOOLEAN DEFAULT 0,
|
||||
content TEXT NOT NULL,
|
||||
CREATED_AT DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME,
|
||||
tags TEXT
|
||||
updated_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users(
|
||||
@@ -18,14 +17,4 @@ 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)
|
||||
);
|
||||
`
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
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 {
|
||||
@@ -15,17 +13,14 @@ 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"`
|
||||
@@ -40,26 +35,3 @@ 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"`
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Makefile
|
||||
dist
|
||||
node_modules
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "daisyui";
|
||||
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
color: oklch(var(--bc));
|
||||
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
color: oklch(var(--bc));
|
||||
background-color: oklch(var(--b1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user