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 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
} }

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 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

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}
}