nquest/pkg/service/team.go

118 lines
2.6 KiB
Go

package service
import (
"context"
"errors"
"slices"
"gitrepo.ru/neonxp/nquest/pkg/models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
var (
ErrTeamNotFound = errors.New("team not found")
)
type Team struct {
DB *gorm.DB
}
// NewTeam returns new Team.
func NewTeam(db *gorm.DB) *Team {
return &Team{
DB: db,
}
}
func (ts *Team) List(ctx context.Context) ([]*models.Team, error) {
teams := []*models.Team{}
return teams, ts.DB.WithContext(ctx).Preload("Members").Find(&teams).Error
}
func (ts *Team) Create(ctx context.Context, name string, user *models.User) (*models.Team, error) {
t := &models.Team{
Name: name,
Members: []*models.TeamMember{{
User: user,
Role: models.Captain,
}},
}
db := ts.DB.WithContext(ctx)
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
return t, err
}
return t, db.Create(t).Error
}
func (ts *Team) GetByID(ctx context.Context, id uint) (*models.Team, error) {
t := new(models.Team)
err := ts.DB.
WithContext(ctx).
Preload("Members").
Preload("Members.User").
Preload("Requests").
Preload("Requests.User").
First(t, id).
Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrTeamNotFound
}
return nil, err
}
return t, nil
}
func (ts *Team) Request(ctx context.Context, team *models.Team, user *models.User) error {
return ts.DB.
WithContext(ctx).
Clauses(clause.OnConflict{DoNothing: true}).
Create(&models.TeamRequest{
Team: team,
User: user,
}).
Error
}
func (ts *Team) ApproveMember(ctx context.Context, team *models.Team, user *models.User) error {
team.Requests = slices.DeleteFunc(team.Requests, func(tr *models.TeamRequest) bool {
return tr.UserID == user.ID
})
team.Members = append(team.Members, &models.TeamMember{
Team: team,
User: user,
Role: models.Member,
})
db := ts.DB.WithContext(ctx)
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
return err
}
return db.Save(team).Error
}
func (ts *Team) DeclineMember(ctx context.Context, team *models.Team, user *models.User) error {
team.Requests = slices.DeleteFunc(team.Requests, func(tr *models.TeamRequest) bool {
return tr.UserID == user.ID
})
db := ts.DB.WithContext(ctx)
if err := db.Delete(&models.TeamRequest{}, `user_id = ?`, user.ID).Error; err != nil {
return err
}
return db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(team).Error
}
func (ts *Team) RemoveMember(ctx context.Context, team *models.Team, user *models.User) error {
return ts.DB.WithContext(ctx).Delete(&models.TeamMember{}, `user_id = ? and team_id = ?`, user.ID, team.ID).Error
}