8244 lines
		
	
	
		
			255 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			8244 lines
		
	
	
		
			255 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Code generated by ogen, DO NOT EDIT.
 | 
						||
 | 
						||
package api
 | 
						||
 | 
						||
import (
 | 
						||
	"context"
 | 
						||
	"net/http"
 | 
						||
	"time"
 | 
						||
 | 
						||
	"github.com/go-faster/errors"
 | 
						||
	"go.opentelemetry.io/otel/attribute"
 | 
						||
	"go.opentelemetry.io/otel/codes"
 | 
						||
	"go.opentelemetry.io/otel/metric"
 | 
						||
	semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
 | 
						||
	"go.opentelemetry.io/otel/trace"
 | 
						||
 | 
						||
	ht "github.com/ogen-go/ogen/http"
 | 
						||
	"github.com/ogen-go/ogen/middleware"
 | 
						||
	"github.com/ogen-go/ogen/ogenerrors"
 | 
						||
)
 | 
						||
 | 
						||
type codeRecorder struct {
 | 
						||
	http.ResponseWriter
 | 
						||
	status int
 | 
						||
}
 | 
						||
 | 
						||
func (c *codeRecorder) WriteHeader(status int) {
 | 
						||
	c.status = status
 | 
						||
	c.ResponseWriter.WriteHeader(status)
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2BufferGoodsTaskGetRequest handles GET /api/v2/buffer/goods/task operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию о товарах и ошибках в
 | 
						||
// товарах из загрузки в обработке.
 | 
						||
// <div class="description_important">
 | 
						||
// Необработанная загрузка — это загрузка скидок для <a
 | 
						||
// href="/openapi/promotion#tag/Kalendar-akcij">календаря акций</a>. Такие
 | 
						||
// скидки применятся к товарам только в момент начала
 | 
						||
// акции.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/buffer/goods/task
 | 
						||
func (s *Server) handleAPIV2BufferGoodsTaskGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/buffer/goods/task"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2BufferGoodsTaskGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2BufferGoodsTaskGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2BufferGoodsTaskGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2BufferGoodsTaskGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2BufferGoodsTaskGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2BufferGoodsTaskGetOperation,
 | 
						||
			OperationSummary: "Детализация необработанной загрузки",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
				{
 | 
						||
					Name: "uploadID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.UploadID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2BufferGoodsTaskGetParams
 | 
						||
			Response = APIV2BufferGoodsTaskGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2BufferGoodsTaskGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2BufferGoodsTaskGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2BufferGoodsTaskGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2BufferGoodsTaskGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2BufferTasksGetRequest handles GET /api/v2/buffer/tasks operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию про загрузку скидок в
 | 
						||
// обработке.
 | 
						||
// <div class="description_important">
 | 
						||
// Необработанная загрузка — это загрузка скидок для <a
 | 
						||
// href="/openapi/promotion#tag/Kalendar-akcij">календаря акций</a>. Такие
 | 
						||
// скидки применятся к товарам только в момент начала
 | 
						||
// акции.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/buffer/tasks
 | 
						||
func (s *Server) handleAPIV2BufferTasksGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/buffer/tasks"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2BufferTasksGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2BufferTasksGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2BufferTasksGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2BufferTasksGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2BufferTasksGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2BufferTasksGetOperation,
 | 
						||
			OperationSummary: "Состояние необработанной загрузки",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "uploadID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.UploadID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2BufferTasksGetParams
 | 
						||
			Response = APIV2BufferTasksGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2BufferTasksGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2BufferTasksGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2BufferTasksGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2BufferTasksGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2HistoryGoodsTaskGetRequest handles GET /api/v2/history/goods/task operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию о товарах и об
 | 
						||
// ошибках в товарах в обработанной загрузке.
 | 
						||
// <div class="description_important">
 | 
						||
// Обработанная загрузка — это загрузка цен и скидок
 | 
						||
// для <a
 | 
						||
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post">товаров</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post">размеров товаров</a>, а также скидок <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post">WB Клуба</a>.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/history/goods/task
 | 
						||
func (s *Server) handleAPIV2HistoryGoodsTaskGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/history/goods/task"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2HistoryGoodsTaskGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2HistoryGoodsTaskGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2HistoryGoodsTaskGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2HistoryGoodsTaskGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2HistoryGoodsTaskGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2HistoryGoodsTaskGetOperation,
 | 
						||
			OperationSummary: "Детализация обработанной загрузки",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
				{
 | 
						||
					Name: "uploadID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.UploadID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2HistoryGoodsTaskGetParams
 | 
						||
			Response = APIV2HistoryGoodsTaskGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2HistoryGoodsTaskGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2HistoryGoodsTaskGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2HistoryGoodsTaskGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2HistoryGoodsTaskGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2HistoryTasksGetRequest handles GET /api/v2/history/tasks operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию об обработанной
 | 
						||
// загрузке цен и скидок.
 | 
						||
// <div class="description_important">
 | 
						||
// Обработанная загрузка — это загрузка цен и скидок
 | 
						||
// для <a
 | 
						||
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post">товаров</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post">размеров товаров</a>, а также скидок <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post">WB Клуба</a>.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/history/tasks
 | 
						||
func (s *Server) handleAPIV2HistoryTasksGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/history/tasks"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2HistoryTasksGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2HistoryTasksGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2HistoryTasksGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2HistoryTasksGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2HistoryTasksGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2HistoryTasksGetOperation,
 | 
						||
			OperationSummary: "Состояние обработанной загрузки",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "uploadID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.UploadID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2HistoryTasksGetParams
 | 
						||
			Response = APIV2HistoryTasksGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2HistoryTasksGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2HistoryTasksGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2HistoryTasksGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2HistoryTasksGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2ListGoodsFilterGetRequest handles GET /api/v2/list/goods/filter operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию о товарах по их
 | 
						||
// артикулам: цены, валюту, общие скидки и скидки для [WB
 | 
						||
// Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post).
 | 
						||
// <br><br>
 | 
						||
// Чтобы получить информацию обо всех товарах продавца,
 | 
						||
// оставьте артикул пустым, установите `limit=1000`, в
 | 
						||
// параметре `offset` установите смещение по количеству
 | 
						||
// записей. Количество нужно рассчитать по формуле: `offset`
 | 
						||
// плюс `limit` из предыдущего запроса. Повторяйте запрос,
 | 
						||
// пока вы не получите ответ с пустым массивом.<br> Чтобы
 | 
						||
// получить информацию о размерах товара, используйте
 | 
						||
// [отдельный
 | 
						||
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/list/goods/filter
 | 
						||
func (s *Server) handleAPIV2ListGoodsFilterGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/list/goods/filter"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2ListGoodsFilterGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2ListGoodsFilterGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2ListGoodsFilterGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2ListGoodsFilterGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2ListGoodsFilterGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2ListGoodsFilterGetOperation,
 | 
						||
			OperationSummary: "Получить товары с ценами",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
				{
 | 
						||
					Name: "filterNmID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.FilterNmID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2ListGoodsFilterGetParams
 | 
						||
			Response = APIV2ListGoodsFilterGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2ListGoodsFilterGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2ListGoodsFilterGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2ListGoodsFilterGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2ListGoodsFilterGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2ListGoodsSizeNmGetRequest handles GET /api/v2/list/goods/size/nm operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию обо всех размерах
 | 
						||
// одного товарам: цены, валюту, общие скидки и скидки
 | 
						||
// для [WB
 | 
						||
// Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post).
 | 
						||
// <br><br>
 | 
						||
// Работает только для товаров из категорий, где можно
 | 
						||
// устанавливать цены отдельно для разных размеров. Для
 | 
						||
// таких товаров `editableSizePrice: true`.
 | 
						||
// <br><br>
 | 
						||
// Чтобы получить информацию о самом товаре,
 | 
						||
// используйте [отдельный
 | 
						||
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1filter/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/list/goods/size/nm
 | 
						||
func (s *Server) handleAPIV2ListGoodsSizeNmGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/list/goods/size/nm"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2ListGoodsSizeNmGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2ListGoodsSizeNmGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2ListGoodsSizeNmGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2ListGoodsSizeNmGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2ListGoodsSizeNmGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2ListGoodsSizeNmGetOperation,
 | 
						||
			OperationSummary: "Получить размеры товара с ценами",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
				{
 | 
						||
					Name: "nmID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.NmID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2ListGoodsSizeNmGetParams
 | 
						||
			Response = APIV2ListGoodsSizeNmGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2ListGoodsSizeNmGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2ListGoodsSizeNmGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2ListGoodsSizeNmGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2ListGoodsSizeNmGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2QuarantineGoodsGetRequest handles GET /api/v2/quarantine/goods operation.
 | 
						||
//
 | 
						||
// Метод предоставляет информацию о товарах в карантине.
 | 
						||
// <br><br>
 | 
						||
// Если новая цена товара со скидкой будет минимум в 3
 | 
						||
// раза меньше старой, товар попадёт [в
 | 
						||
// карантин](https://seller.wildberries.ru/discount-and-prices/quarantine) и будет
 | 
						||
// продаваться по старой цене. Ошибка об этом будет в
 | 
						||
// ответах методов [состояний
 | 
						||
// загрузок](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get).
 | 
						||
// <br><br>
 | 
						||
// Вы можете изменить цену или скидку с помощью API либо
 | 
						||
// вывести товар из карантина [в личном
 | 
						||
// кабинете](https://seller.wildberries.ru/discount-and-prices/quarantine).
 | 
						||
// <br><br>
 | 
						||
// Для товаров с [поразмерной установкой
 | 
						||
// цен](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post)
 | 
						||
// карантин не применяется.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v2/quarantine/goods
 | 
						||
func (s *Server) handleAPIV2QuarantineGoodsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/quarantine/goods"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2QuarantineGoodsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2QuarantineGoodsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2QuarantineGoodsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV2QuarantineGoodsGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV2QuarantineGoodsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2QuarantineGoodsGetOperation,
 | 
						||
			OperationSummary: "Получить товары в карантине",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV2QuarantineGoodsGetParams
 | 
						||
			Response = APIV2QuarantineGoodsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV2QuarantineGoodsGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2QuarantineGoodsGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2QuarantineGoodsGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2QuarantineGoodsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2UploadTaskClubDiscountPostRequest handles POST /api/v2/upload/task/club-discount operation.
 | 
						||
//
 | 
						||
// Устанавливает скидки для товаров в рамках подписки [WB
 | 
						||
// Клуб](https://seller.wildberries.ru/help-center/article/A-337).
 | 
						||
// <div class="description_important">
 | 
						||
// Получить информацию о процессе установки цен и
 | 
						||
// скидок можно с помощью методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /api/v2/upload/task/club-discount
 | 
						||
func (s *Server) handleAPIV2UploadTaskClubDiscountPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/upload/task/club-discount"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskClubDiscountPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2UploadTaskClubDiscountPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskClubDiscountPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV2UploadTaskClubDiscountPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV2UploadTaskClubDiscountPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2UploadTaskClubDiscountPostOperation,
 | 
						||
			OperationSummary: "Установить скидки WB Клуба",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV2UploadTaskClubDiscountPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV2UploadTaskClubDiscountPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2UploadTaskClubDiscountPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2UploadTaskClubDiscountPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2UploadTaskClubDiscountPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2UploadTaskPostRequest handles POST /api/v2/upload/task operation.
 | 
						||
//
 | 
						||
// Метод устанавливает цены и скидки для товаров.
 | 
						||
// <br><br>
 | 
						||
// Чтобы установить цены и скидки для размеров товара,
 | 
						||
// используйте [отдельный
 | 
						||
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post).
 | 
						||
// <div class="description_important">
 | 
						||
// Получить информацию о процессе установки цен и
 | 
						||
// скидок можно с помощью методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /api/v2/upload/task
 | 
						||
func (s *Server) handleAPIV2UploadTaskPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/upload/task"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2UploadTaskPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV2UploadTaskPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV2UploadTaskPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2UploadTaskPostOperation,
 | 
						||
			OperationSummary: "Установить цены и скидки",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV2UploadTaskPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV2UploadTaskPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2UploadTaskPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2UploadTaskPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2UploadTaskPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV2UploadTaskSizePostRequest handles POST /api/v2/upload/task/size operation.
 | 
						||
//
 | 
						||
// Метод устанавливает цены отдельно для размеров
 | 
						||
// товаров.
 | 
						||
// Работает только для товаров из категорий, где можно
 | 
						||
// устанавливать цены отдельно для разных размеров. Для
 | 
						||
// [таких
 | 
						||
// товаров](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get) `editableSizePrice: true`.
 | 
						||
// Чтобы установить цены и скидки для самих товаров,
 | 
						||
// используйте [отдельный
 | 
						||
// метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post).
 | 
						||
// <div class="description_important">
 | 
						||
// Получить информацию о процессе установки цен и
 | 
						||
// скидок можно с помощью методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get">состояния</a> и <a href="/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get">детализации</a> обработанной загрузки.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 10 запросов за 6 <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">секунд</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Цены и скидки</a>
 | 
						||
// на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /api/v2/upload/task/size
 | 
						||
func (s *Server) handleAPIV2UploadTaskSizePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v2/upload/task/size"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV2UploadTaskSizePostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV2UploadTaskSizePostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV2UploadTaskSizePostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV2UploadTaskSizePostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV2UploadTaskSizePostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV2UploadTaskSizePostOperation,
 | 
						||
			OperationSummary: "Установить цены для размеров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV2UploadTaskSizePostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV2UploadTaskSizePostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV2UploadTaskSizePost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV2UploadTaskSizePost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV2UploadTaskSizePostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3OfficesGetRequest handles GET /api/v3/offices operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список всех складов WB для
 | 
						||
// привязки к складам продавца. Предназначен для
 | 
						||
// определения складов WB, чтобы сдавать готовые заказы
 | 
						||
// по схеме [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v3/offices
 | 
						||
func (s *Server) handleAPIV3OfficesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/offices"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3OfficesGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3OfficesGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3OfficesGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV3OfficesGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3OfficesGetOperation,
 | 
						||
			OperationSummary: "Получить список складов WB",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV3OfficesGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3OfficesGet(ctx)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3OfficesGet(ctx)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3OfficesGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3StocksWarehouseIdDeleteRequest handles DELETE /api/v3/stocks/{warehouseId} operation.
 | 
						||
//
 | 
						||
// Метод удаляет запись об остатках товаров продавца из
 | 
						||
// [списка
 | 
						||
// остатков](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
 | 
						||
// <div class="description_important">
 | 
						||
// <strong>Действие необратимо</strong>. Удаленный остаток
 | 
						||
// будет необходимо загрузить повторно для
 | 
						||
// возобновления продаж.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// DELETE /api/v3/stocks/{warehouseId}
 | 
						||
func (s *Server) handleAPIV3StocksWarehouseIdDeleteRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("DELETE"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdDeleteOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3StocksWarehouseIdDeleteOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdDeleteOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV3StocksWarehouseIdDeleteParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV3StocksWarehouseIdDeleteRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV3StocksWarehouseIdDeleteRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3StocksWarehouseIdDeleteOperation,
 | 
						||
			OperationSummary: "Удалить остатки товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "warehouseId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.WarehouseId,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV3StocksWarehouseIdDeleteReq
 | 
						||
			Params   = APIV3StocksWarehouseIdDeleteParams
 | 
						||
			Response = APIV3StocksWarehouseIdDeleteRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV3StocksWarehouseIdDeleteParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3StocksWarehouseIdDelete(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3StocksWarehouseIdDelete(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3StocksWarehouseIdDeleteResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3StocksWarehouseIdPostRequest handles POST /api/v3/stocks/{warehouseId} operation.
 | 
						||
//
 | 
						||
// Метод предоставляет данные об остатках товаров на
 | 
						||
// [складах продавца](/openapi/work-with-products#tag/Sklady-prodavca).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /api/v3/stocks/{warehouseId}
 | 
						||
func (s *Server) handleAPIV3StocksWarehouseIdPostRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3StocksWarehouseIdPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV3StocksWarehouseIdPostParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV3StocksWarehouseIdPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV3StocksWarehouseIdPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3StocksWarehouseIdPostOperation,
 | 
						||
			OperationSummary: "Получить остатки товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "warehouseId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.WarehouseId,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV3StocksWarehouseIdPostReq
 | 
						||
			Params   = APIV3StocksWarehouseIdPostParams
 | 
						||
			Response = APIV3StocksWarehouseIdPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV3StocksWarehouseIdPostParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3StocksWarehouseIdPost(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3StocksWarehouseIdPost(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3StocksWarehouseIdPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3StocksWarehouseIdPutRequest handles PUT /api/v3/stocks/{warehouseId} operation.
 | 
						||
//
 | 
						||
// Метод обновляет количество остатков товаров
 | 
						||
// продавца [в
 | 
						||
// списке](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
 | 
						||
// <div class="description_important">
 | 
						||
// Названия параметров запроса не валидируются. При
 | 
						||
// отправке некорректных названий вы получите успешный
 | 
						||
// ответ (<code>204</code>), но остатки не обновятся.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// PUT /api/v3/stocks/{warehouseId}
 | 
						||
func (s *Server) handleAPIV3StocksWarehouseIdPutRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("PUT"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/stocks/{warehouseId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3StocksWarehouseIdPutOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3StocksWarehouseIdPutOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3StocksWarehouseIdPutOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV3StocksWarehouseIdPutParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV3StocksWarehouseIdPutRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV3StocksWarehouseIdPutRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3StocksWarehouseIdPutOperation,
 | 
						||
			OperationSummary: "Обновить остатки товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "warehouseId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.WarehouseId,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = OptAPIV3StocksWarehouseIdPutReq
 | 
						||
			Params   = APIV3StocksWarehouseIdPutParams
 | 
						||
			Response = APIV3StocksWarehouseIdPutRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV3StocksWarehouseIdPutParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3StocksWarehouseIdPut(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3StocksWarehouseIdPut(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3StocksWarehouseIdPutResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3WarehousesGetRequest handles GET /api/v3/warehouses operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список всех складов продавца.
 | 
						||
// Может использоваться для получения [остатков
 | 
						||
// товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /api/v3/warehouses
 | 
						||
func (s *Server) handleAPIV3WarehousesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/warehouses"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3WarehousesGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV3WarehousesGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3WarehousesGetOperation,
 | 
						||
			OperationSummary: "Получить список складов продавца",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV3WarehousesGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3WarehousesGet(ctx)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3WarehousesGet(ctx)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3WarehousesGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3WarehousesPostRequest handles POST /api/v3/warehouses operation.
 | 
						||
//
 | 
						||
// Метод создаёт склад продавца для работы с [остатками
 | 
						||
// товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). Нужно привязать к складу продавца [склад WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) для работы по схеме [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller).
 | 
						||
// <div class="description_important">
 | 
						||
// Нельзя привязывать склад WB, который уже используется
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /api/v3/warehouses
 | 
						||
func (s *Server) handleAPIV3WarehousesPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/warehouses"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3WarehousesPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV3WarehousesPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV3WarehousesPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3WarehousesPostOperation,
 | 
						||
			OperationSummary: "Создать склад продавца",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV3WarehousesPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = APIV3WarehousesPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3WarehousesPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3WarehousesPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3WarehousesPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3WarehousesWarehouseIdDeleteRequest handles DELETE /api/v3/warehouses/{warehouseId} operation.
 | 
						||
//
 | 
						||
// Метод удаляет склад продавца из [списка
 | 
						||
// складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// DELETE /api/v3/warehouses/{warehouseId}
 | 
						||
func (s *Server) handleAPIV3WarehousesWarehouseIdDeleteRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("DELETE"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/warehouses/{warehouseId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesWarehouseIdDeleteOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3WarehousesWarehouseIdDeleteOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesWarehouseIdDeleteOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV3WarehousesWarehouseIdDeleteParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response APIV3WarehousesWarehouseIdDeleteRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3WarehousesWarehouseIdDeleteOperation,
 | 
						||
			OperationSummary: "Удалить склад продавца",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "warehouseId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.WarehouseId,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = APIV3WarehousesWarehouseIdDeleteParams
 | 
						||
			Response = APIV3WarehousesWarehouseIdDeleteRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV3WarehousesWarehouseIdDeleteParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3WarehousesWarehouseIdDelete(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3WarehousesWarehouseIdDelete(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3WarehousesWarehouseIdDeleteResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleAPIV3WarehousesWarehouseIdPutRequest handles PUT /api/v3/warehouses/{warehouseId} operation.
 | 
						||
//
 | 
						||
// Метод обновляет данные склада продавца в [списке
 | 
						||
// складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get).
 | 
						||
// Данные о привязанном [складе
 | 
						||
// WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) можно
 | 
						||
// изменить один раз в сутки.
 | 
						||
// <div class="description_important">
 | 
						||
// Нельзя привязывать склад WB, который уже используется
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 300 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Маркетплейс</a> на
 | 
						||
// один аккаунт продавца.
 | 
						||
// <br><br>
 | 
						||
// Один запрос с кодом ответа <code>409</code> учитывается как 5
 | 
						||
// запросов
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// PUT /api/v3/warehouses/{warehouseId}
 | 
						||
func (s *Server) handleAPIV3WarehousesWarehouseIdPutRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("PUT"),
 | 
						||
		semconv.HTTPRouteKey.String("/api/v3/warehouses/{warehouseId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), APIV3WarehousesWarehouseIdPutOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: APIV3WarehousesWarehouseIdPutOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, APIV3WarehousesWarehouseIdPutOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeAPIV3WarehousesWarehouseIdPutParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeAPIV3WarehousesWarehouseIdPutRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response APIV3WarehousesWarehouseIdPutRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    APIV3WarehousesWarehouseIdPutOperation,
 | 
						||
			OperationSummary: "Обновить склад продавца",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "warehouseId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.WarehouseId,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *APIV3WarehousesWarehouseIdPutReq
 | 
						||
			Params   = APIV3WarehousesWarehouseIdPutParams
 | 
						||
			Response = APIV3WarehousesWarehouseIdPutRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackAPIV3WarehousesWarehouseIdPutParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.APIV3WarehousesWarehouseIdPut(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.APIV3WarehousesWarehouseIdPut(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeAPIV3WarehousesWarehouseIdPutResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2BarcodesPostRequest handles POST /content/v2/barcodes operation.
 | 
						||
//
 | 
						||
// Метод генерирует массив уникальных баркодов для
 | 
						||
// создания размера в [карточке
 | 
						||
// товара](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post). Можно использовать, если у вас нет собственных баркодов.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/barcodes
 | 
						||
func (s *Server) handleContentV2BarcodesPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/barcodes"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2BarcodesPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2BarcodesPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2BarcodesPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2BarcodesPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2BarcodesPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2BarcodesPostOperation,
 | 
						||
			OperationSummary: "Генерация баркодов",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2BarcodesPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2BarcodesPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2BarcodesPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2BarcodesPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2BarcodesPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsDeleteTrashPostRequest handles POST /content/v2/cards/delete/trash operation.
 | 
						||
//
 | 
						||
// Метод переносит [карточки товаров в
 | 
						||
// корзину](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). При этом карточки товаров не удаляются, их можно [восстановить](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1recover/post).
 | 
						||
// <div class="description_important">
 | 
						||
// После переноса в корзину карточке товара
 | 
						||
// присваивается новый <code>imtID</code>.
 | 
						||
// </div>
 | 
						||
// Карточки товаров удаляются автоматически, если лежат
 | 
						||
// в корзине больше 30 дней. Очистка корзины происходит
 | 
						||
// каждую ночь по московскому времени.<br>
 | 
						||
// Карточки товаров можно удалить в любое время в
 | 
						||
// [личном кабинете](https://seller.wildberries.ru/new-goods/basket-cards).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/cards/delete/trash
 | 
						||
func (s *Server) handleContentV2CardsDeleteTrashPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/delete/trash"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsDeleteTrashPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsDeleteTrashPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsDeleteTrashPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2CardsDeleteTrashPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2CardsDeleteTrashPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsDeleteTrashPostOperation,
 | 
						||
			OperationSummary: "Перенос карточек товаров в корзину",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2CardsDeleteTrashPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsDeleteTrashPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsDeleteTrashPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsDeleteTrashPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsDeleteTrashPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsErrorListGetRequest handles GET /content/v2/cards/error/list operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список карточек товаров, при
 | 
						||
// создании или редактировании которых произошли
 | 
						||
// ошибки, с описанием этих ошибок.
 | 
						||
// <div class="description_important">
 | 
						||
// Чтобы убрать карточку товара из списка, нужно
 | 
						||
// повторно сделать запрос на <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создание</a> или редактирование карточки товара с исправленными ошибками.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/cards/error/list
 | 
						||
func (s *Server) handleContentV2CardsErrorListGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/error/list"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsErrorListGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsErrorListGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsErrorListGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2CardsErrorListGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2CardsErrorListGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsErrorListGetOperation,
 | 
						||
			OperationSummary: "Список несозданных карточек товаров с ошибками",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2CardsErrorListGetParams
 | 
						||
			Response = ContentV2CardsErrorListGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2CardsErrorListGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsErrorListGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsErrorListGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsErrorListGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsLimitsGetRequest handles GET /content/v2/cards/limits operation.
 | 
						||
//
 | 
						||
// Возвращает бесплатные и платные лимиты продавца на
 | 
						||
// [создание карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post).<br><br>
 | 
						||
// Формула для получения количества карточек, которые
 | 
						||
// можно создать:
 | 
						||
// > (`freeLimits` + `paidLimits`) - количество созданных карточек
 | 
						||
// Созданными считаются карточки, которые можно
 | 
						||
// получить через методы [список карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/cards/limits
 | 
						||
func (s *Server) handleContentV2CardsLimitsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/limits"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsLimitsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsLimitsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsLimitsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2CardsLimitsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsLimitsGetOperation,
 | 
						||
			OperationSummary: "Лимиты карточек товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsLimitsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsLimitsGet(ctx)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsLimitsGet(ctx)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsLimitsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsRecoverPostRequest handles POST /content/v2/cards/recover operation.
 | 
						||
//
 | 
						||
// Метод восстанавливает [карточки товаров из
 | 
						||
// корзины](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
 | 
						||
// <div class="description_important">
 | 
						||
// Карточка товара сохраняет тот же <code>imtID</code>, что был
 | 
						||
// присвоен ей при <a
 | 
						||
// href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1delete~1trash/post">перемещении в корзину</a>.
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/cards/recover
 | 
						||
func (s *Server) handleContentV2CardsRecoverPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/recover"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsRecoverPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsRecoverPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsRecoverPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2CardsRecoverPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2CardsRecoverPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsRecoverPostOperation,
 | 
						||
			OperationSummary: "Восстановление карточек товаров из корзины",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2CardsRecoverPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsRecoverPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsRecoverPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsRecoverPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsRecoverPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsUpdatePostRequest handles POST /content/v2/cards/update operation.
 | 
						||
//
 | 
						||
// Метод обновляет карточки товаров. Данные для
 | 
						||
// обновления можно получить через [список карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post).
 | 
						||
// <div class="description_important">
 | 
						||
// Карточка товара перезаписывается при обновлении.
 | 
						||
// Поэтому в запросе нужно передать <strong>все</strong>
 | 
						||
// параметры карточки, в том числе те, которые вы не
 | 
						||
// собираетесь обновлять.
 | 
						||
// </div>
 | 
						||
// Нельзя редактировать или удалять баркоды, но можно
 | 
						||
// добавить дополнительный баркод к карточке товара.
 | 
						||
// Параметры `photos`, `video` и `tags` редактировать или удалять
 | 
						||
// через данный метод нельзя.<br>
 | 
						||
// Габариты товаров можно указать только в `сантиметрах`,
 | 
						||
//
 | 
						||
//	вес товара с упаковкой — в `килограммах`.
 | 
						||
//
 | 
						||
// <br><br>
 | 
						||
// В одном запросе можно отредактировать максимум 3000
 | 
						||
// карточек товаров (`nmID`). Максимальный размер запроса 10
 | 
						||
// Мб.<br>
 | 
						||
// Если ответ `Успешно` (`200`), но какие-то карточки не
 | 
						||
// обновились, получите [список несозданных карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня для метода будет отдельный
 | 
						||
// лимит — 10 запросов в минуту на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/cards/update
 | 
						||
func (s *Server) handleContentV2CardsUpdatePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/update"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUpdatePostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsUpdatePostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUpdatePostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2CardsUpdatePostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2CardsUpdatePostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsUpdatePostOperation,
 | 
						||
			OperationSummary: "Редактирование карточек товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = []ContentV2CardsUpdatePostReqItem
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsUpdatePostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsUpdatePost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsUpdatePost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsUpdatePostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsUploadAddPostRequest handles POST /content/v2/cards/upload/add operation.
 | 
						||
//
 | 
						||
// Метод создаёт новые карточки товаров, присоединяя их
 | 
						||
// к существующим карточкам.
 | 
						||
// Габариты товаров можно указать только в `сантиметрах`,
 | 
						||
//
 | 
						||
//	вес товара с упаковкой — в `килограммах`.
 | 
						||
//
 | 
						||
// <br><br>
 | 
						||
// Создание карточки товара происходит асинхронно.
 | 
						||
// После отправки запрос становится в очередь на
 | 
						||
// обработку.<br>Максимальный размер запроса 10 Мб.<br>
 | 
						||
// Если ответ `Успешно` (`200`), но какие-то карточки не
 | 
						||
// обновились, получите [список несозданных карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня для метода будет отдельный
 | 
						||
// лимит — 10 запросов в минуту на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/cards/upload/add
 | 
						||
func (s *Server) handleContentV2CardsUploadAddPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/upload/add"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUploadAddPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsUploadAddPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUploadAddPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2CardsUploadAddPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2CardsUploadAddPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsUploadAddPostOperation,
 | 
						||
			OperationSummary: "Создание карточек товаров с присоединением",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = OptContentV2CardsUploadAddPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsUploadAddPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsUploadAddPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsUploadAddPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsUploadAddPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2CardsUploadPostRequest handles POST /content/v2/cards/upload operation.
 | 
						||
//
 | 
						||
// Метод создаёт карточки товаров c указанием описаний и
 | 
						||
// характеристик товаров.<br>
 | 
						||
// <div class="description_important">
 | 
						||
// Есть две формы запроса: для создания отдельных и
 | 
						||
// объединённых карточек товаров.
 | 
						||
// </div>
 | 
						||
// Габариты товаров можно указать только в `сантиметрах`,
 | 
						||
//
 | 
						||
//	вес товара с упаковкой — в `килограммах`.
 | 
						||
//
 | 
						||
// <br><br>
 | 
						||
// Создание карточки товара происходит асинхронно.
 | 
						||
// После отправки запрос становится в очередь на
 | 
						||
// обработку.<br>
 | 
						||
// В одном запросе можно создать максимум 100
 | 
						||
// объединённых карточек товаров (`imtID`), по 30 карточек
 | 
						||
// товаров в каждой. Максимальный размер запроса 10 Мб.<br>
 | 
						||
// Если ответ `Успешно` (`200`), но какие-то карточки не
 | 
						||
// обновились, получите [список несозданных карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/get).
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня для метода будет отдельный
 | 
						||
// лимит — 10 запросов в минуту на один аккаунт продавца
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/cards/upload
 | 
						||
func (s *Server) handleContentV2CardsUploadPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/cards/upload"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2CardsUploadPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2CardsUploadPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2CardsUploadPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2CardsUploadPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2CardsUploadPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2CardsUploadPostOperation,
 | 
						||
			OperationSummary: "Создание карточек товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = []ContentV2CardsUploadPostReqItem
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2CardsUploadPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2CardsUploadPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2CardsUploadPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2CardsUploadPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectoryColorsGetRequest handles GET /content/v2/directory/colors operation.
 | 
						||
//
 | 
						||
// Метод предоставляет возможные значения
 | 
						||
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Цвет`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/colors
 | 
						||
func (s *Server) handleContentV2DirectoryColorsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/colors"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryColorsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectoryColorsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryColorsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectoryColorsGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectoryColorsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectoryColorsGetOperation,
 | 
						||
			OperationSummary: "Цвет",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectoryColorsGetParams
 | 
						||
			Response = ContentV2DirectoryColorsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectoryColorsGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectoryColorsGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectoryColorsGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectoryColorsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectoryCountriesGetRequest handles GET /content/v2/directory/countries operation.
 | 
						||
//
 | 
						||
// Метод предоставляет возможные значения
 | 
						||
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Страна производства`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/countries
 | 
						||
func (s *Server) handleContentV2DirectoryCountriesGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/countries"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryCountriesGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectoryCountriesGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryCountriesGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectoryCountriesGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectoryCountriesGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectoryCountriesGetOperation,
 | 
						||
			OperationSummary: "Страна производства",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectoryCountriesGetParams
 | 
						||
			Response = ContentV2DirectoryCountriesGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectoryCountriesGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectoryCountriesGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectoryCountriesGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectoryCountriesGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectoryKindsGetRequest handles GET /content/v2/directory/kinds operation.
 | 
						||
//
 | 
						||
// Метод предоставляет возможные значения
 | 
						||
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Пол`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/kinds
 | 
						||
func (s *Server) handleContentV2DirectoryKindsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/kinds"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryKindsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectoryKindsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryKindsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectoryKindsGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectoryKindsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectoryKindsGetOperation,
 | 
						||
			OperationSummary: "Пол",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectoryKindsGetParams
 | 
						||
			Response = ContentV2DirectoryKindsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectoryKindsGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectoryKindsGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectoryKindsGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectoryKindsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectorySeasonsGetRequest handles GET /content/v2/directory/seasons operation.
 | 
						||
//
 | 
						||
// Метод предоставляет возможные значения
 | 
						||
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Сезон`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/seasons
 | 
						||
func (s *Server) handleContentV2DirectorySeasonsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/seasons"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectorySeasonsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectorySeasonsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectorySeasonsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectorySeasonsGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectorySeasonsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectorySeasonsGetOperation,
 | 
						||
			OperationSummary: "Сезон",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectorySeasonsGetParams
 | 
						||
			Response = ContentV2DirectorySeasonsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectorySeasonsGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectorySeasonsGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectorySeasonsGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectorySeasonsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectoryTnvedGetRequest handles GET /content/v2/directory/tnved operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список ТНВЭД-кодов по ID
 | 
						||
// [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get) и фрагменту ТНВЭД-кода.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/tnved
 | 
						||
func (s *Server) handleContentV2DirectoryTnvedGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/tnved"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryTnvedGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectoryTnvedGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryTnvedGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectoryTnvedGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectoryTnvedGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectoryTnvedGetOperation,
 | 
						||
			OperationSummary: "ТНВЭД-код",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "subjectID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.SubjectID,
 | 
						||
				{
 | 
						||
					Name: "search",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Search,
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectoryTnvedGetParams
 | 
						||
			Response = ContentV2DirectoryTnvedGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectoryTnvedGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectoryTnvedGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectoryTnvedGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectoryTnvedGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2DirectoryVatGetRequest handles GET /content/v2/directory/vat operation.
 | 
						||
//
 | 
						||
// Метод предоставляет возможные значения
 | 
						||
// [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Ставка НДС`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/directory/vat
 | 
						||
func (s *Server) handleContentV2DirectoryVatGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/directory/vat"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2DirectoryVatGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2DirectoryVatGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2DirectoryVatGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2DirectoryVatGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2DirectoryVatGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2DirectoryVatGetOperation,
 | 
						||
			OperationSummary: "Ставка НДС",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2DirectoryVatGetParams
 | 
						||
			Response = ContentV2DirectoryVatGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2DirectoryVatGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2DirectoryVatGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2DirectoryVatGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2DirectoryVatGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2GetCardsListPostRequest handles POST /content/v2/get/cards/list operation.
 | 
						||
//
 | 
						||
// <div class="description_auth">
 | 
						||
// Метод доступен по <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">токену</a> с
 | 
						||
// категорией <strong>Контент</strong> или <strong>Продвижение</strong>
 | 
						||
// </div>
 | 
						||
// Метод предоставляет список созданных карточек
 | 
						||
// товаров.
 | 
						||
// <div class="description_important">
 | 
						||
// В ответе метода не будет карточек, находящихся в
 | 
						||
// корзине. Получить такие карточки можно через <a
 | 
						||
// href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post">отдельный метод</a>.
 | 
						||
// </div>
 | 
						||
// Чтобы получить **больше 100** карточек товаров,
 | 
						||
// воспользуйтесь пагинацией:
 | 
						||
// <ol>
 | 
						||
// <li>Сделайте первый запрос: <br>
 | 
						||
// <pre style="background-color: rgb(38 50 56 / 5%); color: #e53935">
 | 
						||
// {
 | 
						||
// "settings": {
 | 
						||
// "cursor": {
 | 
						||
// "limit": 100
 | 
						||
// },
 | 
						||
// "filter": {
 | 
						||
// "withPhoto": -1
 | 
						||
// }
 | 
						||
// }
 | 
						||
// }</pre>
 | 
						||
// </li>
 | 
						||
// <li>Пройдите в конец полученного списка карточек
 | 
						||
// товаров.</li>
 | 
						||
// <li>Скопируйте из <code>cursor</code> две строки:
 | 
						||
// <ul>
 | 
						||
// <li><code>"updatedAt": "***"</code></li>
 | 
						||
// <li><code>"nmID": ***</code></li>
 | 
						||
// </ul></li>
 | 
						||
// <li>Вставьте скопированные строки в параметр запроса
 | 
						||
// <code>cursor</code>.</li>
 | 
						||
// <li>Повторите запрос. </li>
 | 
						||
// <li>Повторяйте пункты со <b>2</b> по <b>5</b>, пока поле
 | 
						||
// <code>total</code> в ответе не станет меньше чем параметр
 | 
						||
// <code>limit</code> в запросе. Это будет означать, что вы
 | 
						||
// получили все карточки.
 | 
						||
// </ol>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/get/cards/list
 | 
						||
func (s *Server) handleContentV2GetCardsListPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/get/cards/list"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2GetCardsListPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2GetCardsListPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2GetCardsListPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2GetCardsListPostParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2GetCardsListPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2GetCardsListPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2GetCardsListPostOperation,
 | 
						||
			OperationSummary: "Список карточек товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2GetCardsListPostReq
 | 
						||
			Params   = ContentV2GetCardsListPostParams
 | 
						||
			Response = ContentV2GetCardsListPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2GetCardsListPostParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2GetCardsListPost(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2GetCardsListPost(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2GetCardsListPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2GetCardsTrashPostRequest handles POST /content/v2/get/cards/trash operation.
 | 
						||
//
 | 
						||
// <div class="description_auth">
 | 
						||
// Метод доступен по <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">токену</a> с
 | 
						||
// категорией <strong>Контент</strong> или <strong>Продвижение</strong>
 | 
						||
// </div>
 | 
						||
// Метод предоставляет список карточек товаров в
 | 
						||
// корзине.<br><br>
 | 
						||
// Чтобы получить **больше 100** карточек товаров,
 | 
						||
// воспользуйтесь пагинацией:
 | 
						||
// <ol>
 | 
						||
// <li>Сделайте первый запрос: <br>
 | 
						||
// <pre style="background-color: rgb(38 50 56 / 5%); color: #e53935">
 | 
						||
// {
 | 
						||
// "settings": {
 | 
						||
// "cursor": {
 | 
						||
// "limit": 100
 | 
						||
// },
 | 
						||
// "filter": {
 | 
						||
// "withPhoto": -1
 | 
						||
// }
 | 
						||
// }
 | 
						||
// }</pre>
 | 
						||
// </li>
 | 
						||
// <li>Пройдите в конец полученного списка карточек
 | 
						||
// товаров.</li>
 | 
						||
// <li>Скопируйте из <code>cursor</code> две строки:
 | 
						||
// <ul>
 | 
						||
// <li><code>"trashedAt": "***"</code></li>
 | 
						||
// <li><code>"nmID": ***</code></li>
 | 
						||
// </ul></li>
 | 
						||
// <li>Вставьте скопированные строки в параметр запроса
 | 
						||
// <code>cursor</code>.</li>
 | 
						||
// <li>Повторите запрос. </li>
 | 
						||
// <li>Повторяйте пункты со <b>2</b> по <b>5</b>, пока поле
 | 
						||
// <code>total</code> в ответе не станет меньше чем параметр
 | 
						||
// <code>limit</code> в запросе. Это будет означать, что вы
 | 
						||
// получили все карточки.
 | 
						||
// </ol>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/get/cards/trash
 | 
						||
func (s *Server) handleContentV2GetCardsTrashPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/get/cards/trash"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2GetCardsTrashPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2GetCardsTrashPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2GetCardsTrashPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2GetCardsTrashPostParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2GetCardsTrashPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2GetCardsTrashPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2GetCardsTrashPostOperation,
 | 
						||
			OperationSummary: "Список карточек товаров в корзине",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2GetCardsTrashPostReq
 | 
						||
			Params   = ContentV2GetCardsTrashPostParams
 | 
						||
			Response = ContentV2GetCardsTrashPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2GetCardsTrashPostParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2GetCardsTrashPost(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2GetCardsTrashPost(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2GetCardsTrashPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2ObjectAllGetRequest handles GET /content/v2/object/all operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список названий [родительских
 | 
						||
// категорий
 | 
						||
// предметов](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1parent~1all/get) и их предметов с ID. Например, у категории `Игрушки` будут предметы `Калейдоскопы`, `Куклы`, `Мячики`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/object/all
 | 
						||
func (s *Server) handleContentV2ObjectAllGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/object/all"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectAllGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2ObjectAllGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectAllGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2ObjectAllGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2ObjectAllGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2ObjectAllGetOperation,
 | 
						||
			OperationSummary: "Список предметов",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
				{
 | 
						||
					Name: "name",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Name,
 | 
						||
				{
 | 
						||
					Name: "limit",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Limit,
 | 
						||
				{
 | 
						||
					Name: "offset",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Offset,
 | 
						||
				{
 | 
						||
					Name: "parentID",
 | 
						||
					In:   "query",
 | 
						||
				}: params.ParentID,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2ObjectAllGetParams
 | 
						||
			Response = ContentV2ObjectAllGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2ObjectAllGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2ObjectAllGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2ObjectAllGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2ObjectAllGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2ObjectCharcsSubjectIdGetRequest handles GET /content/v2/object/charcs/{subjectId} operation.
 | 
						||
//
 | 
						||
// Метод предоставляет параметры характеристик
 | 
						||
// предмета: названия, типы данных, единицы измерения и
 | 
						||
// так далее. В запросе необходимо указать ID
 | 
						||
// [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get).
 | 
						||
// <div class="description_important">
 | 
						||
// Для получения характеристик <a
 | 
						||
// href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1colors/get">Цвет</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1kinds/get">Пол</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1countries/get">Страна производства</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1seasons/get">Сезон</a>, <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1vat/get">Ставка НДС</a> и <a href="/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1tnved/get">ТНВЭД-код</a> используйте отдельные методы
 | 
						||
// </div>
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/object/charcs/{subjectId}
 | 
						||
func (s *Server) handleContentV2ObjectCharcsSubjectIdGetRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/object/charcs/{subjectId}"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectCharcsSubjectIdGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2ObjectCharcsSubjectIdGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectCharcsSubjectIdGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2ObjectCharcsSubjectIdGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2ObjectCharcsSubjectIdGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2ObjectCharcsSubjectIdGetOperation,
 | 
						||
			OperationSummary: "Характеристики предмета",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "subjectId",
 | 
						||
					In:   "path",
 | 
						||
				}: params.SubjectId,
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2ObjectCharcsSubjectIdGetParams
 | 
						||
			Response = ContentV2ObjectCharcsSubjectIdGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2ObjectCharcsSubjectIdGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2ObjectCharcsSubjectIdGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2ObjectCharcsSubjectIdGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2ObjectCharcsSubjectIdGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2ObjectParentAllGetRequest handles GET /content/v2/object/parent/all operation.
 | 
						||
//
 | 
						||
// Метод предоставляет названия и ID всех родительских
 | 
						||
// категорий для [создания карточек
 | 
						||
// товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov): например,
 | 
						||
// `Электроника`, `Бытовая химия`, `Рукоделие`.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/object/parent/all
 | 
						||
func (s *Server) handleContentV2ObjectParentAllGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/object/parent/all"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2ObjectParentAllGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2ObjectParentAllGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2ObjectParentAllGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV2ObjectParentAllGetParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2ObjectParentAllGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2ObjectParentAllGetOperation,
 | 
						||
			OperationSummary: "Родительские категории товаров",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "locale",
 | 
						||
					In:   "query",
 | 
						||
				}: params.Locale,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = ContentV2ObjectParentAllGetParams
 | 
						||
			Response = ContentV2ObjectParentAllGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV2ObjectParentAllGetParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2ObjectParentAllGet(ctx, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2ObjectParentAllGet(ctx, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2ObjectParentAllGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2TagNomenclatureLinkPostRequest handles POST /content/v2/tag/nomenclature/link operation.
 | 
						||
//
 | 
						||
// Метод добавляет или снимает ярлык с карточки товара.
 | 
						||
// К карточке можно добавить максимум 15 ярлыков.<br>
 | 
						||
// При удалении ярлыка из карточки товара он не
 | 
						||
// удаляется из [списка
 | 
						||
// ярлыков](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get)
 | 
						||
// продавца.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v2/tag/nomenclature/link
 | 
						||
func (s *Server) handleContentV2TagNomenclatureLinkPostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/tag/nomenclature/link"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2TagNomenclatureLinkPostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2TagNomenclatureLinkPostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2TagNomenclatureLinkPostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV2TagNomenclatureLinkPostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV2TagNomenclatureLinkPostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2TagNomenclatureLinkPostOperation,
 | 
						||
			OperationSummary: "Управление ярлыками в карточке товара",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV2TagNomenclatureLinkPostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2TagNomenclatureLinkPostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2TagNomenclatureLinkPost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2TagNomenclatureLinkPost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2TagNomenclatureLinkPostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV2TagsGetRequest handles GET /content/v2/tags operation.
 | 
						||
//
 | 
						||
// Метод предоставляет список и характеристики всех
 | 
						||
// ярлыков продавца для группировки и фильтрации
 | 
						||
// товаров.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// GET /content/v2/tags
 | 
						||
func (s *Server) handleContentV2TagsGetRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("GET"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v2/tags"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV2TagsGetOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV2TagsGetOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV2TagsGetOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	var response ContentV2TagsGetRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV2TagsGetOperation,
 | 
						||
			OperationSummary: "Список ярлыков",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             nil,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = struct{}
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV2TagsGetRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV2TagsGet(ctx)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV2TagsGet(ctx)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV2TagsGetResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV3MediaFilePostRequest handles POST /content/v3/media/file operation.
 | 
						||
//
 | 
						||
// Метод загружает и добавляет один медиафайл к
 | 
						||
// карточке товара.
 | 
						||
// Требования к изображениям:
 | 
						||
// * максимум изображений для одной карточки товара — 30
 | 
						||
// * минимальное разрешение — 700x900 px
 | 
						||
// * максимальный размер — 32 Мб
 | 
						||
// * минимальное качество — 65%
 | 
						||
// * форматы — JPG, PNG, BMP, GIF (статичные), WebP
 | 
						||
// Требования к видео:
 | 
						||
// * максимум одно видео для одной карточки товара
 | 
						||
// * максимальный размер — 50 Мб
 | 
						||
// * форматы — MOV, MP4
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v3/media/file
 | 
						||
func (s *Server) handleContentV3MediaFilePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v3/media/file"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV3MediaFilePostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV3MediaFilePostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV3MediaFilePostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	params, err := decodeContentV3MediaFilePostParams(args, argsEscaped, r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeParamsError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeParams", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV3MediaFilePostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV3MediaFilePostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV3MediaFilePostOperation,
 | 
						||
			OperationSummary: "Загрузить медиафайл",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params: middleware.Parameters{
 | 
						||
				{
 | 
						||
					Name: "X-Nm-Id",
 | 
						||
					In:   "header",
 | 
						||
				}: params.XNmID,
 | 
						||
				{
 | 
						||
					Name: "X-Photo-Number",
 | 
						||
					In:   "header",
 | 
						||
				}: params.XPhotoNumber,
 | 
						||
			},
 | 
						||
			Raw: r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV3MediaFilePostReq
 | 
						||
			Params   = ContentV3MediaFilePostParams
 | 
						||
			Response = ContentV3MediaFilePostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			unpackContentV3MediaFilePostParams,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV3MediaFilePost(ctx, request, params)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV3MediaFilePost(ctx, request, params)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV3MediaFilePostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// handleContentV3MediaSavePostRequest handles POST /content/v3/media/save operation.
 | 
						||
//
 | 
						||
// Метод загружает набор медиафайлов в карточку товара
 | 
						||
// через указание ссылок в запросе.
 | 
						||
// <div class="description_important">
 | 
						||
// Новые медиафайлы полностью заменяют старые. Чтобы
 | 
						||
// добавить новые медиафайлы, укажите в запросе ссылки
 | 
						||
// одновременно на новые и старые медиафайлы.
 | 
						||
// </div>
 | 
						||
// Требования к изображениям:
 | 
						||
// * максимум изображений для одной карточки товара — 30
 | 
						||
// * минимальное разрешение — 700×900 px
 | 
						||
// * максимальный размер — 32 Мб
 | 
						||
// * минимальное качество — 65%
 | 
						||
// * форматы — JPG, PNG, BMP, GIF (статичные), WebP
 | 
						||
// Требования к видео:
 | 
						||
// * максимум одно видео для одной карточки товара
 | 
						||
// * максимальный размер — 50 Мб
 | 
						||
// * форматы — MOV, MP4
 | 
						||
// Если видео или хотя бы одно изображение в запросе не
 | 
						||
// соответствует требованиям, то даже при успешном
 | 
						||
// ответе ни одно изображение/видео не загрузится.
 | 
						||
// <div class="description_limit">
 | 
						||
// Максимум 100 запросов в <a
 | 
						||
// href="/openapi/api-information#tag/Vvedenie/Limity-zaprosov">минуту</a> для всех
 | 
						||
// методов категории <a
 | 
						||
// href="/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token">Контент</a> на один
 | 
						||
// аккаунт продавца. С 5 июня — за исключением методов <a
 | 
						||
// href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post">создания</a>, <a href="/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post">создания с присоединением</a> и <a href="/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post">редактирования</a> карточек товаров
 | 
						||
// </div>.
 | 
						||
//
 | 
						||
// POST /content/v3/media/save
 | 
						||
func (s *Server) handleContentV3MediaSavePostRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
 | 
						||
	statusWriter := &codeRecorder{ResponseWriter: w}
 | 
						||
	w = statusWriter
 | 
						||
	otelAttrs := []attribute.KeyValue{
 | 
						||
		semconv.HTTPRequestMethodKey.String("POST"),
 | 
						||
		semconv.HTTPRouteKey.String("/content/v3/media/save"),
 | 
						||
	}
 | 
						||
 | 
						||
	// Start a span for this request.
 | 
						||
	ctx, span := s.cfg.Tracer.Start(r.Context(), ContentV3MediaSavePostOperation,
 | 
						||
		trace.WithAttributes(otelAttrs...),
 | 
						||
		serverSpanKind,
 | 
						||
	)
 | 
						||
	defer span.End()
 | 
						||
 | 
						||
	// Add Labeler to context.
 | 
						||
	labeler := &Labeler{attrs: otelAttrs}
 | 
						||
	ctx = contextWithLabeler(ctx, labeler)
 | 
						||
 | 
						||
	// Run stopwatch.
 | 
						||
	startTime := time.Now()
 | 
						||
	defer func() {
 | 
						||
		elapsedDuration := time.Since(startTime)
 | 
						||
 | 
						||
		attrSet := labeler.AttributeSet()
 | 
						||
		attrs := attrSet.ToSlice()
 | 
						||
		code := statusWriter.status
 | 
						||
		if code != 0 {
 | 
						||
			codeAttr := semconv.HTTPResponseStatusCode(code)
 | 
						||
			attrs = append(attrs, codeAttr)
 | 
						||
			span.SetAttributes(codeAttr)
 | 
						||
		}
 | 
						||
		attrOpt := metric.WithAttributes(attrs...)
 | 
						||
 | 
						||
		// Increment request counter.
 | 
						||
		s.requests.Add(ctx, 1, attrOpt)
 | 
						||
 | 
						||
		// Use floating point division here for higher precision (instead of Millisecond method).
 | 
						||
		s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
 | 
						||
	}()
 | 
						||
 | 
						||
	var (
 | 
						||
		recordError = func(stage string, err error) {
 | 
						||
			span.RecordError(err)
 | 
						||
 | 
						||
			// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
 | 
						||
			// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
 | 
						||
			// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
 | 
						||
			// max redirects exceeded), in which case status MUST be set to Error.
 | 
						||
			code := statusWriter.status
 | 
						||
			if code >= 100 && code < 500 {
 | 
						||
				span.SetStatus(codes.Error, stage)
 | 
						||
			}
 | 
						||
 | 
						||
			attrSet := labeler.AttributeSet()
 | 
						||
			attrs := attrSet.ToSlice()
 | 
						||
			if code != 0 {
 | 
						||
				attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
 | 
						||
			}
 | 
						||
 | 
						||
			s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
 | 
						||
		}
 | 
						||
		err          error
 | 
						||
		opErrContext = ogenerrors.OperationContext{
 | 
						||
			Name: ContentV3MediaSavePostOperation,
 | 
						||
			ID:   "",
 | 
						||
		}
 | 
						||
	)
 | 
						||
	{
 | 
						||
		type bitset = [1]uint8
 | 
						||
		var satisfied bitset
 | 
						||
		{
 | 
						||
			sctx, ok, err := s.securityHeaderApiKey(ctx, ContentV3MediaSavePostOperation, r)
 | 
						||
			if err != nil {
 | 
						||
				err = &ogenerrors.SecurityError{
 | 
						||
					OperationContext: opErrContext,
 | 
						||
					Security:         "HeaderApiKey",
 | 
						||
					Err:              err,
 | 
						||
				}
 | 
						||
				defer recordError("Security:HeaderApiKey", err)
 | 
						||
				s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
				return
 | 
						||
			}
 | 
						||
			if ok {
 | 
						||
				satisfied[0] |= 1 << 0
 | 
						||
				ctx = sctx
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		if ok := func() bool {
 | 
						||
		nextRequirement:
 | 
						||
			for _, requirement := range []bitset{
 | 
						||
				{0b00000001},
 | 
						||
			} {
 | 
						||
				for i, mask := range requirement {
 | 
						||
					if satisfied[i]&mask != mask {
 | 
						||
						continue nextRequirement
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true
 | 
						||
			}
 | 
						||
			return false
 | 
						||
		}(); !ok {
 | 
						||
			err = &ogenerrors.SecurityError{
 | 
						||
				OperationContext: opErrContext,
 | 
						||
				Err:              ogenerrors.ErrSecurityRequirementIsNotSatisfied,
 | 
						||
			}
 | 
						||
			defer recordError("Security", err)
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
			return
 | 
						||
		}
 | 
						||
	}
 | 
						||
	request, close, err := s.decodeContentV3MediaSavePostRequest(r)
 | 
						||
	if err != nil {
 | 
						||
		err = &ogenerrors.DecodeRequestError{
 | 
						||
			OperationContext: opErrContext,
 | 
						||
			Err:              err,
 | 
						||
		}
 | 
						||
		defer recordError("DecodeRequest", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
	defer func() {
 | 
						||
		if err := close(); err != nil {
 | 
						||
			recordError("CloseRequest", err)
 | 
						||
		}
 | 
						||
	}()
 | 
						||
 | 
						||
	var response ContentV3MediaSavePostRes
 | 
						||
	if m := s.cfg.Middleware; m != nil {
 | 
						||
		mreq := middleware.Request{
 | 
						||
			Context:          ctx,
 | 
						||
			OperationName:    ContentV3MediaSavePostOperation,
 | 
						||
			OperationSummary: "Загрузить медиафайлы по ссылкам",
 | 
						||
			OperationID:      "",
 | 
						||
			Body:             request,
 | 
						||
			Params:           middleware.Parameters{},
 | 
						||
			Raw:              r,
 | 
						||
		}
 | 
						||
 | 
						||
		type (
 | 
						||
			Request  = *ContentV3MediaSavePostReq
 | 
						||
			Params   = struct{}
 | 
						||
			Response = ContentV3MediaSavePostRes
 | 
						||
		)
 | 
						||
		response, err = middleware.HookMiddleware[
 | 
						||
			Request,
 | 
						||
			Params,
 | 
						||
			Response,
 | 
						||
		](
 | 
						||
			m,
 | 
						||
			mreq,
 | 
						||
			nil,
 | 
						||
			func(ctx context.Context, request Request, params Params) (response Response, err error) {
 | 
						||
				response, err = s.h.ContentV3MediaSavePost(ctx, request)
 | 
						||
				return response, err
 | 
						||
			},
 | 
						||
		)
 | 
						||
	} else {
 | 
						||
		response, err = s.h.ContentV3MediaSavePost(ctx, request)
 | 
						||
	}
 | 
						||
	if err != nil {
 | 
						||
		defer recordError("Internal", err)
 | 
						||
		s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		return
 | 
						||
	}
 | 
						||
 | 
						||
	if err := encodeContentV3MediaSavePostResponse(response, w, span); err != nil {
 | 
						||
		defer recordError("EncodeResponse", err)
 | 
						||
		if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
 | 
						||
			s.cfg.ErrorHandler(ctx, w, r, err)
 | 
						||
		}
 | 
						||
		return
 | 
						||
	}
 | 
						||
}
 |