pre-dev: initial commit

This commit is contained in:
2025-08-11 10:25:54 +07:00
parent e0ecf1c906
commit ee9b4a9035
50 changed files with 1020 additions and 1 deletions
View File
@@ -0,0 +1,20 @@
package modifier
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/single"
)
// a sampel of modifying some input
func ModifInput(input *e.Createdto, data *e.Single, tx *gorm.DB) error {
input.Name = "Prefix_" + input.Name
return nil
}
// a sampel of utilizing transaction
func CheckData(input *e.Createdto, data *e.Single, tx *gorm.DB) error {
tx.Where("name = ?", input.Name)
input.Name = "Prefix_" + input.Name
return nil
}
@@ -0,0 +1,59 @@
# Use-Case
Standard pattern to be used to maintain the code scalability by providing
middleware-based flow. Each function can have its own middlewares for
pre- and post-processing.
According to the pattern above all of the case-functions runs only basic
rdbms operations, like getting data or writing data. And it's all based
on the data structure. The middlewares are used to for additional actions.
## How It's Done
The use-case is divided into at least 2 parts:
1. Case (`case.go`), where the `case` functions (the main functions) are stored
2. Tycovar (`tycovar.go`), where package scoped types, const, and variables
are stored
Optionally, there can be other parts, such as:
1. Helper (`helper.go`), where internal functions are stored
2. Middleware (`middleware.go`), where the pre- and post-processing functions
are stored
Then proceed the following steps (example):
1. Inside the `tycovar.go`, define the middleware types for each case
functions. Make sure to:
1. Include dto, table definition, and transaction for the parameters
since the middlewares are to utilize or modifies one ot the parameters.
2. Make all of the parameter pointer for easier handling.
3. Return `error` for blocking purpose when error occurs.
```go
type createMw func(input *e.Createdto, tx *gorm.DB) error
.
.
```
2. Inside the `tycovar.go`, create variables in form of array to make it
possible to have more than one middleware. There are 2 modes (pre- and
post-processing) for each case functions:
```go
var createPreMw []createMw
var createPostMw []createMw
.
.
```
3. Inside the `middleware.go`, create the necessary middlewares
```go
func createPreMwAddNamePrefix(input *e.Createdto, tx *gorm.DB) error {
input.Name = "Prefix_" + input.Name
return nil
}
```
4. Inside the `middleware.go`, append the middlewares during initialization.
The order of the does not really is important, except there are steps that
are dependent on each other.
```go
func init() {
createPreMw = append(createPreMw, createPreMwAddNamePrefix)
}
```
5. Loop through the middleware variables and call each middleware. Since there
are 2 modes (pre- and post-processing), the order of the calls is important.
@@ -0,0 +1,55 @@
/*
DESCRIPTION:
Any functions that are available to be used externally.
*/
package crud
import (
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
e "simrs-vx/internal/domain/main-entities/single"
)
const source = "crud"
func Create(input e.Createdto) (*d.Data, error) {
result, err := CreateData(input)
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"type": "list",
"status": "created",
},
Data: result,
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
data := d.Data{}
query := dg.I
query.Find(&data)
if err := query.Error; err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{},
Data: data,
}, nil
}
func ReadDetail() {
}
func Update() {
}
func Delete() {
}
@@ -0,0 +1,13 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package crud
import (
e "simrs-vx/internal/domain/main-entities/single"
)
func setData(src e.Createdto, dst *e.Single) {
}
@@ -0,0 +1,34 @@
package crud
import (
e "simrs-vx/internal/domain/main-entities/single"
dg "github.com/karincake/apem/db-gorm-pg"
"gorm.io/gorm"
)
func CreateData(input e.Createdto) (*e.Single, error) {
data := e.Single{}
err := dg.I.Transaction(func(tx *gorm.DB) error {
for i := range createPreMw {
if err := createPreMw[i](&input, &data, dg.I); err != nil {
return nil
}
}
if err := dg.I.Create(&data).Error; err != nil {
return nil
}
for i := range createPostMw {
if err := createPostMw[i](&input, &data, dg.I); err != nil {
return nil
}
}
return nil
})
return &data, err
}
@@ -0,0 +1,10 @@
package crud
import (
pm "simrs-vx/internal/use-case/plugin/modifier"
)
func init() {
createPreMw = append(createPreMw, pm.ModifInput)
createPreMw = append(createPreMw, pm.CheckData)
}
@@ -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 crud
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/single"
)
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
type deleteMw func(input *e.ReadDetailDto, data *e.Single, 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
View File