add teams operations

This commit is contained in:
2026-07-28 00:51:25 +07:00
parent 5a5b36e44d
commit f6934e9d5b
11 changed files with 199 additions and 35 deletions
+4 -2
View File
@@ -749,8 +749,10 @@ message Game {
}
message Team {
int32 id = 1;
string name = 2;
int32 id = 1;
string name = 2;
string status = 3;
string password = 4;
}
message GetGameReq {
+1
View File
@@ -86,6 +86,7 @@ func main() {
teamRepo,
scenariosRepo,
os.Getenv("FILE_PREFIX_DOMAIN"),
passwordGenerator,
)
// Create a listener on TCP port
@@ -1996,6 +1996,12 @@
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
+45 -3
View File
@@ -545,7 +545,19 @@ func (s *server) AddTeam(ctx context.Context, req *proto.AddTeamReq) (*proto.Add
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
panic("unimplemented")
err := s.gameService.AddTeam(
ctx,
claims.UserID,
int(req.GameId),
req.Name,
)
if err != nil {
return &proto.AddTeamRsp{
Error: err.Error(),
}, nil
}
return &proto.AddTeamRsp{}, nil
}
func (s *server) UpdateTeam(ctx context.Context, req *proto.UpdateTeamReq) (*proto.UpdateTeamRsp, error) {
@@ -554,7 +566,18 @@ func (s *server) UpdateTeam(ctx context.Context, req *proto.UpdateTeamReq) (*pro
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
panic("unimplemented")
err := s.gameService.UpdateTeam(
ctx,
int(req.Id),
req.Name,
)
if err != nil {
return &proto.UpdateTeamRsp{
Error: err.Error(),
}, nil
}
return &proto.UpdateTeamRsp{}, nil
}
func (s *server) DeleteTeam(ctx context.Context, req *proto.DeleteTeamReq) (*proto.DeleteTeamRsp, error) {
@@ -563,7 +586,17 @@ func (s *server) DeleteTeam(ctx context.Context, req *proto.DeleteTeamReq) (*pro
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
panic("unimplemented")
err := s.gameService.DeleteTeam(
ctx,
int(req.Id),
)
if err != nil {
return &proto.DeleteTeamRsp{
Error: err.Error(),
}, nil
}
return &proto.DeleteTeamRsp{}, nil
}
func (s *server) GiveTeamApplications(ctx context.Context, req *proto.GiveTeamApplicationsReq) (*proto.GiveTeamApplicationsRsp, error) {
@@ -582,3 +615,12 @@ func (s *server) GetTeamActions(ctx context.Context, req *proto.GetTeamActionsRe
func (s *server) AddTeamAction(ctx context.Context, req *proto.AddTeamActionReq) (*proto.AddTeamActionRsp, error) {
panic("unimplemented")
}
func (s *server) DeleteLastTeamAction(ctx context.Context, req *proto.DeleteLastTeamActionReq) (*proto.DeleteLastTeamActionRsp, error) {
claims := ctx.Value("claims").(*processor_jwt.JWTClaims)
if !roles.HasRole(claims, roles.Author) {
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
panic("unimplemented")
}
+4 -2
View File
@@ -9,8 +9,10 @@ func mapTeam(
o *game_service.Team,
) *proto.Team {
return &proto.Team{
Id: int32(o.ID),
Name: o.Name,
Id: int32(o.ID),
Name: o.Name,
Status: o.Status,
Password: o.Password,
}
}
+1
View File
@@ -3,5 +3,6 @@ package repos
type Team struct {
ID int
Name string
Status string
Password string
}
+74 -14
View File
@@ -2,11 +2,16 @@ package teams_repo
import (
"context"
"errors"
"evening_detective_server/internal/repos"
"github.com/jackc/pgx/v5/pgxpool"
)
var (
ErrTeamNotFound = errors.New("Команда не найдена")
)
type TeamsRepo struct {
pool *pgxpool.Pool
}
@@ -24,20 +29,12 @@ func (r *TeamsRepo) GetTeamsByGameID(
rows, err := r.pool.Query(
ctx,
`SELECT
scenarios.id,
scenarios.name,
scenarios.description,
scenarios.image,
scenarios.scenario,
users.id,
users.username,
scenarios.status,
scenarios.updated_at,
scenarios.created_at,
scenarios.published_at
FROM scenarios
LEFT JOIN users on scenarios.author_id = users.id
WHERE scenarios.author_id = $1 and is_deleted = FALSE
id,
name,
status,
password
FROM teams
WHERE game_id = $1
ORDER BY created_at DESC`,
gameId,
)
@@ -52,6 +49,7 @@ func (r *TeamsRepo) GetTeamsByGameID(
err := rows.Scan(
&team.ID,
&team.Name,
&team.Status,
&team.Password,
)
if err != nil {
@@ -65,3 +63,65 @@ func (r *TeamsRepo) GetTeamsByGameID(
return teams, nil
}
func (r *TeamsRepo) AddTeam(
ctx context.Context,
creatorId int,
gameId int,
name string,
scenarioId int,
password string,
) (int, error) {
id := 0
err := r.pool.QueryRow(
ctx,
`INSERT INTO teams (name, creator_id, game_id, scenario_id, password)
VALUES ($1, $2, $3, $4, $5)
RETURNING id`,
name,
creatorId,
gameId,
scenarioId,
password,
).Scan(&id)
if err != nil {
return 0, err
}
return id, nil
}
func (r *TeamsRepo) UpdateTeam(ctx context.Context, teamId int, name string) error {
tag, err := r.pool.Exec(
ctx,
`UPDATE teams
SET
name = $1
WHERE id = $2`,
name,
teamId,
)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrTeamNotFound
}
return nil
}
func (r *TeamsRepo) DeleteTeam(ctx context.Context, teamId int) error {
tag, err := r.pool.Exec(
ctx,
`DELETE FROM teams
WHERE id = $1`,
teamId,
)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrTeamNotFound
}
return nil
}
+38 -8
View File
@@ -2,6 +2,7 @@ package game_service
import (
"context"
"evening_detective_server/internal/modules/password_generator"
"evening_detective_server/internal/repos/games_repo"
"evening_detective_server/internal/repos/scenarios_repo"
"evening_detective_server/internal/repos/teams_repo"
@@ -9,10 +10,11 @@ import (
)
type GameService struct {
gamesRepo *games_repo.GamesRepo
teamsRepo *teams_repo.TeamsRepo
scenariosRepo *scenarios_repo.ScenariosRepo
domain string
gamesRepo *games_repo.GamesRepo
teamsRepo *teams_repo.TeamsRepo
scenariosRepo *scenarios_repo.ScenariosRepo
domain string
passwordGenerator password_generator.IPasswordGenerator
}
func NewGameService(
@@ -20,12 +22,14 @@ func NewGameService(
teamsRepo *teams_repo.TeamsRepo,
scenariosRepo *scenarios_repo.ScenariosRepo,
domain string,
passwordGenerator password_generator.IPasswordGenerator,
) *GameService {
return &GameService{
gamesRepo: gamesRepo,
teamsRepo: teamsRepo,
scenariosRepo: scenariosRepo,
domain: domain,
gamesRepo: gamesRepo,
teamsRepo: teamsRepo,
scenariosRepo: scenariosRepo,
domain: domain,
passwordGenerator: passwordGenerator,
}
}
@@ -91,3 +95,29 @@ func (s *GameService) UpdateGame(
) error {
return s.gamesRepo.UpdateGame(ctx, id, name, description, startAt, scenarioId)
}
func (s *GameService) AddTeam(
ctx context.Context,
creatorId int,
gameId int,
name string,
) error {
game, err := s.gamesRepo.GetGameByID(ctx, gameId)
if err != nil {
return err
}
password, err := s.passwordGenerator.Generate()
if err != nil {
return err
}
_, err = s.teamsRepo.AddTeam(ctx, creatorId, gameId, name, game.ScenarioId, password)
return err
}
func (s *GameService) UpdateTeam(ctx context.Context, teamId int, name string) error {
return s.teamsRepo.UpdateTeam(ctx, teamId, name)
}
func (s *GameService) DeleteTeam(ctx context.Context, teamId int) error {
return s.teamsRepo.DeleteTeam(ctx, teamId)
}
+1
View File
@@ -3,5 +3,6 @@ package game_service
type Team struct {
ID int
Name string
Status string
Password string
}
@@ -8,6 +8,7 @@ func mapTeam(
return &Team{
ID: o.ID,
Name: o.Name,
Status: o.Status,
Password: o.Password,
}
}
+20 -2
View File
@@ -3129,6 +3129,8 @@ type Team struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -3177,6 +3179,20 @@ func (x *Team) GetName() string {
return ""
}
func (x *Team) GetStatus() string {
if x != nil {
return x.Status
}
return ""
}
func (x *Team) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
type GetGameReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
@@ -4344,10 +4360,12 @@ const file_main_proto_rawDesc = "" +
"\bstart_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\astartAt\x12\x16\n" +
"\x06status\x18\x05 \x01(\tR\x06status\x12D\n" +
"\bscenario\x18\x06 \x01(\v2(.crabs.evening_detective_server.ScenarioR\bscenario\x12:\n" +
"\x05teams\x18\a \x03(\v2$.crabs.evening_detective_server.TeamR\x05teams\"*\n" +
"\x05teams\x18\a \x03(\v2$.crabs.evening_detective_server.TeamR\x05teams\"^\n" +
"\x04Team\x12\x0e\n" +
"\x02id\x18\x01 \x01(\x05R\x02id\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\"\x1c\n" +
"\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" +
"\x06status\x18\x03 \x01(\tR\x06status\x12\x1a\n" +
"\bpassword\x18\x04 \x01(\tR\bpassword\"\x1c\n" +
"\n" +
"GetGameReq\x12\x0e\n" +
"\x02id\x18\x01 \x01(\x05R\x02id\"\\\n" +