Compare commits
8 Commits
8e14ccd12a
...
9094d12c3a
Author | SHA1 | Date | |
---|---|---|---|
|
9094d12c3a | ||
|
dc75af4dc7 | ||
|
1295d15eb3 | ||
|
4794137d42 | ||
|
321b4704a2 | ||
|
a9a6f6ad49 | ||
|
ab26e9d585 | ||
|
b9d4a58d71 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,3 +24,4 @@ go.work.sum
|
|||||||
|
|
||||||
# Custom
|
# Custom
|
||||||
/_output
|
/_output
|
||||||
|
/deployment/db_data
|
||||||
|
2
Makefile
2
Makefile
@ -42,7 +42,7 @@ format: # format code.
|
|||||||
|
|
||||||
.PHONY: add-copyright
|
.PHONY: add-copyright
|
||||||
add-copyright: # add license to file headers.
|
add-copyright: # add license to file headers.
|
||||||
@addlicense -v -f $(ROOT_DIR)/LICENSE -ignore third_party/** -ignore vendor/** -ignore $(OUTPUT_DIR) $(ROOT_DIR)
|
@addlicense -v -f $(ROOT_DIR)/LICENSE $(ROOT_DIR) --skip-files=database.yml --skip-dirs=$(OUTPUT_DIR),deployment,migrations,configs
|
||||||
|
|
||||||
.PHONY: swagger
|
.PHONY: swagger
|
||||||
swagger: # Run swagger.
|
swagger: # Run swagger.
|
||||||
|
@ -195,3 +195,5 @@ type User struct {
|
|||||||
ID int
|
ID int
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use Buffalo pop `Soda CLI` to create database migrations.
|
||||||
|
@ -1,25 +1,3 @@
|
|||||||
# MIT License
|
|
||||||
#
|
|
||||||
# Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
|
||||||
# copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
|
|
||||||
dev-mode: true
|
dev-mode: true
|
||||||
|
|
||||||
web:
|
web:
|
||||||
|
7
database.yml
Normal file
7
database.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
development:
|
||||||
|
dialect: postgres
|
||||||
|
database: howmuch
|
||||||
|
user: postgres
|
||||||
|
password: example
|
||||||
|
host: 127.0.0.1
|
||||||
|
pool: 5
|
22
deployment/docker-compose.yml
Normal file
22
deployment/docker-compose.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: example
|
||||||
|
POSTGRES_DB: howmuch
|
||||||
|
volumes:
|
||||||
|
- ../../db_data_howmuch/postgres/:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
5
internal/pkg/core/context.go
Normal file
5
internal/pkg/core/context.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type Context interface {
|
||||||
|
JSON(code int, obj any)
|
||||||
|
}
|
@ -26,7 +26,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrResponse struct {
|
type ErrResponse struct {
|
||||||
@ -36,7 +35,7 @@ type ErrResponse struct {
|
|||||||
|
|
||||||
// WriteResponse writes the response to the HTTP response writer with HTTP code
|
// WriteResponse writes the response to the HTTP response writer with HTTP code
|
||||||
// and potential errors.
|
// and potential errors.
|
||||||
func WriteResponse(c *gin.Context, err error, data any) {
|
func WriteResponse(c Context, err error, data any) {
|
||||||
// No error, write json response directly
|
// No error, write json response directly
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.JSON(http.StatusOK, data)
|
c.JSON(http.StatusOK, data)
|
||||||
|
@ -33,19 +33,14 @@ func RequestID() gin.HandlerFunc {
|
|||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
var rid string
|
var rid string
|
||||||
|
|
||||||
if rid = ctx.GetString(requestID); rid != "" {
|
|
||||||
// request id exists already
|
|
||||||
ctx.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
if rid = ctx.GetHeader(requestID); rid != "" {
|
if rid = ctx.GetHeader(requestID); rid != "" {
|
||||||
ctx.Set(requestID, rid)
|
ctx.Request.Header.Add(requestID, rid)
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
rid = uuid.NewString()
|
rid = uuid.NewString()
|
||||||
ctx.Set(requestID, rid)
|
ctx.Request.Header.Add(requestID, rid)
|
||||||
ctx.Writer.Header().Add(requestID, rid)
|
ctx.Header(requestID, rid)
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,12 +58,12 @@ func TestRequestID(t *testing.T) {
|
|||||||
wanted := "123"
|
wanted := "123"
|
||||||
|
|
||||||
r.GET("/example", func(c *gin.Context) {
|
r.GET("/example", func(c *gin.Context) {
|
||||||
got = c.GetString(requestID)
|
got = c.GetHeader(requestID)
|
||||||
c.Status(http.StatusOK)
|
c.Status(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
r.POST("/example", func(c *gin.Context) {
|
r.POST("/example", func(c *gin.Context) {
|
||||||
got = c.GetString(requestID)
|
got = c.GetHeader(requestID)
|
||||||
c.String(http.StatusAccepted, "ok")
|
c.String(http.StatusAccepted, "ok")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
DROP TABLE IF EXISTS "user";
|
||||||
|
DROP SEQUENCE IF EXISTS user_id_seq;
|
||||||
|
|
14
migrations/20241004191351_create_user_table.postgres.up.sql
Normal file
14
migrations/20241004191351_create_user_table.postgres.up.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
CREATE SEQUENCE user_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."user" (
|
||||||
|
"id" integer DEFAULT nextval('user_id_seq') NOT NULL,
|
||||||
|
"email" character varying(255) NOT NULL UNIQUE,
|
||||||
|
"first_name" character varying(255) NOT NULL,
|
||||||
|
"last_name" character varying(255) NOT NULL,
|
||||||
|
"password" character varying(60) NOT NULL,
|
||||||
|
"created_at" timestamp NOT NULL,
|
||||||
|
"updated_at" timestamp NOT NULL,
|
||||||
|
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
DROP TABLE IF EXISTS "admin";
|
||||||
|
DROP SEQUENCE IF EXISTS admin_id_seq;
|
@ -0,0 +1,9 @@
|
|||||||
|
CREATE SEQUENCE admin_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1;
|
||||||
|
|
||||||
|
CREATE TABLE "public"."admin" (
|
||||||
|
"id" integer DEFAULT nextval('admin_id_seq') NOT NULL,
|
||||||
|
"email" character varying(255) NOT NULL,
|
||||||
|
"password" character varying(255) NOT NULL,
|
||||||
|
"access_level" integer NOT NULL,
|
||||||
|
CONSTRAINT "admin_pkey" PRIMARY KEY ("id")
|
||||||
|
) WITH (oids = false);
|
Loading…
x
Reference in New Issue
Block a user