diff --git a/internal/accessor/category/create.go b/internal/accessor/category/create.go new file mode 100644 index 0000000..f9616fa --- /dev/null +++ b/internal/accessor/category/create.go @@ -0,0 +1,21 @@ +package categoryrepository + +import ( + categorydomain "legalgo-BE-go/internal/domain/category" + + "github.com/google/uuid" +) + +func (a *accessor) Create(spec categorydomain.CategoryReq) error { + data := categorydomain.Category{ + ID: uuid.NewString(), + Name: spec.Name, + Code: spec.Code, + } + + if err := a.DB.Create(&data).Error; err != nil { + return err + } + + return nil +} diff --git a/internal/accessor/category/get_all.go b/internal/accessor/category/get_all.go new file mode 100644 index 0000000..74ae169 --- /dev/null +++ b/internal/accessor/category/get_all.go @@ -0,0 +1,13 @@ +package categoryrepository + +import categorydomain "legalgo-BE-go/internal/domain/category" + +func (a *accessor) GetAll() ([]categorydomain.Category, error) { + var categories []categorydomain.Category + + if err := a.DB.Find(&categories).Error; err != nil { + return nil, err + } + + return categories, nil +} diff --git a/internal/accessor/category/impl.go b/internal/accessor/category/impl.go new file mode 100644 index 0000000..8171fe0 --- /dev/null +++ b/internal/accessor/category/impl.go @@ -0,0 +1,21 @@ +package categoryrepository + +import ( + "legalgo-BE-go/database" + categorydomain "legalgo-BE-go/internal/domain/category" +) + +type accessor struct { + DB *database.DB +} + +type Category interface { + Create(categorydomain.CategoryReq) error + GetAll() ([]categorydomain.Category, error) +} + +func New( + db *database.DB, +) Category { + return &accessor{db} +} diff --git a/internal/accessor/module.go b/internal/accessor/module.go index 8c1638a..5e1d941 100644 --- a/internal/accessor/module.go +++ b/internal/accessor/module.go @@ -1,6 +1,7 @@ package repository import ( + categoryrepository "legalgo-BE-go/internal/accessor/category" redisaccessor "legalgo-BE-go/internal/accessor/redis" staffrepository "legalgo-BE-go/internal/accessor/staff" subscriberepository "legalgo-BE-go/internal/accessor/subscribe" @@ -18,4 +19,5 @@ var Module = fx.Module("repository", fx.Provide( subscribeplanrepository.New, subscriberepository.New, tagrepository.New, + categoryrepository.New, )) diff --git a/internal/api/http/category/create.go b/internal/api/http/category/create.go new file mode 100644 index 0000000..ecaec52 --- /dev/null +++ b/internal/api/http/category/create.go @@ -0,0 +1,67 @@ +package categoryhttp + +import ( + categorydomain "legalgo-BE-go/internal/domain/category" + categorysvc "legalgo-BE-go/internal/services/category" + "legalgo-BE-go/internal/utilities/response" + "legalgo-BE-go/internal/utilities/utils" + "net/http" + + "github.com/go-chi/chi/v5" + "github.com/go-playground/validator/v10" +) + +func Create( + router chi.Router, + validate *validator.Validate, + categorySvc categorysvc.Category, +) { + router.Post("/category/create", func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + var spec categorydomain.CategoryReq + + if err := utils.UnmarshalBody(r, &spec); err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.Error(), + ) + + return + } + + if err := validate.Struct(spec); err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.(validator.ValidationErrors).Error(), + ) + return + } + + if err := categorySvc.Create(spec); err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrCreateEntity.Code, + response.ErrCreateEntity.HttpCode, + err.Error(), + ) + return + } + + response.RespondJsonSuccess(ctx, w, struct { + Message string + }{ + Message: "category created successfully", + }) + }) +} diff --git a/internal/api/http/category/get_all.go b/internal/api/http/category/get_all.go new file mode 100644 index 0000000..be13c90 --- /dev/null +++ b/internal/api/http/category/get_all.go @@ -0,0 +1,32 @@ +package categoryhttp + +import ( + categorysvc "legalgo-BE-go/internal/services/category" + "legalgo-BE-go/internal/utilities/response" + "net/http" + + "github.com/go-chi/chi/v5" +) + +func GetAll( + router chi.Router, + categorySvc categorysvc.Category, +) { + router.Get("/category", func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + subsPlan, err := categorySvc.GetAll() + if err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.Error(), + ) + return + } + + response.RespondJsonSuccess(ctx, w, subsPlan) + }) +} diff --git a/internal/api/http/category/module.go b/internal/api/http/category/module.go new file mode 100644 index 0000000..6b0e5a2 --- /dev/null +++ b/internal/api/http/category/module.go @@ -0,0 +1,8 @@ +package categoryhttp + +import "go.uber.org/fx" + +var Module = fx.Module("categories", fx.Invoke( + Create, + GetAll, +)) diff --git a/internal/api/http/router.go b/internal/api/http/router.go index 6b8aa47..20f25f6 100644 --- a/internal/api/http/router.go +++ b/internal/api/http/router.go @@ -2,6 +2,7 @@ package internalhttp import ( authhttp "legalgo-BE-go/internal/api/http/auth" + categoryhttp "legalgo-BE-go/internal/api/http/category" subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan" taghttp "legalgo-BE-go/internal/api/http/tag" @@ -21,6 +22,7 @@ var Module = fx.Module("router", authhttp.Module, subscribeplanhttp.Module, taghttp.Module, + categoryhttp.Module, ) func initRouter() chi.Router { diff --git a/internal/api/http/tag/get.go b/internal/api/http/tag/get_all.go similarity index 97% rename from internal/api/http/tag/get.go rename to internal/api/http/tag/get_all.go index 7a81762..9260cb7 100644 --- a/internal/api/http/tag/get.go +++ b/internal/api/http/tag/get_all.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi/v5" ) -func Get( +func GetAll( router chi.Router, tagSvc tagsvc.TagIntf, ) { diff --git a/internal/api/http/tag/module.go b/internal/api/http/tag/module.go index 4da5f50..b62951c 100644 --- a/internal/api/http/tag/module.go +++ b/internal/api/http/tag/module.go @@ -4,5 +4,5 @@ import "go.uber.org/fx" var Module = fx.Module("tag", fx.Invoke( Create, - Get, + GetAll, )) diff --git a/internal/domain/category/spec.go b/internal/domain/category/spec.go new file mode 100644 index 0000000..880b37f --- /dev/null +++ b/internal/domain/category/spec.go @@ -0,0 +1,12 @@ +package categorydomain + +type Category struct { + ID string `json:"id"` + Name string `json:"name"` + Code string `json:"code"` +} + +type CategoryReq struct { + Name string `json:"name" validate:"required"` + Code string `json:"code" validate:"required"` +} diff --git a/internal/services/category/create.go b/internal/services/category/create.go new file mode 100644 index 0000000..e11f47b --- /dev/null +++ b/internal/services/category/create.go @@ -0,0 +1,7 @@ +package categorysvc + +import categorydomain "legalgo-BE-go/internal/domain/category" + +func (i *impl) Create(spec categorydomain.CategoryReq) error { + return i.categoryRepo.Create(spec) +} diff --git a/internal/services/category/get_all.go b/internal/services/category/get_all.go new file mode 100644 index 0000000..48419a6 --- /dev/null +++ b/internal/services/category/get_all.go @@ -0,0 +1,7 @@ +package categorysvc + +import categorydomain "legalgo-BE-go/internal/domain/category" + +func (i *impl) GetAll() ([]categorydomain.Category, error) { + return i.categoryRepo.GetAll() +} diff --git a/internal/services/category/impl.go b/internal/services/category/impl.go new file mode 100644 index 0000000..1d97cd2 --- /dev/null +++ b/internal/services/category/impl.go @@ -0,0 +1,23 @@ +package categorysvc + +import ( + categoryrepository "legalgo-BE-go/internal/accessor/category" + categorydomain "legalgo-BE-go/internal/domain/category" +) + +type impl struct { + categoryRepo categoryrepository.Category +} + +type Category interface { + Create(categorydomain.CategoryReq) error + GetAll() ([]categorydomain.Category, error) +} + +func New( + categoryRepo categoryrepository.Category, +) Category { + return &impl{ + categoryRepo: categoryRepo, + } +} diff --git a/internal/services/module.go b/internal/services/module.go index 00f84b1..390a617 100644 --- a/internal/services/module.go +++ b/internal/services/module.go @@ -2,6 +2,7 @@ package services import ( serviceauth "legalgo-BE-go/internal/services/auth" + categorysvc "legalgo-BE-go/internal/services/category" subscribesvc "legalgo-BE-go/internal/services/subscribe" subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan" tagsvc "legalgo-BE-go/internal/services/tag" @@ -15,5 +16,6 @@ var Module = fx.Module("services", subscribeplansvc.New, subscribesvc.New, tagsvc.New, + categorysvc.New, ), ) diff --git a/internal/services/tag/create.go b/internal/services/tag/create.go index 2055cf9..7d314e4 100644 --- a/internal/services/tag/create.go +++ b/internal/services/tag/create.go @@ -3,5 +3,5 @@ package tagsvc import tagdomain "legalgo-BE-go/internal/domain/tag" func (i *impl) Create(spec tagdomain.TagReq) error { - return i.TagRepo.Create(spec) + return i.tagRepo.Create(spec) } diff --git a/internal/services/tag/get_all.go b/internal/services/tag/get_all.go index 1709e39..595271e 100644 --- a/internal/services/tag/get_all.go +++ b/internal/services/tag/get_all.go @@ -3,5 +3,5 @@ package tagsvc import tagdomain "legalgo-BE-go/internal/domain/tag" func (i *impl) GetAll() ([]tagdomain.Tag, error) { - return i.TagRepo.GetAll() + return i.tagRepo.GetAll() } diff --git a/internal/services/tag/impl.go b/internal/services/tag/impl.go index adbd901..ac34c5c 100644 --- a/internal/services/tag/impl.go +++ b/internal/services/tag/impl.go @@ -6,7 +6,7 @@ import ( ) type impl struct { - TagRepo tagrepository.TagAccessor + tagRepo tagrepository.TagAccessor } type TagIntf interface { @@ -17,7 +17,5 @@ type TagIntf interface { func New( tagRepo tagrepository.TagAccessor, ) TagIntf { - return &impl{ - TagRepo: tagRepo, - } + return &impl{tagRepo} } diff --git a/openapi.yml b/openapi.yml index b0ce6db..ef2c932 100644 --- a/openapi.yml +++ b/openapi.yml @@ -5,6 +5,50 @@ info: description: API for handling staff and user login, registration, and subscription plan creation. paths: + /staff/profile: + get: + summary: "get staff profile" + tags: + - Staff + parameters: + - name: "id" + in: query + description: "staff id" + required: true + schema: + type: string + responses: + "200": + description: Success get profile + content: + application/json: + schema: + type: object + properties: + data: + type: object + properties: + id: + type: string + email: + type: string + username: + type: string + "400": + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + code: + type: string + message: + type: string + /staff/login: post: summary: Login for staff @@ -120,50 +164,6 @@ paths: message: type: string - /staff/profile: - get: - summary: "get staff profile" - tags: - - Staff - parameters: - - name: "id" - in: query - description: "staff id" - required: true - schema: - type: string - responses: - "200": - description: Success get profile - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - id: - type: string - email: - type: string - username: - type: string - "400": - description: Bad request - content: - application/json: - schema: - type: object - properties: - error: - type: object - properties: - code: - type: string - message: - type: string - /user/profile: get: summary: "get staff profile" @@ -530,3 +530,104 @@ paths: type: string message: type: string + + /category: + get: + summary: Get all categories + tags: + - Category + responses: + "200": + description: Successfully retrieved all categories + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + type: object + properties: + id: + type: string + code: + type: string + name: + type: string + "400": + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + code: + type: string + message: + type: string + + /category/create: + post: + summary: Create a new category + tags: + - Tags + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + code: + type: string + required: + - code + - name + responses: + "201": + description: Category created + content: + application/json: + schema: + type: object + properties: + data: + type: object + properties: + message: + type: string + example: "category created successfully." + "400": + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + code: + type: string + message: + type: string + "409": + description: Conflict (category code already exists) + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + code: + type: string + message: + type: string