{"openapi":"3.1.0","info":{"title":"Egor Frolov – Portfolio API","description":"REST API, на котором работает портфолио. Каждая секция главной страницы – реальный ответ эндпоинта из этого API. Демо-блок «CoffeeExchange» дёргает POST /api/v1/coffee-demo/recalculate вживую при движении слайдеров.","contact":{"name":"Egor Frolov","email":"egorfjob@yandex.ru"},"version":"1.0.0"},"paths":{"/api/v1/about":{"get":{"tags":["profile"],"summary":"Личная информация и текущий статус","operationId":"get_about_api_v1_about_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/About"}}}}}}},"/api/v1/contacts":{"get":{"tags":["profile"],"summary":"Каналы связи","operationId":"get_contacts_api_v1_contacts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contacts"}}}}}}},"/api/v1/skills":{"get":{"tags":["profile"],"summary":"Технологический стек по категориям","operationId":"get_skills_api_v1_skills_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillsResponse"}}}}}}},"/api/v1/achievements":{"get":{"tags":["profile"],"summary":"Награды, публикации, признание","operationId":"get_achievements_api_v1_achievements_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Achievement"},"type":"array","title":"Response Get Achievements Api V1 Achievements Get"}}}}}}},"/api/v1/projects":{"get":{"tags":["projects"],"summary":"Список проектов (краткие карточки)","operationId":"list_projects_api_v1_projects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProjectSummary"},"type":"array","title":"Response List Projects Api V1 Projects Get"}}}}}}},"/api/v1/projects/{slug}":{"get":{"tags":["projects"],"summary":"Детальная информация о проекте","operationId":"get_project_api_v1_projects__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDetail"}}}},"404":{"description":"Проект не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/coffee-demo/recalculate":{"post":{"tags":["coffee-demo"],"summary":"Live-демо движка ценообразования из проекта CoffeeExchange","description":"Упрощённая публичная версия алгоритма «полоса вокруг среднего». Принимает снапшот рынка (продажи за окно) и параметры – возвращает новые цены, зоны (UP / DOWN / NEUTRAL) и границы нейтральной полосы. На странице портфолио этот эндпоинт вызывается вживую при движении слайдеров.","operationId":"recalculate_api_v1_coffee_demo_recalculate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoffeeDemoRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoffeeDemoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"About":{"properties":{"name":{"type":"string","title":"Name"},"handle":{"type":"string","title":"Handle"},"role":{"type":"string","title":"Role"},"location":{"type":"string","title":"Location"},"years_of_experience":{"type":"number","title":"Years Of Experience"},"bio":{"type":"string","title":"Bio"},"education":{"$ref":"#/components/schemas/Education"},"principles":{"items":{"$ref":"#/components/schemas/Principle"},"type":"array","title":"Principles"}},"type":"object","required":["name","handle","role","location","years_of_experience","bio","education","principles"],"title":"About","description":"Профильные данные на главной странице"},"Achievement":{"properties":{"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"year":{"type":"integer","title":"Year"}},"type":"object","required":["title","description","year"],"title":"Achievement","description":"Награда, публикация или конкурсное достижение"},"CoffeeDemoRequest":{"properties":{"drinks":{"items":{"$ref":"#/components/schemas/DrinkSnapshot"},"type":"array","title":"Drinks"},"neutral_zone_percent":{"type":"number","maximum":100.0,"exclusiveMinimum":0.0,"title":"Neutral Zone Percent","description":"Полная ширина нейтральной полосы вокруг среднего, %","default":20.0},"max_step_up_pct":{"type":"number","maximum":20.0,"exclusiveMinimum":0.0,"title":"Max Step Up Pct","description":"Максимальный шаг повышения цены за цикл, %","default":3.0},"max_step_down_pct":{"type":"number","maximum":20.0,"exclusiveMinimum":0.0,"title":"Max Step Down Pct","description":"Максимальный шаг понижения цены за цикл, %","default":3.0},"price_band_pct":{"type":"number","maximum":50.0,"exclusiveMinimum":0.0,"title":"Price Band Pct","description":"Жёсткие границы цены вокруг базовой, %","default":15.0}},"type":"object","required":["drinks"],"title":"CoffeeDemoRequest","description":"Параметры одного цикла пересчёта рынка."},"CoffeeDemoResponse":{"properties":{"market_average":{"type":"number","title":"Market Average","description":"Средние эффективные продажи рынка за цикл"},"band_low":{"type":"number","title":"Band Low"},"band_high":{"type":"number","title":"Band High"},"updates":{"items":{"$ref":"#/components/schemas/DrinkPriceUpdate"},"type":"array","title":"Updates"}},"type":"object","required":["market_average","band_low","band_high","updates"],"title":"CoffeeDemoResponse","description":"Сводный результат пересчёта рынка."},"Contacts":{"properties":{"telegram":{"type":"string","title":"Telegram"},"email":{"type":"string","title":"Email"}},"type":"object","required":["telegram","email"],"title":"Contacts","description":"Каналы связи."},"DrinkPriceUpdate":{"properties":{"drink_id":{"type":"string","title":"Drink Id"},"name":{"type":"string","title":"Name"},"previous_price":{"type":"number","title":"Previous Price"},"new_price":{"type":"number","title":"New Price"},"zone":{"type":"string","enum":["UP","DOWN","NEUTRAL"],"title":"Zone"},"delta_pct":{"type":"number","title":"Delta Pct","description":"Отклонение от базовой цены, %"}},"type":"object","required":["drink_id","name","previous_price","new_price","zone","delta_pct"],"title":"DrinkPriceUpdate","description":"Результат пересчёта по одному напитку."},"DrinkSnapshot":{"properties":{"drink_id":{"type":"string","title":"Drink Id"},"name":{"type":"string","title":"Name"},"base_price":{"type":"number","exclusiveMinimum":0.0,"title":"Base Price","description":"Базовая цена в рублях"},"sensitivity":{"type":"number","exclusiveMinimum":0.0,"title":"Sensitivity","description":"Множитель чувствительности к спросу. Нишевым напиткам ставится выше, чтобы небольшое число продаж считывалось как реальный сигнал.","default":1.0},"sales_count":{"type":"integer","minimum":0.0,"title":"Sales Count","description":"Продажи за окно анализа"}},"type":"object","required":["drink_id","name","base_price","sales_count"],"title":"DrinkSnapshot","description":"Состояние одного напитка на входе движка пересчёта."},"Education":{"properties":{"institution":{"type":"string","title":"Institution","description":"Название учебного заведения"},"program":{"type":"string","title":"Program","description":"Образовательная программа"},"year":{"type":"integer","title":"Year","description":"Текущий курс"},"expected_graduation":{"type":"integer","title":"Expected Graduation","description":"Год выпуска"}},"type":"object","required":["institution","program","year","expected_graduation"],"title":"Education","description":"Сведения об образовании"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Principle":{"properties":{"title":{"type":"string","title":"Title","description":"Короткая декларация принципа"},"body":{"type":"string","title":"Body","description":"Пояснение с примерами из реальных проектов"}},"type":"object","required":["title","body"],"title":"Principle","description":"Принцип из инженерного манифеста"},"ProjectDetail":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"tagline":{"type":"string","title":"Tagline"},"kind":{"type":"string","enum":["commercial","personal"],"title":"Kind"},"status":{"type":"string","enum":["production","mvp","active","archived"],"title":"Status"},"year":{"type":"string","title":"Year"},"role":{"type":"string","title":"Role"},"stack_highlights":{"items":{"type":"string"},"type":"array","title":"Stack Highlights"},"description":{"type":"string","title":"Description"},"responsibilities":{"items":{"type":"string"},"type":"array","title":"Responsibilities"},"full_stack":{"items":{"type":"string"},"type":"array","title":"Full Stack"},"technical_highlights":{"items":{"type":"string"},"type":"array","title":"Technical Highlights"},"scale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scale"},"public_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Link"}},"type":"object","required":["slug","name","tagline","kind","status","year","role","stack_highlights","description","responsibilities","full_stack","technical_highlights"],"title":"ProjectDetail","description":"Развёрнутое описание проекта с архитектурой и техническими решениями"},"ProjectSummary":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"tagline":{"type":"string","title":"Tagline"},"kind":{"type":"string","enum":["commercial","personal"],"title":"Kind"},"status":{"type":"string","enum":["production","mvp","active","archived"],"title":"Status"},"year":{"type":"string","title":"Year"},"role":{"type":"string","title":"Role"},"stack_highlights":{"items":{"type":"string"},"type":"array","title":"Stack Highlights"}},"type":"object","required":["slug","name","tagline","kind","status","year","role","stack_highlights"],"title":"ProjectSummary","description":"Краткая карточка проекта в общем списке"},"SkillCategory":{"properties":{"name":{"type":"string","title":"Name","description":"Название категории"},"items":{"items":{"type":"string"},"type":"array","title":"Items","description":"Технологии в категории"}},"type":"object","required":["name","items"],"title":"SkillCategory","description":"Категория технологического стека"},"SkillsResponse":{"properties":{"categories":{"items":{"$ref":"#/components/schemas/SkillCategory"},"type":"array","title":"Categories"}},"type":"object","required":["categories"],"title":"SkillsResponse","description":"Технологический стек, сгруппированный по категориям"},"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"}}}}