forked from ebhomengo/niki
feat(niki): add skelton for admin | super-admin | staff | benefactor services
This commit is contained in:
parent
8841987502
commit
3eea2c0d1d
|
@ -7,12 +7,13 @@ type Admin struct {
|
||||||
FirstName string
|
FirstName string
|
||||||
LastName string
|
LastName string
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
|
Role AdminRole
|
||||||
Address string
|
Address string
|
||||||
Description string
|
Description string
|
||||||
Email string
|
Email string
|
||||||
City string
|
City string
|
||||||
Gender UserGender
|
Gender Gender
|
||||||
Status BenefactorStatus
|
Status AdminStatus
|
||||||
Birthday time.Time
|
Birthday time.Time
|
||||||
StatusChangedAt time.Time
|
StatusChangedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ type Benefactor struct {
|
||||||
Description string
|
Description string
|
||||||
Email string
|
Email string
|
||||||
City string
|
City string
|
||||||
Gender UserGender
|
Gender Gender
|
||||||
Status BenefactorStatus
|
Status BenefactorStatus
|
||||||
Birthday time.Time
|
Birthday time.Time
|
||||||
StatusChangedAt time.Time
|
StatusChangedAt time.Time
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminparam
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminparam
|
|
@ -0,0 +1,7 @@
|
||||||
|
package benefactorparam
|
||||||
|
|
||||||
|
type BenefactorProfileRequest struct{}
|
||||||
|
|
||||||
|
type BenefactorProfileResponse struct {
|
||||||
|
Benefactor entity.Benefactor
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package benefactorparam
|
||||||
|
|
||||||
|
type BenefactorLoginRequest struct{}
|
||||||
|
|
||||||
|
type BenefactorLoginResponse struct {
|
||||||
|
Benefactor entity.Benefactor
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package benefactorparam
|
||||||
|
|
||||||
|
import entity "git.gocasts.ir/ebhomengo/niki/entity"
|
||||||
|
|
||||||
|
type BenefactorRegisterRequest struct{}
|
||||||
|
|
||||||
|
type BenefactorRegisterResponse struct {
|
||||||
|
Benefactor entity.Benefactor
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package benefactorparam
|
|
@ -0,0 +1 @@
|
||||||
|
package staffparam
|
|
@ -0,0 +1 @@
|
||||||
|
package staffparam
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package adminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package superadminservice
|
|
@ -0,0 +1 @@
|
||||||
|
package benefactorservice
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package benefactorservice
|
|
@ -0,0 +1 @@
|
||||||
|
package staffservice
|
|
@ -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
|
||||||
|
}
|
|
@ -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}
|
||||||
|
}
|
Loading…
Reference in New Issue