feat(niki): add skelton for admin | super-admin | staff | benefactor services

This commit is contained in:
Iman Mirazimi 2024-01-05 15:43:47 +03:30
parent 8841987502
commit 3eea2c0d1d
53 changed files with 377 additions and 41 deletions

View File

@ -7,12 +7,13 @@ type Admin struct {
FirstName string
LastName string
PhoneNumber string
Role AdminRole
Address string
Description string
Email string
City string
Gender UserGender
Status BenefactorStatus
Gender Gender
Status AdminStatus
Birthday time.Time
StatusChangedAt time.Time
}

38
entity/admin_role.go Normal file
View File

@ -0,0 +1,38 @@
package entity
type AdminRole uint
const (
AdminAdminRole AdminRole = iota + 1
AdminSuperAdminRole
)
var AdminRoleStrings = map[AdminRole]string{
AdminAdminRole: "admin",
AdminSuperAdminRole: "super-admin",
}
func (s AdminRole) String() string {
return AdminRoleStrings[s]
}
// AllAdminRole returns a slice containing all string values of AdminRole.
func AllAdminRole() []string {
roleStrings := make([]string, len(AdminRoleStrings))
for role, str := range AdminRoleStrings {
roleStrings[int(role)-1] = str
}
return roleStrings
}
// MapToAdminRole converts a string to the corresponding AdminRole value.
func MapToAdminRole(roleStr string) AdminRole {
for role, str := range AdminRoleStrings {
if str == roleStr {
return role
}
}
return AdminRole(0)
}

View File

@ -11,7 +11,7 @@ type Benefactor struct {
Description string
Email string
City string
Gender UserGender
Gender Gender
Status BenefactorStatus
Birthday time.Time
StatusChangedAt time.Time

38
entity/gender.go Normal file
View File

@ -0,0 +1,38 @@
package entity
type Gender uint
const (
MaleGender Gender = iota + 1
FemaleGender
)
var GenderStrings = map[Gender]string{
MaleGender: "male",
FemaleGender: "female",
}
func (s Gender) String() string {
return GenderStrings[s]
}
// AllGender returns a slice containing all string values of Gender.
func AllGender() []string {
statusStrings := make([]string, len(GenderStrings))
for status, str := range GenderStrings {
statusStrings[int(status)-1] = str
}
return statusStrings
}
// MapToGender converts a string to the corresponding Gender value.
func MapToGender(statusStr string) Gender {
for status, str := range GenderStrings {
if str == statusStr {
return status
}
}
return Gender(0)
}

18
entity/staff.go Normal file
View File

@ -0,0 +1,18 @@
package entity
import "time"
type Staff struct {
ID uint
FirstName string
LastName string
PhoneNumber string
Address string
Description string
Email string
City string
Gender Gender
Status StaffStatus
Birthday time.Time
StatusChangedAt time.Time
}

38
entity/staff_status.go Normal file
View File

@ -0,0 +1,38 @@
package entity
type StaffStatus uint
const (
StaffActiveStatus StaffStatus = iota + 1
StaffDeactiveStatus
)
var StaffStatusStrings = map[StaffStatus]string{
StaffActiveStatus: "active",
StaffDeactiveStatus: "deactive",
}
func (s StaffStatus) String() string {
return StaffStatusStrings[s]
}
// AllStaffStatus returns a slice containing all string values of StaffStatus.
func AllStaffStatus() []string {
statusStrings := make([]string, len(StaffStatusStrings))
for status, str := range StaffStatusStrings {
statusStrings[int(status)-1] = str
}
return statusStrings
}
// MapToStaffStatus converts a string to the corresponding StaffStatus value.
func MapToStaffStatus(statusStr string) StaffStatus {
for status, str := range StaffStatusStrings {
if str == statusStr {
return status
}
}
return StaffStatus(0)
}

View File

@ -1,38 +0,0 @@
package entity
type UserGender uint
const (
UserMaleGender UserGender = iota + 1
UserFemaleGender
)
var UserGenderStrings = map[UserGender]string{
UserMaleGender: "male",
UserFemaleGender: "female",
}
func (s UserGender) String() string {
return UserGenderStrings[s]
}
// AllUserGender returns a slice containing all string values of UserGender.
func AllUserGender() []string {
statusStrings := make([]string, len(UserGenderStrings))
for status, str := range UserGenderStrings {
statusStrings[int(status)-1] = str
}
return statusStrings
}
// MapToUserGender converts a string to the corresponding UserGender value.
func MapToUserGender(statusStr string) UserGender {
for status, str := range UserGenderStrings {
if str == statusStr {
return status
}
}
return UserGender(0)
}

1
param/admin/admin/get.go Normal file
View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package adminparam

View File

@ -0,0 +1 @@
package superadminparam

View File

@ -0,0 +1 @@
package superadminparam

View File

@ -0,0 +1 @@
package superadminparam

View File

@ -0,0 +1 @@
package superadminparam

View File

@ -0,0 +1 @@
package superadminparam

View File

@ -0,0 +1,7 @@
package benefactorparam
type BenefactorProfileRequest struct{}
type BenefactorProfileResponse struct {
Benefactor entity.Benefactor
}

View File

@ -0,0 +1,7 @@
package benefactorparam
type BenefactorLoginRequest struct{}
type BenefactorLoginResponse struct {
Benefactor entity.Benefactor
}

View File

@ -0,0 +1,9 @@
package benefactorparam
import entity "git.gocasts.ir/ebhomengo/niki/entity"
type BenefactorRegisterRequest struct{}
type BenefactorRegisterResponse struct {
Benefactor entity.Benefactor
}

View File

@ -0,0 +1 @@
package benefactorparam

1
param/staff/staff/get.go Normal file
View File

@ -0,0 +1 @@
package staffparam

View File

@ -0,0 +1 @@
package staffparam

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package adminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package superadminservice

View File

@ -0,0 +1 @@
package benefactorservice

View File

@ -0,0 +1,45 @@
package benefactorservice
import (
"fmt"
"gameapp/param"
"gameapp/pkg/richerror"
)
func (s Service) Login(req param.LoginRequest) (param.LoginResponse, error) {
const op = "benefactorservice.Login"
// TODO - it would be better to user two separate method for existence check and getUserByPhoneNumber
user, err := s.repo.GetUserByPhoneNumber(req.PhoneNumber)
if err != nil {
return param.LoginResponse{}, richerror.New(op).WithErr(err).
WithMeta(map[string]interface{}{"phone_number": req.PhoneNumber})
}
if user.Password != getMD5Hash(req.Password) {
return param.LoginResponse{}, fmt.Errorf("username or password isn't correct")
}
accessToken, err := s.auth.CreateAccessToken(user)
if err != nil {
return param.LoginResponse{}, fmt.Errorf("unexpected error: %w", err)
}
refreshToken, err := s.auth.CreateRefreshToken(user)
if err != nil {
return param.LoginResponse{}, fmt.Errorf("unexpected error: %w", err)
}
return param.LoginResponse{
User: param.UserInfo{
ID: user.ID,
PhoneNumber: user.PhoneNumber,
Name: user.Name,
},
Tokens: param.Tokens{
AccessToken: accessToken,
RefreshToken: refreshToken,
},
}, nil
}

View File

@ -0,0 +1,36 @@
package benefactorservice
import (
"fmt"
entity "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactor"
)
// rol
// login(sms)-> {rigester}() -> next
func (s Service) Register(req param.RegisterRequest) (param.RegisterResponse, error) {
// TODO - we should verify phone number by verification code
// TODO - replace md5 with bcrypt
user := entity.Benefactor{
ID: 0,
PhoneNumber: req.PhoneNumber,
Name: req.Name,
Password: getMD5Hash(req.Password),
Role: entity.BenefactorRole,
}
// create new user in storage
createdUser, err := s.repo.Register(user)
if err != nil {
return param.RegisterResponse{}, fmt.Errorf("unexpected error: %w", err)
}
// return created user
return param.RegisterResponse{User: param.UserInfo{
ID: createdUser.ID,
PhoneNumber: createdUser.Name,
Name: createdUser.PhoneNumber,
}}, nil
}

View File

@ -0,0 +1,27 @@
package benefactorservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
)
type Repository interface {
Register(benefactor entity.Benefactor) (entity.Benefactor, error)
GetUserByPhoneNumber(phoneNumber string) (entity.Benefactor, error)
GetUserByID(ctx context.Context, userID uint) (entity.Benefactor, error)
}
type AuthGenerator interface {
CreateAccessToken(benefactor entity.Benefactor) (string, error)
CreateRefreshToken(benefactor entity.Benefactor) (string, error)
}
type Service struct {
auth AuthGenerator
repo Repository
}
func New(authGenerator AuthGenerator, repo Repository) Service {
return Service{auth: authGenerator, repo: repo}
}

View File

@ -0,0 +1 @@
package benefactorservice

View File

@ -0,0 +1 @@
package staffservice

View File

@ -0,0 +1,45 @@
package staffservice
import (
"fmt"
"gameapp/param"
"gameapp/pkg/richerror"
)
func (s Service) Login(req param.LoginRequest) (param.LoginResponse, error) {
const op = "benefactorservice.Login"
// TODO - it would be better to user two separate method for existence check and getUserByPhoneNumber
user, err := s.repo.GetUserByPhoneNumber(req.PhoneNumber)
if err != nil {
return param.LoginResponse{}, richerror.New(op).WithErr(err).
WithMeta(map[string]interface{}{"phone_number": req.PhoneNumber})
}
if user.Password != getMD5Hash(req.Password) {
return param.LoginResponse{}, fmt.Errorf("username or password isn't correct")
}
accessToken, err := s.auth.CreateAccessToken(user)
if err != nil {
return param.LoginResponse{}, fmt.Errorf("unexpected error: %w", err)
}
refreshToken, err := s.auth.CreateRefreshToken(user)
if err != nil {
return param.LoginResponse{}, fmt.Errorf("unexpected error: %w", err)
}
return param.LoginResponse{
User: param.UserInfo{
ID: user.ID,
PhoneNumber: user.PhoneNumber,
Name: user.Name,
},
Tokens: param.Tokens{
AccessToken: accessToken,
RefreshToken: refreshToken,
},
}, nil
}

View File

@ -0,0 +1,27 @@
package staffservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
)
type Repository interface {
Register(benefactor entity.Benefactor) (entity.Benefactor, error)
GetUserByPhoneNumber(phoneNumber string) (entity.Benefactor, error)
GetUserByID(ctx context.Context, userID uint) (entity.Benefactor, error)
}
type AuthGenerator interface {
CreateAccessToken(benefactor entity.Benefactor) (string, error)
CreateRefreshToken(benefactor entity.Benefactor) (string, error)
}
type Service struct {
auth AuthGenerator
repo Repository
}
func New(authGenerator AuthGenerator, repo Repository) Service {
return Service{auth: authGenerator, repo: repo}
}