package app import ( "context" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/services/scenarios_service" proto "evening_detective_server/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *server) AddScenario(ctx context.Context, req *proto.AddScenarioReq) (*proto.AddScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } id, err := s.scenarioService.AddScenario(ctx, req.Name, claims.UserID) if err != nil { return nil, scenarioErrorStatus(err, "не удалось создать сценарий") } return &proto.AddScenarioRsp{ ID: int32(id), }, nil } func (s *server) GetMyScenarios(ctx context.Context, _ *proto.GetMyScenariosReq) (*proto.GetMyScenariosRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } scenarios, err := s.scenarioService.GetScenariosByAuthorID(ctx, claims.UserID) if err != nil { return nil, scenarioErrorStatus(err, "не удалось получить сценарии автора") } return &proto.GetMyScenariosRsp{ Scenarios: mapScenarios(scenarios), }, nil } func (s *server) GetScenariosCatalog(ctx context.Context, _ *proto.GetScenariosCatalogReq) (*proto.GetScenariosCatalogRsp, error) { scenarios, err := s.scenarioService.GetScenariosCatalog(ctx) if err != nil { return nil, scenarioErrorStatus(err, "не удалось получить каталог сценариев") } if err := s.addScenarioRatings(ctx, scenarios); err != nil { return nil, scenarioErrorStatus(err, "не удалось получить рейтинг сценариев") } return &proto.GetScenariosCatalogRsp{ Scenarios: mapScenarios(scenarios), }, nil } func (s *server) GetFullScenario(ctx context.Context, req *proto.GetScenarioReq) (*proto.GetScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } scenario, err := s.scenarioService.GetFullScenarioByID(ctx, int(req.ID)) if err != nil { return nil, scenarioErrorStatus(err, "не удалось получить сценарий") } return &proto.GetScenarioRsp{ Scenario: mapScenario(scenario), }, nil } func (s *server) GetScenario(ctx context.Context, req *proto.GetScenarioReq) (*proto.GetScenarioRsp, error) { scenario, err := s.scenarioService.GetScenarioByID(ctx, int(req.ID)) if err != nil { return nil, scenarioErrorStatus(err, "не удалось получить сценарий") } if err := s.addScenarioRatings(ctx, []*scenarios_service.Scenario{scenario}); err != nil { return nil, scenarioErrorStatus(err, "не удалось получить рейтинг сценария") } return &proto.GetScenarioRsp{ Scenario: mapScenario(scenario), }, nil } func (s *server) addScenarioRatings(ctx context.Context, scenarios []*scenarios_service.Scenario) error { for _, scenario := range scenarios { average, count, err := s.reviewService.ScenarioRating(ctx, scenario.ID) if err != nil { return err } scenario.AverageRating = average scenario.ReviewsCount = count } return nil } func (s *server) UpdateScenario(ctx context.Context, req *proto.UpdateScenarioReq) (*proto.UpdateScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.scenarioService.UpdateScenarioByID( ctx, int(req.ID), req.Name, req.Description, req.Image, claims.UserID, roles.HasRole(claims, roles.Admin), ) if err != nil { return nil, scenarioErrorStatus(err, "не удалось изменить сценарий") } return &proto.UpdateScenarioRsp{}, nil } func (s *server) PublicScenario(ctx context.Context, req *proto.PublicScenarioReq) (*proto.PublicScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.scenarioService.UpdateScenarioStatusByID( ctx, int(req.ID), "public", claims.UserID, roles.HasRole(claims, roles.Admin), // публикация = момент отчуждения прав ) if err != nil { return nil, scenarioErrorStatus(err, "не удалось опубликовать сценарий") } return &proto.PublicScenarioRsp{}, nil } func (s *server) DraftScenario(ctx context.Context, req *proto.DraftScenarioReq) (*proto.DraftScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } // Снять с публикации опубликованный сценарий может только админ: // исключительное право отчуждено Оператору в момент публикации // (п. 7.2 Пользовательского соглашения, ст. 1234, 1269 ГК РФ). if !roles.HasRole(claims, roles.Admin) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } err := s.scenarioService.UpdateScenarioStatusByID( ctx, int(req.ID), "draft", claims.UserID, true, ) if err != nil { return nil, scenarioErrorStatus(err, "не удалось снять сценарий с публикации") } return &proto.DraftScenarioRsp{}, nil } func (s *server) DeleteScenario(ctx context.Context, req *proto.DeleteScenarioReq) (*proto.DeleteScenarioRsp, error) { claims, claimsErr := claimsFromContext(ctx) if claimsErr != nil { return nil, claimsErr } if !roles.HasRole(claims, roles.Author) { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } // Автор не может удалить опубликованный сценарий (исключительное право // отчуждено); админ может. err := s.scenarioService.DeleteScenarioByID( ctx, int(req.ID), claims.UserID, roles.HasRole(claims, roles.Admin), ) if err != nil { return nil, scenarioErrorStatus(err, "не удалось удалить сценарий") } return &proto.DeleteScenarioRsp{}, nil }