{"openapi":"3.1.0","info":{"title":"Scanderm Product Backend - Sber","description":"Полный backend-only стек Scanderm для проекта Sber: пользователи, анализ кожи, визуализации, результаты, рекомендации, каталог, магазины и импорт.\n\n### Авторизация\n1. Во все API-запросы передавайте `X-API-Key`.\n2. Получите пользовательский JWT через `/auth/guest`, `/auth/register` или `/auth/login`.\n3. Для методов с замком дополнительно передавайте `Authorization: Bearer <access_token>`.\n4. Для каталога и очереди импорта используйте admin JWT либо `X-Internal-Key` вместе с `X-API-Key`.\n\n`/health`, `/docs`, `/swagger` и `/openapi.json` доступны без ключа.","version":"1.0.0"},"paths":{"/auth/register":{"post":{"tags":["auth"],"summary":"Register","operationId":"register_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/auth/guest":{"post":{"tags":["auth"],"summary":"Guest","description":"Create anonymous guest user and return tokens.","operationId":"guest_auth_guest_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}}},"security":[{"ProjectApiKey":[]}]}},"/me":{"put":{"tags":["profile"],"summary":"Update Profile","operationId":"update_profile_me_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/products":{"get":{"tags":["products"],"summary":"List Products","operationId":"list_products_products_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"module","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Module"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]},"post":{"tags":["products"],"summary":"Create Product","operationId":"create_product_products_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/products/{product_id}":{"get":{"tags":["products"],"summary":"Get Product","operationId":"get_product_products__product_id__get","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]},"put":{"tags":["products"],"summary":"Update Product","operationId":"update_product_products__product_id__put","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["products"],"summary":"Delete Product","operationId":"delete_product_products__product_id__delete","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string","title":"Product Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/products/import-csv":{"post":{"tags":["products"],"summary":"Import Csv","description":"Import products from a CSV file (UTF-8, semicolon-separated list values).","operationId":"import_csv_products_import_csv_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_csv_products_import_csv_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}]}},"/products/import-excel":{"post":{"tags":["products"],"summary":"Import Excel","description":"Import products from Excel (.xlsx).\nSame column format as CSV. List values separated by semicolons.\nReturns detailed error report.","operationId":"import_excel_products_import_excel_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_excel_products_import_excel_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}]}},"/analysis/upload":{"post":{"tags":["analysis"],"summary":"Upload For Analysis","operationId":"upload_for_analysis_analysis_upload_post","security":[{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"module","in":"query","required":true,"schema":{"type":"string","description":"Analysis module: face, skin, nails, lips","title":"Module"},"description":"Analysis module: face, skin, nails, lips"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_for_analysis_analysis_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analysis/stream/{session_id}":{"get":{"tags":["analysis"],"summary":"Stream a prepared user analysis (SSE)","description":"Connect after POST /analysis/upload and receive progressive results for that session. Requires X-API-Key plus the user JWT in Authorization or the token query parameter. For a one-request photo stream without JWT use POST /neural/analyze/stream.","operationId":"stream_analysis_analysis_stream__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}}],"responses":{"200":{"description":"Server-Sent Events stream","content":{"text/event-stream":{"schema":{"type":"string"},"example":"data: {\"task_id\":\"redness\",\"status\":\"done\",\"affected_percent\":12.4}\\n\\ndata: {\"type\":\"complete\",\"session_id\":\"...\"}\\n\\n"}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/settings/field-config":{"get":{"tags":["settings"],"summary":"Get Field Config","description":"Get field config. If product_type_id given, return per-type config.","operationId":"get_field_config_settings_field_config_get","parameters":[{"name":"product_type_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Type Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Field Config Settings Field Config Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]},"put":{"tags":["settings"],"summary":"Put Field Config","operationId":"put_field_config_settings_field_config_put","security":[{"ProjectApiKey":[],"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Put Field Config Settings Field Config Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/settings/stock-integration":{"get":{"tags":["settings"],"summary":"Get Stock Integration","operationId":"get_stock_integration_settings_stock_integration_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Stock Integration Settings Stock Integration Get"}}}}},"security":[{"ProjectApiKey":[]}]},"put":{"tags":["settings"],"summary":"Put Stock Integration","operationId":"put_stock_integration_settings_stock_integration_put","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Put Stock Integration Settings Stock Integration Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/settings/product-types":{"get":{"tags":["settings"],"summary":"Get Product Types","operationId":"get_product_types_settings_product_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{},"type":"array","title":"Response Get Product Types Settings Product Types Get"}}}}},"security":[{"ProjectApiKey":[]}]},"put":{"tags":["settings"],"summary":"Put Product Types","operationId":"put_product_types_settings_product_types_put","requestBody":{"content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{},"type":"array","title":"Response Put Product Types Settings Product Types Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/shops":{"get":{"tags":["shops"],"summary":"List Shops","operationId":"list_shops_shops_get","parameters":[{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/shops/nearest":{"get":{"tags":["shops"],"summary":"Nearest Shop","operationId":"nearest_shop_shops_nearest_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","title":"Lat"}},{"name":"lng","in":"query","required":true,"schema":{"type":"number","title":"Lng"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/shops/{code}":{"get":{"tags":["shops"],"summary":"Get Shop","operationId":"get_shop_shops__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/import-queue/upload-excel":{"post":{"tags":["import-queue"],"summary":"Upload Excel","operationId":"upload_excel_import_queue_upload_excel_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"product_type_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Type Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_excel_import_queue_upload_excel_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/upload-csv":{"post":{"tags":["import-queue"],"summary":"Upload Csv","operationId":"upload_csv_import_queue_upload_csv_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"product_type_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Type Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_csv_import_queue_upload_csv_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions":{"get":{"tags":["import-queue"],"summary":"List Sessions","operationId":"list_sessions_import_queue_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}]}},"/import-queue/sessions/{session_id}":{"get":{"tags":["import-queue"],"summary":"Get Session","operationId":"get_session_import_queue_sessions__session_id__get","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["import-queue"],"summary":"Cancel Session","operationId":"cancel_session_import_queue_sessions__session_id__delete","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/items":{"get":{"tags":["import-queue"],"summary":"Get Items","operationId":"get_items_import_queue_sessions__session_id__items_get","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/items/{item_id}":{"put":{"tags":["import-queue"],"summary":"Update Item","operationId":"update_item_import_queue_items__item_id__put","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemUpdateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/approve":{"post":{"tags":["import-queue"],"summary":"Approve Items","operationId":"approve_items_import_queue_sessions__session_id__approve_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchActionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/reject":{"post":{"tags":["import-queue"],"summary":"Reject Items","operationId":"reject_items_import_queue_sessions__session_id__reject_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchActionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/reject-all-error":{"post":{"tags":["import-queue"],"summary":"Reject All Error","operationId":"reject_all_error_import_queue_sessions__session_id__reject_all_error_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/approve-all-valid":{"post":{"tags":["import-queue"],"summary":"Approve All Valid","operationId":"approve_all_valid_import_queue_sessions__session_id__approve_all_valid_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/commit":{"post":{"tags":["import-queue"],"summary":"Commit Approved","operationId":"commit_approved_import_queue_sessions__session_id__commit_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/upload-images":{"post":{"tags":["import-queue"],"summary":"Upload Images Zip","description":"Upload ZIP archive with images named by SKU (e.g. 1000559960.jpg).","operationId":"upload_images_zip_import_queue_sessions__session_id__upload_images_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_images_zip_import_queue_sessions__session_id__upload_images_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import-queue/sessions/{session_id}/enrich":{"post":{"tags":["import-queue"],"summary":"Enrich Session","operationId":"enrich_session_import_queue_sessions__session_id__enrich_post","security":[{"ProjectApiKey":[],"AdminApiKey":[]},{"ProjectApiKey":[],"BearerAuth":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/recommendations":{"post":{"tags":["recommendations"],"summary":"Get Recommendations","operationId":"get_recommendations_recommendations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/care-flow":{"get":{"tags":["care-flow"],"summary":"Get Care Flow","description":"Возвращает упорядоченные этапы ухода для текущего проекта.","operationId":"get_care_flow_care_flow_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results":{"post":{"tags":["face-results"],"summary":"Create Face Result","operationId":"create_face_result_face_results_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaceResultIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[],"BearerAuth":[]}]}},"/face-results/{result_id}/qr-shown":{"post":{"tags":["face-results"],"summary":"Mark Qr Shown","description":"Киоск показал QR «Забрать результат» — фиксируем время первого\nпоказа и счётчик для витринной аналитики (monitor, store_tests).","operationId":"mark_qr_shown_face_results__result_id__qr_shown_post","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/landing-visit":{"post":{"tags":["face-results"],"summary":"Mark Landing Visit","description":"Лендинг результата открыли на устройстве юзера (переход по QR или\nссылке «Открыть в браузере»). PDF-рендерер (?pdf=1) сюда не шлёт.","operationId":"mark_landing_visit_face_results__result_id__landing_visit_post","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}":{"get":{"tags":["face-results"],"summary":"Get Face Result","operationId":"get_face_result_face_results__result_id__get","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FaceResultOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/pdf/prewarm":{"post":{"tags":["face-results"],"summary":"Prewarm Face Result Pdf","description":"Фоновый прогрев PDF: фронт дёргает, пока юзер смотрит рекомендации,\nчтобы «Скачать PDF-отчёт» отдал файл из кэша мгновенно.","operationId":"prewarm_face_result_pdf_face_results__result_id__pdf_prewarm_post","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/pdf":{"get":{"tags":["face-results"],"summary":"Get Face Result Pdf","description":"PDF-отчёт по результату: серверный рендер QR-лендинга\n/face/landing/<id>?pdf=1 через headless-chromium рендерер\n(browserless /pdf). Без авторизации — как GET результата.\nОтдаёт из кэша, если прогрет; иначе присоединяется к летящему\nрендеру или запускает свой.","operationId":"get_face_result_pdf_face_results__result_id__pdf_get","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/saved-products":{"patch":{"tags":["face-results"],"summary":"Update Saved Products","description":"Перезаписывает saved_products у результата. Без авторизации,\nкак и GET — публичный share-лендинг это переживёт.","operationId":"update_saved_products_face_results__result_id__saved_products_patch","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedProductsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/recs":{"patch":{"tags":["face-results"],"summary":"Update Recs","description":"Перезаписывает recs у результата отфильтрованным списком.\nБез авторизации, как и saved-products — публичный share-лендинг.","operationId":"update_recs_face_results__result_id__recs_patch","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-results/{result_id}/detailed-llm":{"post":{"tags":["face-results"],"summary":"Start Or Get Detailed Llm","operationId":"start_or_get_detailed_llm_face_results__result_id__detailed_llm_post","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]},"get":{"tags":["face-results"],"summary":"Get Detailed Llm","operationId":"get_detailed_llm_face_results__result_id__detailed_llm_get","parameters":[{"name":"result_id","in":"path","required":true,"schema":{"type":"string","title":"Result Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/face-config/filters":{"get":{"tags":["face-config"],"summary":"Get Filter Config","description":"Объединённая конфига фильтров для UI.","operationId":"get_filter_config_face_config_filters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"ProjectApiKey":[]}]}},"/image-proxy":{"get":{"tags":["image-proxy"],"summary":"Proxy Image","operationId":"proxy_image_image_proxy_get","parameters":[{"name":"u","in":"query","required":true,"schema":{"type":"string","description":"Полный URL картинки","title":"U"},"description":"Полный URL картинки"},{"name":"w","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2048,"minimum":16},{"type":"null"}],"description":"Целевая ширина, px (даунскейл)","title":"W"},"description":"Целевая ширина, px (даунскейл)"},{"name":"q","in":"query","required":false,"schema":{"type":"integer","maximum":95,"minimum":30,"description":"Качество webp при ресайзе","default":75,"title":"Q"},"description":"Качество webp при ресайзе"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/loyalty-card":{"post":{"tags":["loyalty"],"summary":"Save Loyalty Card","operationId":"save_loyalty_card_loyalty_card_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoyaltyCardIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Save Loyalty Card Loyalty Card Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/neural/analyze":{"post":{"tags":["neural"],"summary":"Analyze a photo directly (REST)","description":"Send one JPEG, PNG or WebP image and wait for the complete neural-network result. No guest account, JWT, session preparation or result persistence is required. The project X-API-Key is still required.","operationId":"direct_analyze_neural_analyze_post","parameters":[{"name":"module","in":"query","required":false,"schema":{"type":"string","description":"Enabled analysis module","default":"face","title":"Module"},"description":"Enabled analysis module"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_direct_analyze_neural_analyze_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectAnalysisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/neural/analyze/stream":{"post":{"tags":["neural"],"summary":"Analyze a photo directly (SSE)","description":"Send one image and receive SSE events in the same HTTP response. Events: session, progress, complete, result, done or error. Use a streaming POST client such as curl -N or fetch().","operationId":"direct_analyze_stream_neural_analyze_stream_post","parameters":[{"name":"module","in":"query","required":false,"schema":{"type":"string","description":"Enabled analysis module","default":"face","title":"Module"},"description":"Enabled analysis module"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_direct_analyze_stream_neural_analyze_stream_post"}}}},"responses":{"200":{"description":"Server-Sent Events stream","content":{"text/event-stream":{"schema":{"type":"string"},"example":"event: session\\ndata: {\"session_id\":\"...\"}\\n\\nevent: progress\\ndata: {\"task_id\":\"redness\",\"status\":\"done\"}\\n\\nevent: result\\ndata: {\"status\":\"done\",\"results\":{}}\\n\\nevent: done\\ndata: {\"session_id\":\"...\"}\\n\\n"}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ProjectApiKey":[]}]}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[]}}},"components":{"schemas":{"AnalysisResultOut":{"properties":{"id":{"type":"string","title":"Id"},"session_id":{"type":"string","title":"Session Id"},"model_type":{"type":"string","title":"Model Type"},"visualization_type":{"type":"string","title":"Visualization Type"},"result":{"additionalProperties":true,"type":"object","title":"Result"},"image_url":{"type":"string","title":"Image Url"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","session_id","model_type","visualization_type","result","image_url","created_at"],"title":"AnalysisResultOut"},"AnalysisUploadResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"s3_key":{"type":"string","title":"S3 Key"},"status":{"type":"string","title":"Status","default":"done"},"cropped_face_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cropped Face Url"},"results":{"additionalProperties":true,"type":"object","title":"Results","default":{}}},"type":"object","required":["session_id","s3_key"],"title":"AnalysisUploadResponse"},"BatchActionBody":{"properties":{"item_ids":{"items":{"type":"string"},"type":"array","title":"Item Ids"}},"type":"object","required":["item_ids"],"title":"BatchActionBody"},"Body_direct_analyze_neural_analyze_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Photo to analyze"}},"type":"object","required":["file"],"title":"Body_direct_analyze_neural_analyze_post"},"Body_direct_analyze_stream_neural_analyze_stream_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Photo to analyze"}},"type":"object","required":["file"],"title":"Body_direct_analyze_stream_neural_analyze_stream_post"},"Body_import_csv_products_import_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_csv_products_import_csv_post"},"Body_import_excel_products_import_excel_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_excel_products_import_excel_post"},"Body_upload_csv_import_queue_upload_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_csv_import_queue_upload_csv_post"},"Body_upload_excel_import_queue_upload_excel_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_excel_import_queue_upload_excel_post"},"Body_upload_for_analysis_analysis_upload_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_for_analysis_analysis_upload_post"},"Body_upload_images_zip_import_queue_sessions__session_id__upload_images_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_images_zip_import_queue_sessions__session_id__upload_images_post"},"CreateResponse":{"properties":{"id":{"type":"string","title":"Id"}},"type":"object","required":["id"],"title":"CreateResponse"},"DirectAnalysisResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"status":{"type":"string","title":"Status"},"backend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Backend"},"cropped_face_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cropped Face Url"},"scores":{"additionalProperties":{"type":"number"},"type":"object","title":"Scores"},"age":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Age"},"results":{"additionalProperties":true,"type":"object","title":"Results"},"warning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warning"}},"additionalProperties":true,"type":"object","required":["session_id","status"],"title":"DirectAnalysisResponse"},"FaceResultIn":{"properties":{"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"metrics":{"additionalProperties":true,"type":"object","title":"Metrics"},"recs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Recs"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"shop_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Code"},"loyalty_card":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Loyalty Card"}},"type":"object","required":["metrics"],"title":"FaceResultIn"},"FaceResultOut":{"properties":{"id":{"type":"string","title":"Id"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"metrics":{"additionalProperties":true,"type":"object","title":"Metrics"},"recs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Recs"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"cropped_face_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cropped Face Url"},"saved_products":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Saved Products","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","metrics","created_at"],"title":"FaceResultOut"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ItemUpdateBody":{"properties":{"data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Data"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"ItemUpdateBody"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"LoyaltyCardIn":{"properties":{"card_number":{"type":"string","maxLength":64,"minLength":1,"title":"Card Number"}},"type":"object","required":["card_number"],"title":"LoyaltyCardIn"},"ProductCreate":{"properties":{"sku":{"type":"string","title":"Sku"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"volume":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Volume"},"care_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Stage"},"product_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Line"},"type":{"type":"string","title":"Type","default":"product"},"modules":{"items":{"type":"string"},"type":"array","title":"Modules","default":[]},"categories":{"items":{"type":"string"},"type":"array","title":"Categories","default":[]},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"inci_components":{"items":{"type":"string"},"type":"array","title":"Inci Components","default":[]},"skin_types":{"items":{"type":"string"},"type":"array","title":"Skin Types","default":[]},"contraindications":{"items":{"type":"string"},"type":"array","title":"Contraindications","default":[]},"confirmation_tags":{"items":{"type":"string"},"type":"array","title":"Confirmation Tags","default":[]},"hypoallergenic":{"type":"boolean","title":"Hypoallergenic","default":false},"pregnancy_safe":{"type":"boolean","title":"Pregnancy Safe","default":false},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"attributes":{"additionalProperties":true,"type":"object","title":"Attributes","default":{}},"images":{"items":{"type":"string"},"type":"array","title":"Images","default":[]},"price":{"type":"number","title":"Price","default":0},"currency":{"type":"string","title":"Currency","default":"RUB"}},"type":"object","required":["sku","name"],"title":"ProductCreate"},"ProductUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"volume":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Volume"},"care_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Stage"},"product_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Line"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"modules":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Modules"},"categories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Categories"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"inci_components":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Inci Components"},"skin_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Skin Types"},"contraindications":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Contraindications"},"confirmation_tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Confirmation Tags"},"hypoallergenic":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Hypoallergenic"},"pregnancy_safe":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pregnancy Safe"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"attributes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Attributes"},"images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Images"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"ProductUpdate"},"ProfileUpdate":{"properties":{"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"preferences":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Preferences"}},"type":"object","title":"ProfileUpdate"},"RecommendationsRequest":{"properties":{"module":{"type":"string","title":"Module","default":"face"},"result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Id"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"analysis_results":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Analysis Results"},"age":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"limit":{"type":"integer","title":"Limit","default":10},"exclude_skus":{"items":{"type":"string"},"type":"array","title":"Exclude Skus","default":[]},"shop_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Code"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"price_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Min"},"price_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Max"},"boolean_filters":{"additionalProperties":true,"type":"object","title":"Boolean Filters","default":{}},"preferred_brands":{"items":{"type":"string"},"type":"array","title":"Preferred Brands","default":[]}},"type":"object","title":"RecommendationsRequest"},"RecommendationsResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"project_id":{"type":"string","title":"Project Id"},"module":{"type":"string","title":"Module"},"products":{"items":{"$ref":"#/components/schemas/RecommendedProduct"},"type":"array","title":"Products","default":[]},"procedure_page":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Procedure Page"}},"type":"object","required":["user_id","project_id","module"],"title":"RecommendationsResponse"},"RecommendedProduct":{"properties":{"sku":{"type":"string","title":"Sku"},"name":{"type":"string","title":"Name"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand"},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"categories":{"items":{"type":"string"},"type":"array","title":"Categories","default":[]},"price":{"type":"number","title":"Price","default":0.0},"original_price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Original Price"},"currency":{"type":"string","title":"Currency","default":"RUB"},"score":{"type":"number","title":"Score","default":0.0},"reason":{"type":"string","title":"Reason","default":""},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"spec":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Spec"},"skin_types":{"items":{"type":"string"},"type":"array","title":"Skin Types","default":[]},"skin_states":{"items":{"type":"string"},"type":"array","title":"Skin States","default":[]},"texture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Texture"},"how_to_use":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"How To Use"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"effect":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Effect"},"volume":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Volume"},"care_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Level"},"hypoallergenic":{"type":"boolean","title":"Hypoallergenic","default":false},"pregnancy_safe":{"type":"boolean","title":"Pregnancy Safe","default":false}},"type":"object","required":["sku","name"],"title":"RecommendedProduct"},"RecsUpdate":{"properties":{"recs":{"additionalProperties":true,"type":"object","title":"Recs"}},"type":"object","required":["recs"],"title":"RecsUpdate","description":"Юзер применил фильтры на экране результатов → фронт PATCH'ит сюда\nотфильтрованные рекомендации, чтобы QR-лендинг отдавал именно их,\nа не исходный (нефильтрованный) список со скана."},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"RegisterRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"preferences":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Preferences"}},"type":"object","required":["email","password"],"title":"RegisterRequest"},"SavedProductsIn":{"properties":{"saved_products":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Saved Products"}},"type":"object","required":["saved_products"],"title":"SavedProductsIn","description":"Юзер закидывает SKU в корзину на киоске → перед открытием\n«Забрать результат» фронт PATCH'ит сюда выбранные продукты, чтобы\nQR-лендинг (другое устройство) увидел только то, что юзер реально\nотметил, а не весь LLM-список рекомендаций."},"TokenPair":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"}},"type":"object","required":["access_token","refresh_token"],"title":"TokenPair"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"ProjectApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Ключ доступа к внешнему endpoint проекта."},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT access_token из /auth/guest, /auth/register или /auth/login. Для административных операций требуется admin JWT."},"AdminApiKey":{"type":"apiKey","in":"header","name":"X-Internal-Key","description":"Серверный ключ для каталога и очереди импорта. Не передавайте во frontend."}}}}