Skip to content

Commit fc8da65

Browse files
feat: owner create and update endpoints
1 parent 2a92243 commit fc8da65

File tree

7 files changed

+252
-7
lines changed

7 files changed

+252
-7
lines changed

backend/cms-sys/cmd/main.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ import (
2323
)
2424

2525
type DISection struct {
26-
repo repository.AuthRepository
27-
srv service.AuthService
28-
handler handler.AuthHandle
26+
repo repository.AuthRepository
27+
srv service.AuthService
28+
handler handler.AuthHandle
29+
ownerHandler handler.OwnerHandle
2930
}
3031

3132
func main() {
@@ -145,6 +146,7 @@ func main() {
145146

146147
di := DependencyInjectionSection(appLogger, dbConnection.DB)
147148
routes.SetupRoutes(app, di.handler)
149+
routes.SetupOwnerRoutes(app, di.ownerHandler)
148150

149151
port := utils.GetEnv("PORT", "8080")
150152

@@ -175,11 +177,17 @@ func main() {
175177
func DependencyInjectionSection(logger *logrus.Logger, db *gorm.DB) *DISection {
176178
repo := repository.NewRepo(logger, db)
177179
srv := service.NewService(logger, repo)
178-
handler := handler.NewHandler(srv)
180+
authHandler := handler.NewHandler(srv)
181+
182+
// Owner
183+
ownerRepo := repository.NewOwnerRepository(logger, db)
184+
ownerService := service.NewOwnerService(logger, ownerRepo, repo)
185+
ownerHandler := handler.NewOwnerHandler(ownerService)
179186

180187
return &DISection{
181-
repo: repo,
182-
srv: srv,
183-
handler: handler,
188+
repo: repo,
189+
srv: srv,
190+
handler: authHandler,
191+
ownerHandler: ownerHandler,
184192
}
185193
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package handler
2+
3+
import (
4+
"github.com/go-playground/validator/v10"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/multi-tenants-cms-golang/cms-sys/internal/service"
7+
"github.com/multi-tenants-cms-golang/cms-sys/internal/types"
8+
"github.com/multi-tenants-cms-golang/cms-sys/pkg/utils"
9+
)
10+
11+
type OwnerHandle interface {
12+
Create(c *fiber.Ctx) error
13+
Update(c *fiber.Ctx) error
14+
}
15+
type OwnerHandler struct {
16+
service service.OwnerService
17+
validator *validator.Validate
18+
}
19+
20+
var _ OwnerHandle = (*OwnerHandler)(nil)
21+
22+
func NewOwnerHandler(service service.OwnerService) OwnerHandle {
23+
return &OwnerHandler{service: service, validator: validator.New()}
24+
}
25+
26+
func (o OwnerHandler) Create(c *fiber.Ctx) error {
27+
var req types.OwnerCreateRequest
28+
if err := c.BodyParser(&req); err != nil {
29+
return utils.BadRequestResponse(c, "Invalid request body", err.Error())
30+
}
31+
32+
if err := o.validator.Struct(req); err != nil {
33+
return utils.BadRequestResponse(c, "Validation failed!", err.Error())
34+
}
35+
36+
ownerResponse, err := o.service.Create(req)
37+
if err != nil {
38+
return utils.InternalServerErrorResponse(c, "Failed to create owner", err.Error())
39+
}
40+
41+
return utils.CreatedResponse(c, "Owner created", ownerResponse)
42+
}
43+
44+
func (o OwnerHandler) Update(c *fiber.Ctx) error {
45+
id := c.Params("id")
46+
var req types.OwnerUpdateRequest
47+
48+
if err := c.BodyParser(&req); err != nil {
49+
return utils.BadRequestResponse(c, "Invalid request body", err.Error())
50+
}
51+
if err := o.validator.Struct(req); err != nil {
52+
return utils.BadRequestResponse(c, "Validation failed!", err.Error())
53+
}
54+
55+
ownerResponse, err := o.service.Update(id, req)
56+
if err != nil {
57+
return utils.InternalServerErrorResponse(c, "Failed to update owner", err.Error())
58+
}
59+
60+
return utils.SuccessResponse(c, "Owner updated", ownerResponse)
61+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package repository
2+
3+
import (
4+
"github.com/multi-tenants-cms-golang/cms-sys/internal/types"
5+
"github.com/sirupsen/logrus"
6+
"gorm.io/gorm"
7+
)
8+
9+
type OwnerRepository interface {
10+
CreateOwner(owner *types.CMSUser) error
11+
GeyById(id string) (*types.CMSUser, error)
12+
UpdateOwner(owner *types.CMSUser) error
13+
}
14+
15+
type OwnerRepositoryImpl struct {
16+
logger *logrus.Logger
17+
db *gorm.DB
18+
}
19+
20+
var _ OwnerRepository = (*OwnerRepositoryImpl)(nil)
21+
22+
func NewOwnerRepository(logger *logrus.Logger, db *gorm.DB) OwnerRepository {
23+
return &OwnerRepositoryImpl{logger: logger, db: db}
24+
}
25+
26+
func (r *OwnerRepositoryImpl) CreateOwner(owner *types.CMSUser) error {
27+
if err := r.db.Create(owner).Error; err != nil {
28+
r.logger.WithError(err).Error("Failed to create owner")
29+
return err
30+
}
31+
return nil
32+
}
33+
34+
func (r *OwnerRepositoryImpl) GeyById(id string) (*types.CMSUser, error) {
35+
var owner types.CMSUser
36+
err := r.db.Where("cms_user_id", id).First(&owner).Error
37+
return &owner, err
38+
}
39+
40+
func (r *OwnerRepositoryImpl) UpdateOwner(owner *types.CMSUser) error {
41+
if err := r.db.Save(owner).Error; err != nil {
42+
r.logger.WithError(err).Error("Failed to update owner")
43+
}
44+
return nil
45+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package routes
2+
3+
import (
4+
"github.com/gofiber/fiber/v2"
5+
"github.com/multi-tenants-cms-golang/cms-sys/internal/handler"
6+
)
7+
8+
func SetupOwnerRoutes(app *fiber.App, handler handler.OwnerHandle) {
9+
ownerRoute := app.Group("/owners")
10+
ownerRoute.Post("/create", handler.Create)
11+
ownerRoute.Put("/update/:id", handler.Update)
12+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package service
2+
3+
import (
4+
"errors"
5+
"github.com/google/uuid"
6+
"github.com/multi-tenants-cms-golang/cms-sys/internal/repository"
7+
"github.com/multi-tenants-cms-golang/cms-sys/internal/types"
8+
"github.com/multi-tenants-cms-golang/cms-sys/pkg/utils"
9+
"github.com/sirupsen/logrus"
10+
"time"
11+
)
12+
13+
type OwnerService interface {
14+
Create(req types.OwnerCreateRequest) (*types.OwnerResponse, error)
15+
Update(id string, req types.OwnerUpdateRequest) (*types.OwnerResponse, error)
16+
}
17+
18+
type OwnerServiceImpl struct {
19+
log *logrus.Logger
20+
repo repository.OwnerRepository
21+
authRepo repository.AuthRepository
22+
}
23+
24+
var _ OwnerService = (*OwnerServiceImpl)(nil)
25+
26+
func NewOwnerService(log *logrus.Logger, repo repository.OwnerRepository, authRepo repository.AuthRepository) OwnerService {
27+
return &OwnerServiceImpl{
28+
log: log,
29+
repo: repo,
30+
authRepo: authRepo,
31+
}
32+
}
33+
34+
func (os *OwnerServiceImpl) Create(req types.OwnerCreateRequest) (*types.OwnerResponse, error) {
35+
exists, err := os.authRepo.EmailExists(req.Email)
36+
if err != nil {
37+
os.log.WithError(err).Error("Failed to check email exists!")
38+
}
39+
40+
if exists {
41+
return nil, errors.New("email already exists")
42+
}
43+
44+
hashedPassword, err := utils.HashPassword(req.Password)
45+
if err != nil {
46+
os.log.WithError(err).Error("Failed to hash password!")
47+
return nil, errors.New("filed to process password")
48+
}
49+
50+
owner := &types.CMSUser{
51+
CMSUserID: uuid.New(),
52+
CMSUserName: req.Name,
53+
CMSUserEmail: req.Email,
54+
CMSNameSpace: &req.NameSpace, // TODO : Gotta fix it later as business logic
55+
Password: hashedPassword,
56+
CMSUserRole: string(types.CMSCustomer),
57+
Verified: false,
58+
CreatedAt: time.Now(),
59+
UpdatedAt: time.Now(),
60+
}
61+
62+
if err := os.repo.CreateOwner(owner); err != nil {
63+
os.log.WithError(err).Error("Failed to create owner")
64+
return nil, errors.New("failed to create owner")
65+
}
66+
67+
return &types.OwnerResponse{
68+
ID: owner.CMSUserID,
69+
Name: owner.CMSUserName,
70+
Email: owner.CMSUserEmail,
71+
Role: owner.CMSUserRole,
72+
NameSpace: *owner.CMSNameSpace,
73+
Verified: owner.Verified,
74+
}, nil
75+
}
76+
77+
func (os *OwnerServiceImpl) Update(id string, req types.OwnerUpdateRequest) (*types.OwnerResponse, error) {
78+
owner, err := os.repo.GeyById(id)
79+
if err != nil {
80+
os.log.WithError(err).Error("Failed to get owner with id ", id)
81+
return nil, errors.New("failed to get owner")
82+
}
83+
owner.CMSUserName = req.Name
84+
// TODO : Gotta fix it later as business logic
85+
owner.CMSNameSpace = &req.NameSpace
86+
if err := os.repo.UpdateOwner(owner); err != nil {
87+
os.log.WithError(err).Error("Failed to update owner")
88+
return nil, errors.New("failed to update owner")
89+
}
90+
91+
return &types.OwnerResponse{
92+
ID: owner.CMSUserID,
93+
Name: owner.CMSUserName,
94+
Email: owner.CMSUserEmail,
95+
Role: owner.CMSUserRole,
96+
NameSpace: *owner.CMSNameSpace,
97+
Verified: owner.Verified,
98+
}, nil
99+
}

backend/cms-sys/internal/types/request.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@ type RegisterRequest struct {
1515
type RefreshTokenRequest struct {
1616
RefreshToken string `json:"refresh_token" validate:"required"`
1717
}
18+
19+
type OwnerCreateRequest struct {
20+
Name string `json:"name" validate:"required,min=2"`
21+
Email string `json:"email" validate:"required,email"`
22+
NameSpace string `json:"namespace" validate:"required,min=3"` // TODO : Gotta remove namespace later
23+
Password string `json:"password" validate:"required,min=6"`
24+
}
25+
type OwnerUpdateRequest struct {
26+
Name string `json:"name" validate:"required,min=2"`
27+
NameSpace string `json:"namespace" validate:"required,min=3"` // TODO : Gotta remove namespace later
28+
}

backend/cms-sys/internal/types/response.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ type TokenResponse struct {
2727
RefreshToken string `json:"refresh_token"`
2828
ExpiresAt time.Time `json:"expires_at"`
2929
}
30+
31+
type OwnerResponse struct {
32+
ID uuid.UUID `json:"id"`
33+
Name string `json:"name"`
34+
Email string `json:"email"`
35+
Role string `json:"role"`
36+
NameSpace string `json:"name_space"`
37+
Verified bool `json:"verified"`
38+
}

0 commit comments

Comments
 (0)