feat (user): add create
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package single
|
||||
|
||||
type Createdto struct {
|
||||
type CreateDto struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
@@ -23,7 +23,7 @@ type ReadDetailDto struct {
|
||||
|
||||
type Updatedto struct {
|
||||
Id uint `json:"id"`
|
||||
Createdto
|
||||
CreateDto
|
||||
}
|
||||
|
||||
type Deletedto struct {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package user
|
||||
|
||||
import erc "simrs-vx/internal/domain/references/common"
|
||||
|
||||
type CreateDto struct {
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
Status_Code erc.StatusCode `json:"status_code"`
|
||||
}
|
||||
|
||||
type ReadListDto struct {
|
||||
Name string `json:"name"`
|
||||
Status_Code erc.StatusCode `json:"status_code"`
|
||||
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
NoPagination int `json:"no_pagination"`
|
||||
}
|
||||
|
||||
type ReadDetailDto struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Updatedto struct {
|
||||
Id uint `json:"id"`
|
||||
CreateDto
|
||||
}
|
||||
|
||||
type Deletedto struct {
|
||||
Id uint `json:"id"`
|
||||
}
|
||||
|
||||
type MetaDto struct {
|
||||
PageNumber int `json:"page_number"`
|
||||
PageSize int `json:"page_size"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
ecore "simrs-vx/internal/domain/base-entities/core"
|
||||
erc "simrs-vx/internal/domain/references/common"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ecore.Main // adjust this according to the needs
|
||||
Name string `json:"name" gorm:"not null;size:25"`
|
||||
Password string `json:"password" gorm:"not null;size:255"`
|
||||
Status_Code erc.StatusCode `json:"status_code" gorm:"not null;size:10"`
|
||||
FailedLoginCount uint `json:"failedLoginCount"`
|
||||
}
|
||||
@@ -23,7 +23,7 @@ const source = "crud"
|
||||
func Create(input e.Createdto) (*d.Data, error) {
|
||||
data := e.Single{}
|
||||
|
||||
setData(&data, &input)
|
||||
setData(input, &data)
|
||||
|
||||
event := pl.Event{
|
||||
Feature: "Create",
|
||||
@@ -47,7 +47,7 @@ func Create(input e.Createdto) (*d.Data, error) {
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "MW_PRE_FAILED", // TODO: add to lang json
|
||||
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
|
||||
Raw: mwErr,
|
||||
Raw: err,
|
||||
}
|
||||
return pl.SetLogError(event, data)
|
||||
}
|
||||
@@ -59,7 +59,8 @@ func Create(input e.Createdto) (*d.Data, error) {
|
||||
event.Action = "DBCreate"
|
||||
event.Status = "started"
|
||||
pl.SetLogInfo(event, data)
|
||||
if result, err := CreateData(&data, tx).Error; err != nil {
|
||||
result, err := CreateData(&data, tx)
|
||||
if err != nil {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "data-create-fail",
|
||||
@@ -83,7 +84,7 @@ func Create(input e.Createdto) (*d.Data, error) {
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "MW_POST_FAILED", // TODO: add to lang json
|
||||
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
|
||||
Raw: mwErr,
|
||||
Raw: err,
|
||||
}
|
||||
return pl.SetLogError(event, data)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ Any functions that are used internally by the use-case
|
||||
package crud
|
||||
|
||||
import (
|
||||
e "simrs-vx/internal/domain/main-entities/single"
|
||||
e "simrs-vx/internal/domain/_template/single"
|
||||
)
|
||||
|
||||
func setData(src e.Createdto, dst *e.Single) {
|
||||
|
||||
@@ -16,7 +16,7 @@ func CreateData(input *e.Single, dbx ...*gorm.DB) (*e.Single, error) {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
if err := tx.Create(&data).Error; err != nil {
|
||||
if err := tx.Create(&input).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
e "simrs-vx/internal/domain/main-entities/single"
|
||||
)
|
||||
|
||||
type createMw func(input *e.Createdto, data *e.Single, tx *gorm.DB) error
|
||||
type createMw func(input *e.CreateDto, data *e.Single, tx *gorm.DB) error
|
||||
type readListMw func(input *e.ReadListDto, data *e.Single, tx *gorm.DB) error
|
||||
type readDetailMw func(input *e.ReadDetailDto, data *e.Single, tx *gorm.DB) error
|
||||
type updateMw func(input *e.ReadDetailDto, data *e.Single, tx *gorm.DB) error
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
e "simrs-vx/internal/domain/main-entities/user"
|
||||
|
||||
dg "github.com/karincake/apem/db-gorm-pg"
|
||||
d "github.com/karincake/dodol"
|
||||
|
||||
pl "simrs-vx/pkg/logger"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const source = "user"
|
||||
|
||||
func Create(input e.CreateDto) (*d.Data, error) {
|
||||
data := e.User{}
|
||||
|
||||
setData(input, &data)
|
||||
|
||||
event := pl.Event{
|
||||
Feature: "Create",
|
||||
Source: source,
|
||||
}
|
||||
|
||||
// Start log
|
||||
event.Action = "Create"
|
||||
event.Status = "started"
|
||||
pl.SetLogInfo(event, input)
|
||||
|
||||
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||
for i := range createPreMw {
|
||||
mwName := fmt.Sprintf("createPreMw[%d]", i)
|
||||
|
||||
event.Action = mwName
|
||||
event.Status = "started"
|
||||
pl.SetLogInfo(event, data)
|
||||
|
||||
if err := createPreMw[i](&input, &data, tx); err != nil {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "MW_PRE_FAILED", // TODO: add to lang json
|
||||
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
|
||||
Raw: err,
|
||||
}
|
||||
return pl.SetLogError(event, data)
|
||||
}
|
||||
|
||||
event.Status = "completed"
|
||||
pl.SetLogInfo(event, nil)
|
||||
}
|
||||
|
||||
event.Action = "DBCreate"
|
||||
event.Status = "started"
|
||||
pl.SetLogInfo(event, data)
|
||||
_, err := CreateData(&data, tx)
|
||||
if err != nil {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "data-create-fail",
|
||||
Detail: "Database insert failed",
|
||||
Raw: err,
|
||||
}
|
||||
return pl.SetLogError(event, data)
|
||||
}
|
||||
|
||||
event.Status = "completed"
|
||||
pl.SetLogInfo(event, nil)
|
||||
|
||||
for i := range createPostMw {
|
||||
mwName := fmt.Sprintf("createPostMw[%d]", i)
|
||||
|
||||
event.Action = mwName
|
||||
event.Status = "started"
|
||||
pl.SetLogInfo(event, input)
|
||||
if err := createPostMw[i](&input, &data, tx); err != nil {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "MW_POST_FAILED", // TODO: add to lang json
|
||||
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
|
||||
Raw: err,
|
||||
}
|
||||
return pl.SetLogError(event, data)
|
||||
}
|
||||
}
|
||||
|
||||
event.Status = "completed"
|
||||
pl.SetLogInfo(event, nil)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &d.Data{
|
||||
Meta: d.II{
|
||||
"source": source,
|
||||
"type": "list",
|
||||
"status": "created",
|
||||
},
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
Any functions that are used internally by the use-case
|
||||
*/
|
||||
package user
|
||||
|
||||
import (
|
||||
e "simrs-vx/internal/domain/main-entities/user"
|
||||
|
||||
p "simrs-vx/pkg/password"
|
||||
)
|
||||
|
||||
func setData(src e.CreateDto, dst *e.User) error {
|
||||
pass, err := p.Hash(src.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dst.Name = src.Name
|
||||
dst.Password = pass
|
||||
dst.Status_Code = src.Status_Code
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
e "simrs-vx/internal/domain/main-entities/user"
|
||||
|
||||
dg "github.com/karincake/apem/db-gorm-pg"
|
||||
gh "github.com/karincake/getuk"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func CreateData(input *e.User, dbx ...*gorm.DB) (*e.User, error) {
|
||||
var tx *gorm.DB
|
||||
if len(dbx) > 0 {
|
||||
tx = dbx[0]
|
||||
} else {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
if err := tx.Create(&input).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func ReadListData(input e.ReadListDto, dbx ...*gorm.DB) ([]e.User, *e.MetaDto, error) {
|
||||
data := []e.User{}
|
||||
pagination := gh.Pagination{}
|
||||
count := int64(0)
|
||||
meta := e.MetaDto{}
|
||||
|
||||
var tx *gorm.DB
|
||||
if len(dbx) > 0 {
|
||||
tx = dbx[0]
|
||||
} else {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
tx = tx.
|
||||
Model(&e.User{}).
|
||||
// Joins("Patient"). // if needed
|
||||
// Preload("Patient"). // if needed
|
||||
Scopes(gh.Filter(input)).
|
||||
Count(&count).
|
||||
Scopes(gh.Paginate(input, &pagination)).
|
||||
Order("CreatedAt DESC")
|
||||
|
||||
if err := tx.Find(&data).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, &meta, nil
|
||||
}
|
||||
return nil, nil, err
|
||||
|
||||
}
|
||||
meta.Count = count
|
||||
meta.PageNumber = pagination.PageNumber
|
||||
meta.PageSize = pagination.PageSize
|
||||
return data, &meta, nil
|
||||
}
|
||||
|
||||
func ReadDetailData(input e.ReadDetailDto, dbx ...*gorm.DB) (*e.User, error) {
|
||||
data := e.User{}
|
||||
|
||||
var tx *gorm.DB
|
||||
if len(dbx) > 0 {
|
||||
tx = dbx[0]
|
||||
} else {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
if err := tx.First(&data, input.Id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
func UpdateData(input e.User, dbx ...*gorm.DB) error {
|
||||
var tx *gorm.DB
|
||||
if len(dbx) > 0 {
|
||||
tx = dbx[0]
|
||||
} else {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
return tx.Save(&input).Error
|
||||
}
|
||||
|
||||
func DeleteData(input *e.User, dbx ...*gorm.DB) error {
|
||||
var tx *gorm.DB
|
||||
if len(dbx) > 0 {
|
||||
tx = dbx[0]
|
||||
} else {
|
||||
tx = dg.I
|
||||
}
|
||||
|
||||
return tx.Delete(input).Error
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
DESCRIPTION:
|
||||
A sample, part of the package that contains type, constants, and/or variables.
|
||||
|
||||
In this sample it also provides type and variable regarding the needs of the
|
||||
middleware to separate from main use-case which has the basic CRUD
|
||||
functionality. The purpose of this is to make the code more maintainable.
|
||||
*/
|
||||
package user
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
|
||||
e "simrs-vx/internal/domain/main-entities/user"
|
||||
)
|
||||
|
||||
type createMw func(input *e.CreateDto, data *e.User, tx *gorm.DB) error
|
||||
type readListMw func(input *e.ReadListDto, data *e.User, tx *gorm.DB) error
|
||||
type readDetailMw func(input *e.ReadDetailDto, data *e.User, tx *gorm.DB) error
|
||||
type updateMw func(input *e.ReadDetailDto, data *e.User, tx *gorm.DB) error
|
||||
type deleteMw func(input *e.ReadDetailDto, data *e.User, tx *gorm.DB) error
|
||||
|
||||
var createPreMw []createMw // preprocess middleware
|
||||
var createPostMw []createMw // postprocess middleware
|
||||
var readListPreMw []readListMw // ..
|
||||
var readListPostMw []readListMw // ..
|
||||
var readDetailPreMw []readDetailMw
|
||||
var readDetailPostMw []readDetailMw
|
||||
var udpatePreMw []readDetailMw
|
||||
var udpatePostMw []readDetailMw
|
||||
var deletePreMw []readDetailMw
|
||||
var deletePostMw []readDetailMw
|
||||
@@ -0,0 +1,17 @@
|
||||
package password
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
var Cost = 10 // can be set by consumer
|
||||
|
||||
func Hash(password string) (string, error) {
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), Cost)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func Check(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
Reference in New Issue
Block a user