Compare commits
No commits in common. "5b18009658b5d56e945384558a8cc3a32e31b788" and "c0cb8269173e0a3b3158bc00c6f6d5d488ee953a" have entirely different histories.
5b18009658
...
c0cb826917
38 changed files with 185 additions and 1185 deletions
|
|
@ -5,11 +5,9 @@ allow:
|
||||||
|
|
||||||
components:
|
components:
|
||||||
domain: { in: internal/domain/** }
|
domain: { in: internal/domain/** }
|
||||||
repository: {in: internal/domain/repository/**}
|
|
||||||
application: { in: internal/application/** }
|
application: { in: internal/application/** }
|
||||||
commands: { in: internal/application/}
|
|
||||||
infrastructure: { in: internal/infrastructure/** }
|
infrastructure: { in: internal/infrastructure/** }
|
||||||
interface: { in: internal/interfaces/** }
|
interface: { in: internal/interface/** }
|
||||||
cmd: {in: cmd/**}
|
cmd: {in: cmd/**}
|
||||||
|
|
||||||
commonComponents:
|
commonComponents:
|
||||||
|
|
|
||||||
48
cmd/main.go
48
cmd/main.go
|
|
@ -4,33 +4,28 @@ package main
|
||||||
// @version 1.0
|
// @version 1.0
|
||||||
// @description 58team blog's backend
|
// @description 58team blog's backend
|
||||||
// @termsOfService http://swagger.io/terms/
|
// @termsOfService http://swagger.io/terms/
|
||||||
|
|
||||||
// @contact.name API Support
|
// @contact.name API Support
|
||||||
// @contact.url http://www.swagger.io/support
|
// @contact.url http://www.swagger.io/support
|
||||||
// @contact.email support@swagger.io
|
// @contact.email support@swagger.io
|
||||||
|
|
||||||
// @license.name Apache 2.0
|
// @license.name Apache 2.0
|
||||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
// @host localhost:8080
|
// @host localhost:8080
|
||||||
// @BasePath /api/v1
|
// @BasePath /api/v1
|
||||||
|
|
||||||
// @securityDefinitions.basic BasicAuth
|
// @securityDefinitions.basic BasicAuth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
docs "58team_blog/docs"
|
"58team_blog/docs"
|
||||||
"58team_blog/internal/application/services"
|
|
||||||
"58team_blog/internal/infrastructure"
|
|
||||||
"58team_blog/internal/infrastructure/db"
|
|
||||||
"58team_blog/internal/infrastructure/db/repo"
|
|
||||||
"58team_blog/internal/interfaces"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
swaggerFiles "github.com/swaggo/files"
|
"github.com/swaggo/files"
|
||||||
ginSwagger "github.com/swaggo/gin-swagger"
|
"github.com/swaggo/gin-swagger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
|
|
||||||
// Swagger setup
|
|
||||||
docs.SwaggerInfo.Title = "58team blog"
|
docs.SwaggerInfo.Title = "58team blog"
|
||||||
docs.SwaggerInfo.Description = "This is blog 58team"
|
docs.SwaggerInfo.Description = "This is blog 58team"
|
||||||
docs.SwaggerInfo.Version = "1.0"
|
docs.SwaggerInfo.Version = "1.0"
|
||||||
|
|
@ -38,33 +33,6 @@ func main() {
|
||||||
docs.SwaggerInfo.BasePath = "/api/v1/"
|
docs.SwaggerInfo.BasePath = "/api/v1/"
|
||||||
docs.SwaggerInfo.Schemes = []string{"http", "https"}
|
docs.SwaggerInfo.Schemes = []string{"http", "https"}
|
||||||
|
|
||||||
// router.GET("/swagger/*any", func(c *gin.Context) {
|
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
// path := c.Param("any")
|
|
||||||
// if strings.HasPrefix(path, "/doc.json") {
|
|
||||||
// c.File("docs/swagger.json")
|
|
||||||
// } else {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.URL("http://localhost:8080/swag/doc/doc.json")))
|
|
||||||
router.StaticFile("/swag/doc/doc.json", "docs/swagger.json")
|
|
||||||
|
|
||||||
// Routes setup
|
|
||||||
g := router.Group("/api/v1")
|
|
||||||
|
|
||||||
config, err := infrastructure.LoadConfig()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Load config error: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := db.DatabaseInit(*config)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Database error: ", err)
|
|
||||||
}
|
|
||||||
postRepository := repo.CreatePostRepository(d)
|
|
||||||
|
|
||||||
postService := services.CreatePostService(&postRepository)
|
|
||||||
interfaces.BindPostAdmin(&postService, g)
|
|
||||||
|
|
||||||
router.Run(":8080")
|
router.Run(":8080")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
config.yaml
10
config.yaml
|
|
@ -1,10 +0,0 @@
|
||||||
db-user: userpg
|
|
||||||
db-name: 58blog
|
|
||||||
db-password: 1205
|
|
||||||
db-host: localhost
|
|
||||||
db-port: 5432
|
|
||||||
admin_name: muts
|
|
||||||
admin_pass: 1205
|
|
||||||
images_path: ./images/
|
|
||||||
posts_path: ./posts/
|
|
||||||
|
|
||||||
32
docs/docs.go
32
docs/docs.go
|
|
@ -1,11 +1,35 @@
|
||||||
// Code generated by swaggo/swag. DO NOT EDIT.
|
// Package docs Code generated by swaggo/swag. DO NOT EDIT
|
||||||
|
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import "github.com/swaggo/swag/v2"
|
import "github.com/swaggo/swag"
|
||||||
|
|
||||||
const docTemplate = `{
|
const docTemplate = `{
|
||||||
"schemes": {{ marshal .Schemes }},"swagger":"2.0","info":{"description":"{{escape .Description}}","title":"{{.Title}}","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"{{.Version}}"},"host":"{{.Host}}","basePath":"{{.BasePath}}","paths":{"/images/{path}":{"get":{"description":"get image by path","produces":["image/png","image/jpeg"],"summary":"Get an image by path","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}}}}},"/post/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}}`
|
"schemes": {{ marshal .Schemes }},
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "{{escape .Description}}",
|
||||||
|
"title": "{{.Title}}",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "{{.Version}}"
|
||||||
|
},
|
||||||
|
"host": "{{.Host}}",
|
||||||
|
"basePath": "{{.BasePath}}",
|
||||||
|
"paths": {},
|
||||||
|
"securityDefinitions": {
|
||||||
|
"BasicAuth": {
|
||||||
|
"type": "basic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
var SwaggerInfo = &swag.Spec{
|
var SwaggerInfo = &swag.Spec{
|
||||||
|
|
|
||||||
|
|
@ -1 +1,26 @@
|
||||||
{"swagger":"2.0","info":{"description":"58team blog's backend","title":"58team blog backend","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"1.0"},"host":"localhost:8080","basePath":"/api/v1","paths":{"/images/{path}":{"get":{"description":"get image by path","produces":["image/png","image/jpeg"],"summary":"Get an image by path","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}}}}},"/post/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}}
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "58team blog's backend",
|
||||||
|
"title": "58team blog backend",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "1.0"
|
||||||
|
},
|
||||||
|
"host": "localhost:8080",
|
||||||
|
"basePath": "/api/v1",
|
||||||
|
"paths": {},
|
||||||
|
"securityDefinitions": {
|
||||||
|
"BasicAuth": {
|
||||||
|
"type": "basic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,59 +1,4 @@
|
||||||
basePath: /api/v1
|
basePath: /api/v1
|
||||||
definitions:
|
|
||||||
requests.CreatePostRequest:
|
|
||||||
properties:
|
|
||||||
content:
|
|
||||||
minLength: 36
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 8
|
|
||||||
type: string
|
|
||||||
title:
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 8
|
|
||||||
type: string
|
|
||||||
userId:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- content
|
|
||||||
- description
|
|
||||||
- title
|
|
||||||
- userId
|
|
||||||
type: object
|
|
||||||
responses.ErrorResponse:
|
|
||||||
properties:
|
|
||||||
error_code:
|
|
||||||
type: integer
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
responses.GetListPostResponseItem:
|
|
||||||
properties:
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
responses.PostResponse:
|
|
||||||
properties:
|
|
||||||
content:
|
|
||||||
type: string
|
|
||||||
createdAt:
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
updatedAt:
|
|
||||||
type: string
|
|
||||||
userId:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
host: localhost:8080
|
host: localhost:8080
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
|
|
@ -67,123 +12,7 @@ info:
|
||||||
termsOfService: http://swagger.io/terms/
|
termsOfService: http://swagger.io/terms/
|
||||||
title: 58team blog backend
|
title: 58team blog backend
|
||||||
version: "1.0"
|
version: "1.0"
|
||||||
paths:
|
paths: {}
|
||||||
/images/{path}:
|
|
||||||
get:
|
|
||||||
description: get image by path
|
|
||||||
parameters:
|
|
||||||
- description: Path to image
|
|
||||||
in: query
|
|
||||||
name: path
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- image/png
|
|
||||||
- image/jpeg
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
summary: Get an image by path
|
|
||||||
/post:
|
|
||||||
get:
|
|
||||||
description: Return first 5 posts
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/responses.GetListPostResponseItem'
|
|
||||||
type: array
|
|
||||||
summary: Get all posts
|
|
||||||
tags:
|
|
||||||
- post
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: Create new post in blog
|
|
||||||
parameters:
|
|
||||||
- description: Post data
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/requests.CreatePostRequest'
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/responses.PostResponse'
|
|
||||||
"400":
|
|
||||||
description: Bad Request
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/responses.ErrorResponse'
|
|
||||||
summary: Create new post
|
|
||||||
tags:
|
|
||||||
- post
|
|
||||||
/post/{id}:
|
|
||||||
get:
|
|
||||||
description: get post by id
|
|
||||||
parameters:
|
|
||||||
- description: Id of post
|
|
||||||
in: query
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/responses.PostResponse'
|
|
||||||
type: array
|
|
||||||
summary: Get post by id
|
|
||||||
tags:
|
|
||||||
- post
|
|
||||||
put:
|
|
||||||
description: update post content
|
|
||||||
parameters:
|
|
||||||
- description: Id of post
|
|
||||||
in: query
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/responses.PostResponse'
|
|
||||||
summary: Update post content
|
|
||||||
tags:
|
|
||||||
- post
|
|
||||||
/post/{offset}:
|
|
||||||
get:
|
|
||||||
description: return 5 posts after first offset posts
|
|
||||||
parameters:
|
|
||||||
- description: Offset of posts
|
|
||||||
in: query
|
|
||||||
name: offset
|
|
||||||
required: true
|
|
||||||
type: integer
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/responses.GetListPostResponseItem'
|
|
||||||
type: array
|
|
||||||
summary: Get posts after offset
|
|
||||||
tags:
|
|
||||||
- post
|
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
BasicAuth:
|
BasicAuth:
|
||||||
type: basic
|
type: basic
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 60 KiB |
14
go.mod
14
go.mod
|
|
@ -16,13 +16,12 @@ require (
|
||||||
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
|
||||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.10.1 // indirect
|
github.com/gin-gonic/gin v1.10.1 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
github.com/go-openapi/spec v0.20.9 // indirect
|
github.com/go-openapi/spec v0.20.4 // indirect
|
||||||
github.com/go-openapi/swag v0.22.3 // indirect
|
github.com/go-openapi/swag v0.19.15 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator v9.31.0+incompatible // indirect
|
|
||||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
|
|
@ -34,12 +33,11 @@ require (
|
||||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/lib/pq v1.10.9 // indirect
|
github.com/lib/pq v1.10.9 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.6 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
|
||||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||||
github.com/spf13/afero v1.15.0 // indirect
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
|
|
@ -47,11 +45,9 @@ require (
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/spf13/viper v1.21.0 // indirect
|
github.com/spf13/viper v1.21.0 // indirect
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/sv-tools/openapi v0.2.1 // indirect
|
|
||||||
github.com/swaggo/files v1.0.1 // indirect
|
github.com/swaggo/files v1.0.1 // indirect
|
||||||
github.com/swaggo/gin-swagger v1.6.1 // indirect
|
github.com/swaggo/gin-swagger v1.6.1 // indirect
|
||||||
github.com/swaggo/swag v1.16.6 // indirect
|
github.com/swaggo/swag v1.16.6 // indirect
|
||||||
github.com/swaggo/swag/v2 v2.0.0-rc4 // indirect
|
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
|
|
|
||||||
21
go.sum
21
go.sum
|
|
@ -31,28 +31,17 @@ github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
|
||||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
|
||||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
|
||||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
|
||||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
|
||||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA=
|
|
||||||
github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig=
|
|
||||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
|
@ -76,7 +65,6 @@ github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzh
|
||||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
|
@ -88,8 +76,6 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
|
|
@ -101,8 +87,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||||
|
|
@ -127,8 +111,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA=
|
|
||||||
github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg=
|
|
||||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY=
|
github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY=
|
||||||
|
|
@ -137,8 +119,6 @@ github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w=
|
||||||
github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
|
github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
|
||||||
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
|
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
|
||||||
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
|
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
|
||||||
github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY=
|
|
||||||
github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE=
|
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||||
|
|
@ -197,7 +177,6 @@ google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,18 @@ import (
|
||||||
"58team_blog/internal/application/queries"
|
"58team_blog/internal/application/queries"
|
||||||
"58team_blog/internal/domain/entities"
|
"58team_blog/internal/domain/entities"
|
||||||
"58team_blog/internal/domain/repository"
|
"58team_blog/internal/domain/repository"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PostService struct {
|
type PostService struct {
|
||||||
repo repository.PostRepository
|
repo repository.PostRepository
|
||||||
|
postsService PostsService
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePostService(repo repository.PostRepository) PostService {
|
func CreatePostService(repo repository.PostRepository, postsService PostsService) PostService {
|
||||||
return PostService{
|
return PostService{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
postsService: postsService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@ func (s *PostService) Create(cmd commands.CreatePostCommand) (*common.PostResult
|
||||||
|
|
||||||
post, err := s.repo.Create(&entity)
|
post, err := s.repo.Create(&entity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Db error: %s", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := mapper.CreatePostResultFromEntity(post)
|
result := mapper.CreatePostResultFromEntity(post)
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,12 @@ const PostTable = "post"
|
||||||
|
|
||||||
type Post struct {
|
type Post struct {
|
||||||
Id uuid.UUID `db:"id"`
|
Id uuid.UUID `db:"id"`
|
||||||
UserId uuid.UUID `db:"userid"`
|
UserId uuid.UUID `db:"user_id"`
|
||||||
Title string `db:"title"`
|
Title string `db:"title"`
|
||||||
Description string `db:"description"`
|
Description string `db:"description"`
|
||||||
Content string `db:"content"`
|
Content string `db:"content"`
|
||||||
CreatedAt time.Time `db:"createdat"`
|
CreatedAt time.Time `db:"createdAt"`
|
||||||
UpdatedAt time.Time `db:"updatedat"`
|
UpdatedAt time.Time `db:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePost(userId uuid.UUID, title string, description string, content string) (post Post, err error) {
|
func CreatePost(userId uuid.UUID, title string, description string, content string) (post Post, err error) {
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ type Config struct {
|
||||||
PostsPath string `mapstructure:"posts_path" default:"./posts/"`
|
PostsPath string `mapstructure:"posts_path" default:"./posts/"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig() (config *Config, err error) {
|
func LoadConfig() (config Config, err error) {
|
||||||
config = &Config{}
|
config = Config{}
|
||||||
if err = defaults.Set(config); err != nil {
|
if err = defaults.Set(config); err != nil {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
|
|
@ -30,12 +30,12 @@ func LoadConfig() (config *Config, err error) {
|
||||||
viper.AddConfigPath("/58team_blog/cfgs/")
|
viper.AddConfigPath("/58team_blog/cfgs/")
|
||||||
|
|
||||||
if err = viper.ReadInConfig(); err != nil {
|
if err = viper.ReadInConfig(); err != nil {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = viper.Unmarshal(&config); err != nil {
|
if err = viper.Unmarshal(&config); err != nil {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, nil
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
internal/infrastructure/db.go
Normal file
19
internal/infrastructure/db.go
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package infrastructure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Database struct {
|
||||||
|
connection *sqlx.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func DatabaseInit(config Config) (db Database, err error) {
|
||||||
|
db = Database{}
|
||||||
|
db_setup := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s", config.DBUser, config.DBPass, config.DBHost, config.DBPort, config.DBName)
|
||||||
|
db.connection, err = sqlx.Connect("postgres", db_setup)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package db
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/infrastructure"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Database struct {
|
|
||||||
Conn *sqlx.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func DatabaseInit(config infrastructure.Config) (db *Database, err error) {
|
|
||||||
db = &Database{}
|
|
||||||
|
|
||||||
db_setup := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=disable", config.DBUser, config.DBPass, config.DBHost, config.DBPort, config.DBName)
|
|
||||||
db.Conn, err = sqlx.Connect("postgres", db_setup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return db, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
package repo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/domain/entities"
|
|
||||||
"58team_blog/internal/infrastructure/db"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ImagesRepository struct {
|
|
||||||
conn *db.Database
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateImagesRepository(conn *db.Database) ImagesRepository {
|
|
||||||
return ImagesRepository{
|
|
||||||
conn: conn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ImagesRepository) Create(entity *entities.Images) error {
|
|
||||||
query := "INSERT INTO " + entities.ImagesTable + "(id, path) VALUES (:id, :path)"
|
|
||||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ImagesRepository) FindById(id uuid.UUID) (*entities.Images, error) {
|
|
||||||
var entity *entities.Images
|
|
||||||
|
|
||||||
query := "SELECT * FROM " + entities.ImagesTable + " WHERE id = ?"
|
|
||||||
query, args, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
err = r.conn.Conn.Get(entity, query, args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ImagesRepository) Delete(id uuid.UUID) error {
|
|
||||||
query := "DELETE FROM " + entities.ImagesTable + " WHERE id=?"
|
|
||||||
|
|
||||||
query, args, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
_, err = r.conn.Conn.Query(query, args...)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
package repo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/domain/entities"
|
|
||||||
"58team_blog/internal/infrastructure/db"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PostRepository struct {
|
|
||||||
conn *db.Database
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePostRepository(conn *db.Database) PostRepository {
|
|
||||||
return PostRepository{
|
|
||||||
conn: conn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) Create(entity *entities.Post) (*entities.Post, error) {
|
|
||||||
query := "INSERT INTO " + entities.PostTable + " (id, userid, title, description, content, createdat, updatedat)" +
|
|
||||||
"VALUES (:id, :userid, :title, :description, :content, :createdat, :updatedat)"
|
|
||||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
|
||||||
|
|
||||||
return entity, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) FindById(id uuid.UUID) (*entities.Post, error) {
|
|
||||||
var entity *entities.Post
|
|
||||||
query := "SELECT * FROM " + entities.PostTable + " WHERE id=?"
|
|
||||||
|
|
||||||
query, args, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
err = r.conn.Conn.Get(entity, query, args)
|
|
||||||
|
|
||||||
return entity, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) FindAllByUserName(userName string) ([]*entities.Post, error) {
|
|
||||||
var entity_list []*entities.Post
|
|
||||||
query := "SELECT * FROM " + entities.PostTable + " WHERE userid=?"
|
|
||||||
|
|
||||||
query, args, err := sqlx.In(query, userName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
err = r.conn.Conn.Select(entity_list, query, args...)
|
|
||||||
|
|
||||||
return entity_list, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) GetAll() ([]*entities.Post, error) {
|
|
||||||
var entity_list []*entities.Post
|
|
||||||
query := "SELECT * FROM " + entities.PostTable + " ORDER BY createdat, updatedat LIMIT 5;"
|
|
||||||
|
|
||||||
err := r.conn.Conn.Select(&entity_list, query)
|
|
||||||
|
|
||||||
return entity_list, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) Update(entity *entities.Post) error {
|
|
||||||
query := "UPDATE " + entities.PostTable + "SET title=:title, description=:description, content=:content, updatedat=:updatedat WHERE id=:id"
|
|
||||||
|
|
||||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostRepository) Delete(id uuid.UUID) error {
|
|
||||||
query := "DELETE FROM " + entities.PostTable + " WHERE id=?"
|
|
||||||
|
|
||||||
query, args, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
_, err = r.conn.Conn.Exec(query, args...)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
package repo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/domain/entities"
|
|
||||||
"58team_blog/internal/infrastructure/db"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserRepository struct {
|
|
||||||
conn *db.Database
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateUserRepository(conn *db.Database) UserRepository {
|
|
||||||
return UserRepository{
|
|
||||||
conn: conn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) Create(entity *entities.User) (*entities.User, error) {
|
|
||||||
query := "INSERT INTO " + entities.UserTable + "(id, username, password) VALUES (:id, :username, :password)"
|
|
||||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) FindById(id uuid.UUID) (*entities.User, error) {
|
|
||||||
var entity *entities.User
|
|
||||||
|
|
||||||
query := "SELECT * FROM " + entities.UserTable + " WHERE id=?"
|
|
||||||
query, arg, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
err = r.conn.Conn.Get(entity, query, arg...)
|
|
||||||
|
|
||||||
return entity, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) FindByName(username string) (*entities.User, error) {
|
|
||||||
var entity *entities.User
|
|
||||||
|
|
||||||
query := "SELECT * FROM " + entities.UserTable + " WHERE username=?"
|
|
||||||
query, arg, err := sqlx.In(query, username)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
err = r.conn.Conn.Get(entity, query, arg...)
|
|
||||||
|
|
||||||
return entity, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) GetAll() ([]*entities.User, error) {
|
|
||||||
var entity_list []*entities.User
|
|
||||||
|
|
||||||
query := "SELECT * FROM " + entities.UserTable
|
|
||||||
err := r.conn.Conn.Select(entity_list, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity_list, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) Update(user *entities.User) error {
|
|
||||||
query := "UPDATE " + entities.UserTable + " SET username=:username, password=:password WHERE id=:id"
|
|
||||||
|
|
||||||
_, err := r.conn.Conn.NamedExec(query, user)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserRepository) Delete(id uuid.UUID) error {
|
|
||||||
query := "DELETE FROM " + entities.UserTable + " WHERE id=?"
|
|
||||||
|
|
||||||
query, arg, err := sqlx.In(query, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
query = r.conn.Conn.Rebind(query)
|
|
||||||
_, err = r.conn.Conn.Exec(query, arg...)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
20
internal/infrastructure/infrastructure.go
Normal file
20
internal/infrastructure/infrastructure.go
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package infrastructure
|
||||||
|
|
||||||
|
type Infrastructure struct {
|
||||||
|
Config Config
|
||||||
|
Db Database
|
||||||
|
}
|
||||||
|
|
||||||
|
func InfrastructureInit() (infra Infrastructure, err error) {
|
||||||
|
infra = Infrastructure{}
|
||||||
|
|
||||||
|
if infra.Config, err = LoadConfig(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if infra.Db, err = DatabaseInit(infra.Config); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/services"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ImagesController struct {
|
|
||||||
service *services.ImagesService
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateImagesController(service *services.ImagesService) ImagesController {
|
|
||||||
return ImagesController{
|
|
||||||
service: service,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get /images/{path}
|
|
||||||
// post /images
|
|
||||||
// delete /images/{id}
|
|
||||||
|
|
||||||
// @Summary Get an image by path
|
|
||||||
// @Description get image by path
|
|
||||||
// @Param path query string true "Path to image"
|
|
||||||
// @Produce image/png
|
|
||||||
// @Produce image/jpeg
|
|
||||||
// @Success 200
|
|
||||||
// @Router /images/{path} [get]
|
|
||||||
func (r *ImagesController) GetImage(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ImagesController) PostImage(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ImagesController) DeleteImage(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/commands"
|
|
||||||
"58team_blog/internal/application/queries"
|
|
||||||
"58team_blog/internal/application/services"
|
|
||||||
"58team_blog/internal/interfaces/api/dto"
|
|
||||||
"58team_blog/internal/interfaces/api/requests"
|
|
||||||
"58team_blog/internal/interfaces/api/responses"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PostController struct {
|
|
||||||
service *services.PostService
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePostController(service *services.PostService) PostController {
|
|
||||||
return PostController{
|
|
||||||
service: service,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostPost godoc
|
|
||||||
//
|
|
||||||
// @Summary Create new post
|
|
||||||
// @Description Create new post in blog
|
|
||||||
// @Tags post
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param request body requests.CreatePostRequest true "Post data"
|
|
||||||
// @Success 200 {object} responses.PostResponse
|
|
||||||
// @Failure 400 {object} responses.ErrorResponse
|
|
||||||
// @Failure 500 {object} responses.ErrorResponse
|
|
||||||
// @Router /post [post]
|
|
||||||
func (r *PostController) Post(c *gin.Context) {
|
|
||||||
var request requests.CreatePostRequest
|
|
||||||
|
|
||||||
if err := c.BindJSON(&request); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "BadRequest")
|
|
||||||
c.IndentedJSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userId, err := uuid.Parse(request.UserId)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Incorrect user id")
|
|
||||||
c.IndentedJSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := commands.CreatePostCommand{
|
|
||||||
UserId: userId,
|
|
||||||
Title: request.Title,
|
|
||||||
Description: request.Description,
|
|
||||||
Content: request.Content,
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := r.service.Create(cmd)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
|
|
||||||
c.IndentedJSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
response := dto.ResponseFromPostResult(res)
|
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusOK, response)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllPost godoc
|
|
||||||
//
|
|
||||||
// @Summary Get all posts
|
|
||||||
// @Description Return first 5 posts
|
|
||||||
// @Tags post
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {array} responses.GetListPostResponseItem
|
|
||||||
// @Failure 500 {object} responses.ErrorResponse
|
|
||||||
// @Router /post [get]
|
|
||||||
func (r *PostController) GetAll(c *gin.Context) {
|
|
||||||
result, err := r.service.GetAll()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
|
|
||||||
c.IndentedJSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
res := dto.ResponseFromPostGetAllResult(result)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllWithOffsetPost godoc
|
|
||||||
// @Summary Get posts after offset
|
|
||||||
// @Description return 5 posts after first offset posts
|
|
||||||
// @Tags post
|
|
||||||
// @Param offset query int true "Offset of posts"
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {array} responses.GetListPostResponseItem
|
|
||||||
// @Router /post/{offset} [get]
|
|
||||||
func (r *PostController) GetAllWithOffset(c *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetByIdPost godoc
|
|
||||||
// @Summary Get post by id
|
|
||||||
// @Description get post by id
|
|
||||||
// @Tags post
|
|
||||||
// @Param id query string true "Id of post"
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {array} responses.PostResponse
|
|
||||||
// @Failure 400 {object} responses.ErrorResponse
|
|
||||||
// @Router /post/{id} [get]
|
|
||||||
func (r *PostController) GetById(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
|
|
||||||
id_valid, err := uuid.Parse(id)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("User get by id error: ", err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id")
|
|
||||||
c.JSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
query := queries.PostFindByIdQuery{
|
|
||||||
Id: id_valid,
|
|
||||||
}
|
|
||||||
|
|
||||||
posts, err := r.service.FindById(query)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Post service error: ", err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
|
|
||||||
c.JSON(resp.ErrorCode, resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result := dto.ResponseFormPostFindByIdResult(posts)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutPost godoc
|
|
||||||
// @Summary Update post content
|
|
||||||
// @Description update post content
|
|
||||||
// @Tags post
|
|
||||||
// @Param id query string true "Id of post"
|
|
||||||
//
|
|
||||||
// @Param request body requests.PutPostRequest true "Post data"
|
|
||||||
//
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {object} responses.PostResponse
|
|
||||||
// @Failure 400 {object} responses.ErrorResponse
|
|
||||||
// @Router /post/{id} [put]
|
|
||||||
func (r *PostController) Put(c *gin.Context) {
|
|
||||||
var request requests.PutPostRequest
|
|
||||||
|
|
||||||
if err := c.BindJSON(request); err != nil {
|
|
||||||
log.Println("Post request error: ", err)
|
|
||||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
|
|
||||||
c.JSON(resp.ErrorCode, resp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete godoc
|
|
||||||
// @Summary Delete post
|
|
||||||
// @Description Delete post by id
|
|
||||||
// @Tags post
|
|
||||||
// @Param id query string true "Id of post"
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200
|
|
||||||
// @Router /post/{id} [delete]
|
|
||||||
|
|
||||||
func (r *PostController) Delete(c *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/services"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserController struct {
|
|
||||||
service *services.UserService
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateUserController(service *services.UserService) UserController {
|
|
||||||
return UserController{
|
|
||||||
service: service,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Create new user
|
|
||||||
// @Description Creates new user in system
|
|
||||||
// @Param path query string true "Path to image"
|
|
||||||
// @Produce
|
|
||||||
// @Success 200
|
|
||||||
// @Router /images/{path} [get]
|
|
||||||
func (r *UserController) Post(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserController) FindById(c *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserController) FindByName(c *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserController) GetAll(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserController) Put(c *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UserController) Delete(c *gin.Context) {
|
|
||||||
// TODO: return image
|
|
||||||
panic("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package dto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/queries"
|
|
||||||
"58team_blog/internal/interfaces/api/responses"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ResponseFormPostFindByIdResult(result *queries.PostFindByIdResult) responses.PostResponse {
|
|
||||||
res := result.Result
|
|
||||||
return responses.PostResponse{
|
|
||||||
Id: res.Id.String(),
|
|
||||||
UserId: res.UserId.String(),
|
|
||||||
Title: res.Title,
|
|
||||||
Description: res.Description,
|
|
||||||
Content: res.Content,
|
|
||||||
CreatedAt: res.CreatedAt,
|
|
||||||
UpdatedAt: res.UpdatedAt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package dto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/common"
|
|
||||||
"58team_blog/internal/application/queries"
|
|
||||||
"58team_blog/internal/interfaces/api/responses"
|
|
||||||
)
|
|
||||||
|
|
||||||
func itemFromResult(item *common.PostResult) responses.GetListPostResponseItem {
|
|
||||||
return responses.GetListPostResponseItem{
|
|
||||||
Id: item.Id.String(),
|
|
||||||
Title: item.Title,
|
|
||||||
Description: item.Description,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ResponseFromPostGetAllResult(result *queries.PostGetAllResult) responses.GetListPostResponse {
|
|
||||||
var resp []responses.GetListPostResponseItem
|
|
||||||
|
|
||||||
for _, r := range result.Result.Result {
|
|
||||||
resp = append(resp, itemFromResult(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package dto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/common"
|
|
||||||
"58team_blog/internal/interfaces/api/responses"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ResponseFromPostResult(result *common.PostResult) responses.PostResponse {
|
|
||||||
return responses.PostResponse{
|
|
||||||
Id: result.Id.String(),
|
|
||||||
UserId: result.UserId.String(),
|
|
||||||
Title: result.Title,
|
|
||||||
Description: result.Description,
|
|
||||||
Content: result.Content,
|
|
||||||
CreatedAt: result.CreatedAt,
|
|
||||||
UpdatedAt: result.UpdatedAt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
internal/interfaces/api/images_controller.go
Normal file
1
internal/interfaces/api/images_controller.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
||||||
1
internal/interfaces/api/post_controller.go
Normal file
1
internal/interfaces/api/post_controller.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
type CreatePostRequest struct {
|
|
||||||
Title string `json:"title" validate:"required,min=8,max=255"`
|
|
||||||
Description string `json:"description" validate:"required,min=8,max=255"`
|
|
||||||
Content string `json:"content" validate:"required,min=36"`
|
|
||||||
UserId string `json:"userId" validate:"required,uuid5"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
type PutPostRequest struct {
|
|
||||||
Title string `json:"title"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package responses
|
|
||||||
|
|
||||||
type ErrorResponse struct {
|
|
||||||
ErrorCode int `json:"error_code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateErrorResponse(code int, msg string) ErrorResponse {
|
|
||||||
return ErrorResponse{
|
|
||||||
ErrorCode: code,
|
|
||||||
Message: msg,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package responses
|
|
||||||
|
|
||||||
type GetListPostResponseItem struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetListPostResponse []GetListPostResponseItem
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package responses
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type PostResponse struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
UserId string `json:"userId"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostResponseList []*PostResponse
|
|
||||||
1
internal/interfaces/api/user_controller.go
Normal file
1
internal/interfaces/api/user_controller.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
||||||
|
|
@ -1,18 +1 @@
|
||||||
package interfaces
|
package interfaces
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/application/services"
|
|
||||||
"58team_blog/internal/interfaces/api/controllers"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BindPostAdmin(service *services.PostService, group *gin.RouterGroup) {
|
|
||||||
post := controllers.CreatePostController(service)
|
|
||||||
|
|
||||||
g := group.Group("/post")
|
|
||||||
g.GET("/", post.GetAllPost)
|
|
||||||
g.GET("/:id", post.GetByIdPost)
|
|
||||||
g.POST("/", post.PostPost)
|
|
||||||
g.PUT("/:id", post.PutPost)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
BIN
migrate
BIN
migrate
Binary file not shown.
98
migrate.go
98
migrate.go
|
|
@ -1,98 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"58team_blog/internal/infrastructure"
|
|
||||||
"database/sql"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/golang-migrate/migrate"
|
|
||||||
"github.com/golang-migrate/migrate/database/postgres"
|
|
||||||
_ "github.com/golang-migrate/migrate/source/file"
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var command = flag.String("command", "up", "Migration command: up, down, version, force.")
|
|
||||||
var steps = flag.Int("steps", -1, "Number of migration steps (for up/down commands)")
|
|
||||||
var version = flag.Int("version", -1, "Target version (for force command)")
|
|
||||||
|
|
||||||
config, err := infrastructure.LoadConfig()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Cannot load config file: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
DbUrl := "postgres://" + config.DBUser + ":" + config.DBPass +
|
|
||||||
"@" + config.DBHost + ":" + config.DBPort + "/" + config.DBName + "?sslmode=disable"
|
|
||||||
fmt.Println(DbUrl)
|
|
||||||
|
|
||||||
db, err := sql.Open("postgres", DbUrl)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to connect to database:", err)
|
|
||||||
}
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
driver, err := postgres.WithInstance(db, &postgres.Config{})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to create database driver:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m, err := migrate.NewWithDatabaseInstance("file://./migrations", "postgres", driver)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to create migrate instance:", err)
|
|
||||||
}
|
|
||||||
defer m.Close()
|
|
||||||
|
|
||||||
switch *command {
|
|
||||||
case "up":
|
|
||||||
if *steps > 0 {
|
|
||||||
err = m.Steps(*steps)
|
|
||||||
} else {
|
|
||||||
err = m.Up()
|
|
||||||
}
|
|
||||||
if err != nil && err != migrate.ErrNoChange {
|
|
||||||
log.Fatal("Migration up failed:", err)
|
|
||||||
}
|
|
||||||
if err == migrate.ErrNoChange {
|
|
||||||
fmt.Println("No migrations to apply")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Migrations applied successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
case "down":
|
|
||||||
if *steps > 0 {
|
|
||||||
err = m.Steps(-*steps)
|
|
||||||
} else {
|
|
||||||
err = m.Down()
|
|
||||||
}
|
|
||||||
if err != nil && err != migrate.ErrNoChange {
|
|
||||||
log.Fatal("Migration down failed:", err)
|
|
||||||
}
|
|
||||||
if err == migrate.ErrNoChange {
|
|
||||||
fmt.Println("No migrations to rollback")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Migrations rolled back successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
case "version":
|
|
||||||
version, dirty, err := m.Version()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to get version:", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Current version: %d (dirty: %v)\n", version, dirty)
|
|
||||||
|
|
||||||
case "force":
|
|
||||||
if *version < 0 {
|
|
||||||
log.Fatal("Version is required for force command. Use -version flag")
|
|
||||||
}
|
|
||||||
err = m.Force(*version)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Force migration failed:", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Forced migration to version %d\n", *version)
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Fatal("Unknown command:", *command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
DROP TABLE IF EXISTS images;
|
|
||||||
DROP TABLE IF EXISTS users;
|
|
||||||
DROP TABLE IF EXISTS post;
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
username TEXT NOT NULL UNIQUE,
|
|
||||||
password TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS post (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
userId TEXT NOT NULL,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
description TEXT NOT NULL,
|
|
||||||
content TEXT NOT NULL,
|
|
||||||
createdAt TIMESTAMP NOT NULL,
|
|
||||||
updatedAt TIMESTAMP NOT NULL,
|
|
||||||
FOREIGN KEY (userId) REFERENCES users(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS images (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
path TEXT NOT NULL
|
|
||||||
);
|
|
||||||
47
migrations/create.sql
Normal file
47
migrations/create.sql
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
CREATE TABLE "users" (
|
||||||
|
"id" TEXT NOT NULL UNIQUE,
|
||||||
|
"username" VARCHAR(255) UNIQUE,
|
||||||
|
"password" VARCHAR(255),
|
||||||
|
PRIMARY KEY("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE "post" (
|
||||||
|
"id" TEXT NOT NULL UNIQUE,
|
||||||
|
"title" TEXT,
|
||||||
|
"description" TEXT,
|
||||||
|
"content" TEXT,
|
||||||
|
"createdAt" TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP,
|
||||||
|
PRIMARY KEY("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE "posts" (
|
||||||
|
"id" TEXT NOT NULL UNIQUE,
|
||||||
|
"user_id" INTEGER,
|
||||||
|
"post_id" INTEGER,
|
||||||
|
PRIMARY KEY("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE "images" (
|
||||||
|
"id" TEXT NOT NULL UNIQUE,
|
||||||
|
"path" TEXT,
|
||||||
|
PRIMARY KEY("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE "users"
|
||||||
|
ADD FOREIGN KEY("id") REFERENCES "posts"("user_id")
|
||||||
|
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||||
|
ALTER TABLE "post"
|
||||||
|
ADD FOREIGN KEY("id") REFERENCES "posts"("post_id")
|
||||||
|
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue