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 }