package app import ( "context" "errors" "mime" "evening_detective_server/internal/modules/processor_jwt" "evening_detective_server/internal/modules/roles" "evening_detective_server/internal/modules/team_qr_pdf" "evening_detective_server/internal/repos/games_repo" "evening_detective_server/proto" "google.golang.org/genproto/googleapis/api/httpbody" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) func (s *server) DownloadTeamQR(ctx context.Context, req *proto.GetGameReq) (*httpbody.HttpBody, error) { claims, ok := ctx.Value("claims").(*processor_jwt.JWTClaims) if !ok || claims == nil { return nil, status.Error(codes.Unauthenticated, "необходима авторизация") } if !roles.HasRole(claims, roles.Organizer) && !roles.HasRole(claims, roles.Author) { return nil, status.Error(codes.PermissionDenied, "permission denied") } if req == nil || req.Id <= 0 { return nil, status.Error(codes.InvalidArgument, "некорректный идентификатор игры") } data, filename, err := s.teamService.DownloadTeamQR(ctx, int(req.Id)) if err != nil { switch { case errors.Is(err, games_repo.ErrGameNotFound): return nil, status.Error(codes.NotFound, err.Error()) case errors.Is(err, team_qr_pdf.ErrNoCards): return nil, status.Error(codes.FailedPrecondition, err.Error()) default: return nil, status.Error(codes.Internal, err.Error()) } } if err := grpc.SetHeader(ctx, metadata.Pairs( "Content-Disposition", mime.FormatMediaType("attachment", map[string]string{"filename": filename}), "X-Content-Type-Options", "nosniff", "Cache-Control", "no-store", )); err != nil { return nil, status.Error(codes.Internal, "не удалось установить заголовки PDF") } return &httpbody.HttpBody{ContentType: "application/pdf", Data: data}, nil }