{"openapi":"3.0.3","info":{"title":"Мозък Б API","version":"1.4.0","description":"REST API за календар, колекции, каталог тестове, банка задачи, учебна таксономия и AI exam pipeline. Всички /v1 маршрути изискват API ключ (calendar:*, collections:*, exams:*, exams:inspect, questions:*, pipeline:*, taxonomy:*). Полетата на издание наследяват стойности от серията, освен ако са зададени изрично (price, място, venues и др.)."},"servers":[{"url":"https://api.mozak.be"}],"tags":[{"name":"Competitions","description":"Серии състезания (eventSeries)"},{"name":"Editions","description":"Издания (eventOccurrences)"},{"name":"Collections","description":"Колекции от тестове (examCollections)"},{"name":"Exams","description":"Каталог тестове — метаданни (без съдържание на въпроси освен /inspect)"},{"name":"Questions","description":"Банка задачи — търсене без ключове; решение зад questions:inspect"},{"name":"Pipeline","description":"Глобален AI pipeline config"},{"name":"Taxonomy","description":"Учебна йерархия (тема / сюжет / умение) и класификация на задачи"},{"name":"System","description":"Здраве и документация"}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key"}},"schemas":{"CompetitionWrite":{"type":"object","properties":{"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Заглавие на серията състезание (показва се в календара)."},"slug":{"description":"URL slug в kebab-case. По подразбиране се генерира от заглавието (транслитерация + kebab-case); при конфликт се добавя суфикс -2, -3, …","type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"scope":{"type":"string","enum":["school","city","national","international"],"description":"Обхват: school (училищно), city (градско), national (национално), international (международно)."},"difficulty":{"nullable":true,"description":"Трудност 1–5 (1 = много лесно, 5 = много трудно). null = не е зададена.","type":"integer","minimum":1,"maximum":5},"purposes":{"description":"Предназначение / аудитория (1–3 стойности).","maxItems":3,"type":"array","items":{"type":"string","enum":["olympiad","contest","popular","exam_prep","club","international"],"description":"Предназначение: olympiad, contest, popular, exam_prep, club, international."}},"regulationsMarkdown":{"description":"Регламент в Markdown. По подразбиране: празен низ.","type":"string","maxLength":50000},"regulationsSummary":{"description":"Кратко резюме на регламента (по избор).","nullable":true,"type":"string","maxLength":500},"defaultLocationText":{"description":"Място по подразбиране за всички издания (напр. „Учебна сграда“).","nullable":true,"type":"string","maxLength":300},"defaultCity":{"description":"Град по подразбиране за изданията.","nullable":true,"type":"string","maxLength":120},"defaultMapsUrl":{"description":"Карта по подразбиране (https).","nullable":true,"type":"string","format":"uri"},"defaultVenues":{"description":"Списък места по подразбиране. Издание може да ги замени.","maxItems":50,"type":"array","items":{"description":"Място за провеждане (град, зала, карта).","type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"description":"Име на сграда, зала или адрес (по избор).","nullable":true,"type":"string","maxLength":300},"mapsUrl":{"description":"Линк към карта (https).","nullable":true,"type":"string","format":"uri"},"gradesNote":{"description":"Бележка за класове на това място (свободен текст).","nullable":true,"type":"string","maxLength":200},"isPrimary":{"description":"Дали е основното място при няколко локации. По подразбиране: false.","type":"boolean"}},"required":["city"],"additionalProperties":false}},"defaultVenuesNote":{"description":"Markdown бележка за местата (напр. няколко града).","nullable":true,"type":"string","maxLength":5000},"heldOnlyInCity":{"description":"Град, в който състезанието се провежда присъствено и само там (напр. „Плевен“). По подразбиране за изданията. null = няма изричен град. Празен низ = изрично без значка (не се извежда от местата). Не се взима от defaultCity или scope. Макс. 120 символа. Отхвърля се за онлайн/дистанционно.","nullable":true,"type":"string","maxLength":120},"price":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"description":"Такса в EUR. null = сумата не е уточнена.","nullable":true,"type":"number","minimum":0},"note":{"description":"Пояснение към цената (свободен текст).","nullable":true,"type":"string","maxLength":500}},"required":["type"],"additionalProperties":false}],"description":"Цена по подразбиране за изданията."},"registrationInfo":{"description":"Информация за записване (Markdown).","nullable":true,"type":"string","maxLength":5000},"registrationDeadlineAt":{"description":"Краен срок за записване (ISO 8601).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"gradesMin":{"description":"Минимален клас (1–12).","nullable":true,"type":"integer","minimum":1,"maximum":12},"gradesMax":{"description":"Максимален клас (1–12).","nullable":true,"type":"integer","minimum":1,"maximum":12},"officialUrl":{"description":"Официален сайт на състезанието (https).","nullable":true,"type":"string","format":"uri"},"organizers":{"description":"Организатори (до 20).","maxItems":20,"type":"array","items":{"description":"Организатор на състезанието.","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Име на организатора."},"role":{"description":"Роля (напр. „Организатор“, „Координатор“).","nullable":true,"type":"string","maxLength":200},"email":{"description":"Имейл за контакт.","nullable":true,"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"description":"Телефон за контакт.","nullable":true,"type":"string","maxLength":50}},"required":["name"],"additionalProperties":false}},"participationMode":{"nullable":true,"type":"string","enum":["individual","team","both"],"description":"Режим на участие: individual (индивидуално), team (отборно), both (и двете)."},"teamSizeMin":{"description":"Минимален размер на отбор (при отборно участие).","nullable":true,"type":"integer","minimum":1,"maximum":20},"teamSizeMax":{"description":"Максимален размер на отбор (при отборно участие).","nullable":true,"type":"integer","minimum":1,"maximum":20},"roundType":{"type":"string","enum":["municipal","regional","national","remote_round","semi","final","single"],"description":"Тип кръг: municipal (общински), regional (областен), national (национален), remote_round (дистанционен), semi (полуфинал), final (финал), single (еднократно състезание)."},"groupSlug":{"description":"Slug на група свързани кръгове (напр. nom-math). Свързва отделни серии без промяна на URL. Няма проверка дали други серии вече ползват същия slug.","nullable":true,"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"groupTitle":{"description":"Заглавие на групата кръгове (напр. „НОМ по математика“).","nullable":true,"type":"string","maxLength":200},"roundOrder":{"description":"Ред на кръга в групата (1, 2, 3…).","nullable":true,"type":"integer","minimum":1,"maximum":20},"applicationInstructions":{"description":"Инструкции за записване (Markdown).","nullable":true,"type":"string","maxLength":10000},"resultsUrl":{"description":"Линк към резултати (https).","nullable":true,"type":"string","format":"uri"},"sourceUrl":{"description":"Източник на информацията (https).","nullable":true,"type":"string","format":"uri"},"admissionsNote":{"description":"Бележка за прием / квалификация (свободен текст).","nullable":true,"type":"string","maxLength":2000},"defaultDateMode":{"type":"string","enum":["sitting","window","multi_day_event"],"description":"Формат на провеждане: sitting (изпит в определен час), window (прозорец — училището избира ден), multi_day_event (многодневно събитие)."}},"required":["subject","title","scope","difficulty","price"],"additionalProperties":false},"CompetitionPatch":{"type":"object","properties":{"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Заглавие на серията състезание (показва се в календара)."},"slug":{"description":"URL slug в kebab-case. По подразбиране се генерира от заглавието (транслитерация + kebab-case); при конфликт се добавя суфикс -2, -3, …","type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"scope":{"type":"string","enum":["school","city","national","international"],"description":"Обхват: school (училищно), city (градско), national (национално), international (международно)."},"difficulty":{"nullable":true,"description":"Трудност 1–5 (1 = много лесно, 5 = много трудно). null = не е зададена.","type":"integer","minimum":1,"maximum":5},"purposes":{"description":"Предназначение / аудитория (1–3 стойности).","maxItems":3,"type":"array","items":{"type":"string","enum":["olympiad","contest","popular","exam_prep","club","international"],"description":"Предназначение: olympiad, contest, popular, exam_prep, club, international."}},"regulationsMarkdown":{"description":"Регламент в Markdown. По подразбиране: празен низ.","type":"string","maxLength":50000},"regulationsSummary":{"description":"Кратко резюме на регламента (по избор).","nullable":true,"type":"string","maxLength":500},"defaultLocationText":{"description":"Място по подразбиране за всички издания (напр. „Учебна сграда“).","nullable":true,"type":"string","maxLength":300},"defaultCity":{"description":"Град по подразбиране за изданията.","nullable":true,"type":"string","maxLength":120},"defaultMapsUrl":{"description":"Карта по подразбиране (https).","nullable":true,"type":"string","format":"uri"},"defaultVenues":{"description":"Списък места по подразбиране. Издание може да ги замени.","maxItems":50,"type":"array","items":{"description":"Място за провеждане (град, зала, карта).","type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"description":"Име на сграда, зала или адрес (по избор).","nullable":true,"type":"string","maxLength":300},"mapsUrl":{"description":"Линк към карта (https).","nullable":true,"type":"string","format":"uri"},"gradesNote":{"description":"Бележка за класове на това място (свободен текст).","nullable":true,"type":"string","maxLength":200},"isPrimary":{"description":"Дали е основното място при няколко локации. По подразбиране: false.","type":"boolean"}},"required":["city"],"additionalProperties":false}},"defaultVenuesNote":{"description":"Markdown бележка за местата (напр. няколко града).","nullable":true,"type":"string","maxLength":5000},"heldOnlyInCity":{"description":"Град, в който състезанието се провежда присъствено и само там (напр. „Плевен“). По подразбиране за изданията. null = няма изричен град. Празен низ = изрично без значка (не се извежда от местата). Не се взима от defaultCity или scope. Макс. 120 символа. Отхвърля се за онлайн/дистанционно.","nullable":true,"type":"string","maxLength":120},"price":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"description":"Такса в EUR. null = сумата не е уточнена.","nullable":true,"type":"number","minimum":0},"note":{"description":"Пояснение към цената (свободен текст).","nullable":true,"type":"string","maxLength":500}},"required":["type"],"additionalProperties":false}],"description":"Цена по подразбиране за изданията."},"registrationInfo":{"description":"Информация за записване (Markdown).","nullable":true,"type":"string","maxLength":5000},"registrationDeadlineAt":{"description":"Краен срок за записване (ISO 8601).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"gradesMin":{"description":"Минимален клас (1–12).","nullable":true,"type":"integer","minimum":1,"maximum":12},"gradesMax":{"description":"Максимален клас (1–12).","nullable":true,"type":"integer","minimum":1,"maximum":12},"officialUrl":{"description":"Официален сайт на състезанието (https).","nullable":true,"type":"string","format":"uri"},"organizers":{"description":"Организатори (до 20).","maxItems":20,"type":"array","items":{"description":"Организатор на състезанието.","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Име на организатора."},"role":{"description":"Роля (напр. „Организатор“, „Координатор“).","nullable":true,"type":"string","maxLength":200},"email":{"description":"Имейл за контакт.","nullable":true,"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"description":"Телефон за контакт.","nullable":true,"type":"string","maxLength":50}},"required":["name"],"additionalProperties":false}},"participationMode":{"nullable":true,"type":"string","enum":["individual","team","both"],"description":"Режим на участие: individual (индивидуално), team (отборно), both (и двете)."},"teamSizeMin":{"description":"Минимален размер на отбор (при отборно участие).","nullable":true,"type":"integer","minimum":1,"maximum":20},"teamSizeMax":{"description":"Максимален размер на отбор (при отборно участие).","nullable":true,"type":"integer","minimum":1,"maximum":20},"roundType":{"type":"string","enum":["municipal","regional","national","remote_round","semi","final","single"],"description":"Тип кръг: municipal (общински), regional (областен), national (национален), remote_round (дистанционен), semi (полуфинал), final (финал), single (еднократно състезание)."},"groupSlug":{"description":"Slug на група свързани кръгове (напр. nom-math). Свързва отделни серии без промяна на URL. Няма проверка дали други серии вече ползват същия slug.","nullable":true,"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"groupTitle":{"description":"Заглавие на групата кръгове (напр. „НОМ по математика“).","nullable":true,"type":"string","maxLength":200},"roundOrder":{"description":"Ред на кръга в групата (1, 2, 3…).","nullable":true,"type":"integer","minimum":1,"maximum":20},"applicationInstructions":{"description":"Инструкции за записване (Markdown).","nullable":true,"type":"string","maxLength":10000},"resultsUrl":{"description":"Линк към резултати (https).","nullable":true,"type":"string","format":"uri"},"sourceUrl":{"description":"Източник на информацията (https).","nullable":true,"type":"string","format":"uri"},"admissionsNote":{"description":"Бележка за прием / квалификация (свободен текст).","nullable":true,"type":"string","maxLength":2000},"defaultDateMode":{"type":"string","enum":["sitting","window","multi_day_event"],"description":"Формат на провеждане: sitting (изпит в определен час), window (прозорец — училището избира ден), multi_day_event (многодневно събитие)."}},"additionalProperties":false},"Competition":{"type":"object","properties":{"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Заглавие на серията състезание (показва се в календара)."},"slug":{"description":"URL slug в kebab-case. По подразбиране се генерира от заглавието (транслитерация + kebab-case); при конфликт се добавя суфикс -2, -3, …","type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"scope":{"type":"string","enum":["school","city","national","international"],"description":"Обхват: school (училищно), city (градско), national (национално), international (международно)."},"difficulty":{"nullable":true,"description":"Трудност 1–5 (1 = много лесно, 5 = много трудно). null = не е зададена.","type":"integer","minimum":1,"maximum":5},"purposes":{"description":"Предназначение / аудитория (1–3 стойности).","maxItems":3,"type":"array","items":{"type":"string","enum":["olympiad","contest","popular","exam_prep","club","international"],"description":"Предназначение: olympiad, contest, popular, exam_prep, club, international."}},"regulationsMarkdown":{"type":"string","description":"Регламент в Markdown. По подразбиране: празен низ."},"regulationsSummary":{"nullable":true,"description":"Кратко резюме на регламента (по избор).","type":"string"},"defaultLocationText":{"nullable":true,"description":"Място по подразбиране за всички издания (напр. „Учебна сграда“).","type":"string"},"defaultCity":{"nullable":true,"description":"Град по подразбиране за изданията.","type":"string"},"defaultMapsUrl":{"nullable":true,"description":"Карта по подразбиране (https).","type":"string"},"defaultVenues":{"type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."},"description":"Списък места по подразбиране за изданията."},"defaultVenuesNote":{"nullable":true,"description":"Markdown бележка за местата (напр. няколко града).","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Град по подразбиране „само в …“. null = няма изричен град. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}],"description":"Цена по подразбиране за изданията."},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"gradesMin":{"nullable":true,"description":"Минимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"gradesMax":{"nullable":true,"description":"Максимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"officialUrl":{"nullable":true,"description":"Официален сайт на състезанието (https).","type":"string"},"organizers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Име на организатора."},"role":{"nullable":true,"description":"Роля (напр. „Организатор“, „Координатор“).","type":"string","maxLength":200},"email":{"nullable":true,"description":"Имейл за контакт.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"nullable":true,"description":"Телефон за контакт.","type":"string","maxLength":50}},"required":["name","role","email","phone"],"additionalProperties":false,"description":"Организатор на състезанието."},"description":"Организатори на състезанието."},"participationMode":{"nullable":true,"type":"string","enum":["individual","team","both"],"description":"Режим на участие: individual (индивидуално), team (отборно), both (и двете)."},"teamSizeMin":{"nullable":true,"description":"Минимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"teamSizeMax":{"nullable":true,"description":"Максимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"roundType":{"type":"string","enum":["municipal","regional","national","remote_round","semi","final","single"],"description":"Тип кръг: municipal (общински), regional (областен), national (национален), remote_round (дистанционен), semi (полуфинал), final (финал), single (еднократно състезание)."},"groupSlug":{"nullable":true,"description":"Slug на група свързани кръгове (напр. nom-math). Свързва отделни серии без промяна на URL.","type":"string"},"groupTitle":{"nullable":true,"description":"Заглавие на групата кръгове (напр. „НОМ по математика“).","type":"string"},"roundOrder":{"nullable":true,"description":"Ред на кръга в групата (1, 2, 3…).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"applicationInstructions":{"nullable":true,"description":"Инструкции за записване (Markdown).","type":"string"},"resultsUrl":{"nullable":true,"description":"Линк към резултати (https).","type":"string"},"sourceUrl":{"nullable":true,"description":"Източник на информацията (https).","type":"string"},"admissionsNote":{"nullable":true,"description":"Бележка за прием / квалификация (свободен текст).","type":"string"},"defaultDateMode":{"type":"string","enum":["sitting","window","multi_day_event"],"description":"Формат на провеждане: sitting (изпит в определен час), window (прозорец — училището избира ден), multi_day_event (многодневно събитие)."},"id":{"type":"string","description":"Firestore document ID на серията."},"cover":{"type":"object","properties":{"originalUrl":{"nullable":true,"description":"HTTPS URL на оригиналното изображение в Mozak Storage.","type":"string"},"thumbUrl":{"nullable":true,"description":"HTTPS URL на миниатюрата за списъка.","type":"string"},"headerUrl":{"nullable":true,"description":"HTTPS URL на header за детайла.","type":"string"},"crops":{"type":"object","properties":{"thumb":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"header":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"required":["thumb","header"],"additionalProperties":false,"description":"Изрязвания по вариант (thumb и header са независими)."},"updatedAt":{"nullable":true,"description":"Кога е обновена корицата (ISO 8601).","type":"string"}},"required":["originalUrl","thumbUrl","headerUrl","crops","updatedAt"],"additionalProperties":false,"description":"Корица в Mozak Storage (thumb, header, оригинал)."},"coverUrl":{"nullable":true,"description":"Показван URL на корицата (header, иначе thumb, иначе legacy). Само за четене.","type":"string"},"currentRegulationVersionId":{"nullable":true,"description":"ID на текущата (отворена) публикувана версия в regulationVersions; null ако няма.","type":"string"},"sourceCheckedAt":{"nullable":true,"description":"Кога е проверен източникът (ISO 8601). Само за четене; задава се автоматично при промяна на sourceUrl.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"editions":{"description":"Списък с издания на серията (присъства при ?include=editions).","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID на изданието."},"competitionId":{"type":"string","description":"ID на родителската серия (seriesId)."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"nullable":true,"description":"Край на изданието (ISO 8601). За all-day: край на периода (включително).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"nullable":true,"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"nullable":true,"description":"Начало на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"nullable":true,"description":"Край на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"nullable":true,"description":"Място (замества defaultLocationText на серията).","type":"string"},"city":{"nullable":true,"description":"Град (замества defaultCity на серията).","type":"string"},"mapsUrl":{"nullable":true,"description":"Карта (https). Замества defaultMapsUrl на серията.","type":"string"},"venues":{"nullable":true,"description":"Места за това издание. null = наследява defaultVenues от серията.","type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."}},"venuesNote":{"nullable":true,"description":"Markdown бележка за местата.","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Записан град „само в …“. null = наследява серията. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"nullable":true,"description":"Цена за изданието. null = наследява цената на серията.","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}]},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."},"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Календарна година на събитието (Europe/Sofia)."},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","competitionId","subject","startAt","endAt","allDay","dateMode","examStartAt","examEndAt","locationText","city","mapsUrl","venues","venuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","status","year","createdAt","updatedAt"],"additionalProperties":false}}},"required":["subject","title","scope","difficulty","regulationsMarkdown","regulationsSummary","defaultLocationText","defaultCity","defaultMapsUrl","defaultVenues","defaultVenuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","gradesMin","gradesMax","officialUrl","organizers","participationMode","teamSizeMin","teamSizeMax","roundType","groupSlug","groupTitle","roundOrder","applicationInstructions","resultsUrl","sourceUrl","admissionsNote","defaultDateMode","id","cover","coverUrl","currentRegulationVersionId","sourceCheckedAt","createdAt","updatedAt"],"additionalProperties":false,"description":"Серия състезание (eventSeries)."},"CompetitionList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Заглавие на серията състезание (показва се в календара)."},"slug":{"description":"URL slug в kebab-case. По подразбиране се генерира от заглавието (транслитерация + kebab-case); при конфликт се добавя суфикс -2, -3, …","type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"scope":{"type":"string","enum":["school","city","national","international"],"description":"Обхват: school (училищно), city (градско), national (национално), international (международно)."},"difficulty":{"nullable":true,"description":"Трудност 1–5 (1 = много лесно, 5 = много трудно). null = не е зададена.","type":"integer","minimum":1,"maximum":5},"purposes":{"description":"Предназначение / аудитория (1–3 стойности).","maxItems":3,"type":"array","items":{"type":"string","enum":["olympiad","contest","popular","exam_prep","club","international"],"description":"Предназначение: olympiad, contest, popular, exam_prep, club, international."}},"regulationsMarkdown":{"type":"string","description":"Регламент в Markdown. По подразбиране: празен низ."},"regulationsSummary":{"nullable":true,"description":"Кратко резюме на регламента (по избор).","type":"string"},"defaultLocationText":{"nullable":true,"description":"Място по подразбиране за всички издания (напр. „Учебна сграда“).","type":"string"},"defaultCity":{"nullable":true,"description":"Град по подразбиране за изданията.","type":"string"},"defaultMapsUrl":{"nullable":true,"description":"Карта по подразбиране (https).","type":"string"},"defaultVenues":{"type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."},"description":"Списък места по подразбиране за изданията."},"defaultVenuesNote":{"nullable":true,"description":"Markdown бележка за местата (напр. няколко града).","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Град по подразбиране „само в …“. null = няма изричен град. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}],"description":"Цена по подразбиране за изданията."},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"gradesMin":{"nullable":true,"description":"Минимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"gradesMax":{"nullable":true,"description":"Максимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"officialUrl":{"nullable":true,"description":"Официален сайт на състезанието (https).","type":"string"},"organizers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Име на организатора."},"role":{"nullable":true,"description":"Роля (напр. „Организатор“, „Координатор“).","type":"string","maxLength":200},"email":{"nullable":true,"description":"Имейл за контакт.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"nullable":true,"description":"Телефон за контакт.","type":"string","maxLength":50}},"required":["name","role","email","phone"],"additionalProperties":false,"description":"Организатор на състезанието."},"description":"Организатори на състезанието."},"participationMode":{"nullable":true,"type":"string","enum":["individual","team","both"],"description":"Режим на участие: individual (индивидуално), team (отборно), both (и двете)."},"teamSizeMin":{"nullable":true,"description":"Минимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"teamSizeMax":{"nullable":true,"description":"Максимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"roundType":{"type":"string","enum":["municipal","regional","national","remote_round","semi","final","single"],"description":"Тип кръг: municipal (общински), regional (областен), national (национален), remote_round (дистанционен), semi (полуфинал), final (финал), single (еднократно състезание)."},"groupSlug":{"nullable":true,"description":"Slug на група свързани кръгове (напр. nom-math). Свързва отделни серии без промяна на URL.","type":"string"},"groupTitle":{"nullable":true,"description":"Заглавие на групата кръгове (напр. „НОМ по математика“).","type":"string"},"roundOrder":{"nullable":true,"description":"Ред на кръга в групата (1, 2, 3…).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"applicationInstructions":{"nullable":true,"description":"Инструкции за записване (Markdown).","type":"string"},"resultsUrl":{"nullable":true,"description":"Линк към резултати (https).","type":"string"},"sourceUrl":{"nullable":true,"description":"Източник на информацията (https).","type":"string"},"admissionsNote":{"nullable":true,"description":"Бележка за прием / квалификация (свободен текст).","type":"string"},"defaultDateMode":{"type":"string","enum":["sitting","window","multi_day_event"],"description":"Формат на провеждане: sitting (изпит в определен час), window (прозорец — училището избира ден), multi_day_event (многодневно събитие)."},"id":{"type":"string","description":"Firestore document ID на серията."},"cover":{"type":"object","properties":{"originalUrl":{"nullable":true,"description":"HTTPS URL на оригиналното изображение в Mozak Storage.","type":"string"},"thumbUrl":{"nullable":true,"description":"HTTPS URL на миниатюрата за списъка.","type":"string"},"headerUrl":{"nullable":true,"description":"HTTPS URL на header за детайла.","type":"string"},"crops":{"type":"object","properties":{"thumb":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"header":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"required":["thumb","header"],"additionalProperties":false,"description":"Изрязвания по вариант (thumb и header са независими)."},"updatedAt":{"nullable":true,"description":"Кога е обновена корицата (ISO 8601).","type":"string"}},"required":["originalUrl","thumbUrl","headerUrl","crops","updatedAt"],"additionalProperties":false,"description":"Корица в Mozak Storage (thumb, header, оригинал)."},"coverUrl":{"nullable":true,"description":"Показван URL на корицата (header, иначе thumb, иначе legacy). Само за четене.","type":"string"},"currentRegulationVersionId":{"nullable":true,"description":"ID на текущата (отворена) публикувана версия в regulationVersions; null ако няма.","type":"string"},"sourceCheckedAt":{"nullable":true,"description":"Кога е проверен източникът (ISO 8601). Само за четене; задава се автоматично при промяна на sourceUrl.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["subject","title","scope","difficulty","regulationsMarkdown","regulationsSummary","defaultLocationText","defaultCity","defaultMapsUrl","defaultVenues","defaultVenuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","gradesMin","gradesMax","officialUrl","organizers","participationMode","teamSizeMin","teamSizeMax","roundType","groupSlug","groupTitle","roundOrder","applicationInstructions","resultsUrl","sourceUrl","admissionsNote","defaultDateMode","id","cover","coverUrl","currentRegulationVersionId","sourceCheckedAt","createdAt","updatedAt"],"additionalProperties":false},"description":"Списък със серии състезания."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Лимит на върнатите записи."},"nextCursor":{"nullable":true,"description":"Курсор за следваща страница (base64url) или null.","type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false,"description":"Информация за пагинация."}},"required":["data","pagination"],"additionalProperties":false,"description":"Отговор със списък от серии състезания."},"EditionWrite":{"type":"object","properties":{"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"description":"Край на изданието. За all-day: край на периода (включително).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","nullable":true,"type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"description":"Начало на изпита (само при multi_day_event).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"description":"Край на изпита (само при multi_day_event).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"description":"Място (замества defaultLocationText на серията).","nullable":true,"type":"string","maxLength":300},"city":{"description":"Град (замества defaultCity на серията).","nullable":true,"type":"string","maxLength":120},"mapsUrl":{"description":"Карта (https). Замества defaultMapsUrl на серията.","nullable":true,"type":"string","format":"uri"},"venues":{"description":"Места за това издание. null = наследява defaultVenues от серията.","nullable":true,"maxItems":50,"type":"array","items":{"description":"Място за провеждане (град, зала, карта).","type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"description":"Име на сграда, зала или адрес (по избор).","nullable":true,"type":"string","maxLength":300},"mapsUrl":{"description":"Линк към карта (https).","nullable":true,"type":"string","format":"uri"},"gradesNote":{"description":"Бележка за класове на това място (свободен текст).","nullable":true,"type":"string","maxLength":200},"isPrimary":{"description":"Дали е основното място при няколко локации. По подразбиране: false.","type":"boolean"}},"required":["city"],"additionalProperties":false}},"venuesNote":{"description":"Markdown бележка за местата.","nullable":true,"type":"string","maxLength":5000},"heldOnlyInCity":{"description":"Град, в който това издание се провежда присъствено и само там. null = наследява heldOnlyInCity на серията, после извеждане от venues (или defaultVenues), ако всички са в един град и няма дистанционен вариант. Непразен низ замества серията. Празен низ = без значка за това издание. Не се взима от city. Макс. 120.","nullable":true,"type":"string","maxLength":120},"price":{"description":"Цена за изданието. null = наследява цената на серията.","nullable":true,"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"description":"Такса в EUR. null = сумата не е уточнена.","nullable":true,"type":"number","minimum":0},"note":{"description":"Пояснение към цената (свободен текст).","nullable":true,"type":"string","maxLength":500}},"required":["type"],"additionalProperties":false}]},"registrationInfo":{"description":"Информация за записване (Markdown).","nullable":true,"type":"string","maxLength":5000},"registrationDeadlineAt":{"description":"Краен срок за записване (ISO 8601).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."}},"required":["startAt","allDay","status"],"additionalProperties":false},"EditionPatch":{"type":"object","properties":{"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"description":"Край на изданието. За all-day: край на периода (включително).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","nullable":true,"type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"description":"Начало на изпита (само при multi_day_event).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"description":"Край на изпита (само при multi_day_event).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"description":"Място (замества defaultLocationText на серията).","nullable":true,"type":"string","maxLength":300},"city":{"description":"Град (замества defaultCity на серията).","nullable":true,"type":"string","maxLength":120},"mapsUrl":{"description":"Карта (https). Замества defaultMapsUrl на серията.","nullable":true,"type":"string","format":"uri"},"venues":{"description":"Места за това издание. null = наследява defaultVenues от серията.","nullable":true,"maxItems":50,"type":"array","items":{"description":"Място за провеждане (град, зала, карта).","type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"description":"Име на сграда, зала или адрес (по избор).","nullable":true,"type":"string","maxLength":300},"mapsUrl":{"description":"Линк към карта (https).","nullable":true,"type":"string","format":"uri"},"gradesNote":{"description":"Бележка за класове на това място (свободен текст).","nullable":true,"type":"string","maxLength":200},"isPrimary":{"description":"Дали е основното място при няколко локации. По подразбиране: false.","type":"boolean"}},"required":["city"],"additionalProperties":false}},"venuesNote":{"description":"Markdown бележка за местата.","nullable":true,"type":"string","maxLength":5000},"heldOnlyInCity":{"description":"Град, в който това издание се провежда присъствено и само там. null = наследява heldOnlyInCity на серията, после извеждане от venues (или defaultVenues), ако всички са в един град и няма дистанционен вариант. Непразен низ замества серията. Празен низ = без значка за това издание. Не се взима от city. Макс. 120.","nullable":true,"type":"string","maxLength":120},"price":{"description":"Цена за изданието. null = наследява цената на серията.","nullable":true,"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"description":"Такса в EUR. null = сумата не е уточнена.","nullable":true,"type":"number","minimum":0},"note":{"description":"Пояснение към цената (свободен текст).","nullable":true,"type":"string","maxLength":500}},"required":["type"],"additionalProperties":false}]},"registrationInfo":{"description":"Информация за записване (Markdown).","nullable":true,"type":"string","maxLength":5000},"registrationDeadlineAt":{"description":"Краен срок за записване (ISO 8601).","nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."}},"additionalProperties":false},"Edition":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID на изданието."},"competitionId":{"type":"string","description":"ID на родителската серия (seriesId)."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"nullable":true,"description":"Край на изданието (ISO 8601). За all-day: край на периода (включително).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"nullable":true,"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"nullable":true,"description":"Начало на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"nullable":true,"description":"Край на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"nullable":true,"description":"Място (замества defaultLocationText на серията).","type":"string"},"city":{"nullable":true,"description":"Град (замества defaultCity на серията).","type":"string"},"mapsUrl":{"nullable":true,"description":"Карта (https). Замества defaultMapsUrl на серията.","type":"string"},"venues":{"nullable":true,"description":"Места за това издание. null = наследява defaultVenues от серията.","type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."}},"venuesNote":{"nullable":true,"description":"Markdown бележка за местата.","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Записан град „само в …“. null = наследява серията. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"nullable":true,"description":"Цена за изданието. null = наследява цената на серията.","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}]},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."},"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Календарна година на събитието (Europe/Sofia)."},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","competitionId","subject","startAt","endAt","allDay","dateMode","examStartAt","examEndAt","locationText","city","mapsUrl","venues","venuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","status","year","createdAt","updatedAt"],"additionalProperties":false},"EditionList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID на изданието."},"competitionId":{"type":"string","description":"ID на родителската серия (seriesId)."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"nullable":true,"description":"Край на изданието (ISO 8601). За all-day: край на периода (включително).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"nullable":true,"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"nullable":true,"description":"Начало на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"nullable":true,"description":"Край на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"nullable":true,"description":"Място (замества defaultLocationText на серията).","type":"string"},"city":{"nullable":true,"description":"Град (замества defaultCity на серията).","type":"string"},"mapsUrl":{"nullable":true,"description":"Карта (https). Замества defaultMapsUrl на серията.","type":"string"},"venues":{"nullable":true,"description":"Места за това издание. null = наследява defaultVenues от серията.","type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."}},"venuesNote":{"nullable":true,"description":"Markdown бележка за местата.","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Записан град „само в …“. null = наследява серията. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"nullable":true,"description":"Цена за изданието. null = наследява цената на серията.","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}]},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."},"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Календарна година на събитието (Europe/Sofia)."},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","competitionId","subject","startAt","endAt","allDay","dateMode","examStartAt","examEndAt","locationText","city","mapsUrl","venues","venuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","status","year","createdAt","updatedAt"],"additionalProperties":false},"description":"Списък с издания."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Лимит на върнатите записи."},"nextCursor":{"nullable":true,"description":"Курсор за следваща страница (base64url) или null.","type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false,"description":"Информация за пагинация."}},"required":["data","pagination"],"additionalProperties":false,"description":"Отговор със списък от издания за дадена серия."},"EditionFeed":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID на изданието."},"competitionId":{"type":"string","description":"ID на родителската серия (seriesId)."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"startAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Начало на изданието (ISO 8601)."},"endAt":{"nullable":true,"description":"Край на изданието (ISO 8601). За all-day: край на периода (включително).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"allDay":{"type":"boolean","description":"true = целодневно събитие (без конкретен час)."},"dateMode":{"nullable":true,"description":"Формат на датите. null = наследява defaultDateMode от серията. Стойности: sitting (изпит в определен час), window (прозорец), multi_day_event (многодневно събитие — startAt/endAt са пътуване, examStartAt/examEndAt са изпит).","type":"string","enum":["sitting","window","multi_day_event"]},"examStartAt":{"nullable":true,"description":"Начало на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"examEndAt":{"nullable":true,"description":"Край на изпита (само при multi_day_event).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"locationText":{"nullable":true,"description":"Място (замества defaultLocationText на серията).","type":"string"},"city":{"nullable":true,"description":"Град (замества defaultCity на серията).","type":"string"},"mapsUrl":{"nullable":true,"description":"Карта (https). Замества defaultMapsUrl на серията.","type":"string"},"venues":{"nullable":true,"description":"Места за това издание. null = наследява defaultVenues от серията.","type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."}},"venuesNote":{"nullable":true,"description":"Markdown бележка за местата.","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Записан град „само в …“. null = наследява серията. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"nullable":true,"description":"Цена за изданието. null = наследява цената на серията.","oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}]},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"status":{"type":"string","enum":["draft","published"],"description":"Статус на изданието: draft (чернова) или published (публикувано)."},"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Календарна година на събитието (Europe/Sofia)."},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"competition":{"description":"Данни за родителската серия (при ?expand=competition).","nullable":true,"type":"object","properties":{"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Заглавие на серията състезание (показва се в календара)."},"slug":{"description":"URL slug в kebab-case. По подразбиране се генерира от заглавието (транслитерация + kebab-case); при конфликт се добавя суфикс -2, -3, …","type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"scope":{"type":"string","enum":["school","city","national","international"],"description":"Обхват: school (училищно), city (градско), national (национално), international (международно)."},"difficulty":{"nullable":true,"description":"Трудност 1–5 (1 = много лесно, 5 = много трудно). null = не е зададена.","type":"integer","minimum":1,"maximum":5},"purposes":{"description":"Предназначение / аудитория (1–3 стойности).","maxItems":3,"type":"array","items":{"type":"string","enum":["olympiad","contest","popular","exam_prep","club","international"],"description":"Предназначение: olympiad, contest, popular, exam_prep, club, international."}},"regulationsMarkdown":{"type":"string","description":"Регламент в Markdown. По подразбиране: празен низ."},"regulationsSummary":{"nullable":true,"description":"Кратко резюме на регламента (по избор).","type":"string"},"defaultLocationText":{"nullable":true,"description":"Място по подразбиране за всички издания (напр. „Учебна сграда“).","type":"string"},"defaultCity":{"nullable":true,"description":"Град по подразбиране за изданията.","type":"string"},"defaultMapsUrl":{"nullable":true,"description":"Карта по подразбиране (https).","type":"string"},"defaultVenues":{"type":"array","items":{"type":"object","properties":{"city":{"type":"string","minLength":1,"maxLength":120,"description":"Град на мястото за провеждане."},"place":{"nullable":true,"description":"Име на сграда, зала или адрес (по избор).","type":"string","maxLength":300},"mapsUrl":{"nullable":true,"description":"Линк към карта (https).","type":"string","format":"uri"},"gradesNote":{"nullable":true,"description":"Бележка за класове на това място (свободен текст).","type":"string","maxLength":200},"isPrimary":{"type":"boolean","description":"Дали е основното място при няколко локации."}},"required":["city","place","mapsUrl","gradesNote","isPrimary"],"additionalProperties":false,"description":"Място за провеждане (град, зала, карта)."},"description":"Списък места по подразбиране за изданията."},"defaultVenuesNote":{"nullable":true,"description":"Markdown бележка за местата (напр. няколко града).","type":"string"},"heldOnlyInCity":{"nullable":true,"description":"Град по подразбиране „само в …“. null = няма изричен град. Празен низ = изрично без значка. Не е изведеният град за UI.","type":"string"},"price":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["free"],"description":"Вид цена: free (безплатно)."}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["paid"],"description":"Вид цена: paid (платено)."},"amountEur":{"nullable":true,"type":"number","minimum":0},"note":{"nullable":true,"type":"string","maxLength":500}},"required":["type","amountEur","note"],"additionalProperties":false}],"description":"Цена по подразбиране за изданията."},"registrationInfo":{"nullable":true,"description":"Информация за записване (Markdown).","type":"string"},"registrationDeadlineAt":{"nullable":true,"description":"Краен срок за записване (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"gradesMin":{"nullable":true,"description":"Минимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"gradesMax":{"nullable":true,"description":"Максимален клас (1–12).","type":"integer","minimum":1,"maximum":12},"officialUrl":{"nullable":true,"description":"Официален сайт на състезанието (https).","type":"string"},"organizers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Име на организатора."},"role":{"nullable":true,"description":"Роля (напр. „Организатор“, „Координатор“).","type":"string","maxLength":200},"email":{"nullable":true,"description":"Имейл за контакт.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"nullable":true,"description":"Телефон за контакт.","type":"string","maxLength":50}},"required":["name","role","email","phone"],"additionalProperties":false,"description":"Организатор на състезанието."},"description":"Организатори на състезанието."},"participationMode":{"nullable":true,"type":"string","enum":["individual","team","both"],"description":"Режим на участие: individual (индивидуално), team (отборно), both (и двете)."},"teamSizeMin":{"nullable":true,"description":"Минимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"teamSizeMax":{"nullable":true,"description":"Максимален размер на отбор (при отборно участие).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"roundType":{"type":"string","enum":["municipal","regional","national","remote_round","semi","final","single"],"description":"Тип кръг: municipal (общински), regional (областен), national (национален), remote_round (дистанционен), semi (полуфинал), final (финал), single (еднократно състезание)."},"groupSlug":{"nullable":true,"description":"Slug на група свързани кръгове (напр. nom-math). Свързва отделни серии без промяна на URL.","type":"string"},"groupTitle":{"nullable":true,"description":"Заглавие на групата кръгове (напр. „НОМ по математика“).","type":"string"},"roundOrder":{"nullable":true,"description":"Ред на кръга в групата (1, 2, 3…).","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"applicationInstructions":{"nullable":true,"description":"Инструкции за записване (Markdown).","type":"string"},"resultsUrl":{"nullable":true,"description":"Линк към резултати (https).","type":"string"},"sourceUrl":{"nullable":true,"description":"Източник на информацията (https).","type":"string"},"admissionsNote":{"nullable":true,"description":"Бележка за прием / квалификация (свободен текст).","type":"string"},"defaultDateMode":{"type":"string","enum":["sitting","window","multi_day_event"],"description":"Формат на провеждане: sitting (изпит в определен час), window (прозорец — училището избира ден), multi_day_event (многодневно събитие)."},"id":{"type":"string","description":"Firestore document ID на серията."},"cover":{"type":"object","properties":{"originalUrl":{"nullable":true,"description":"HTTPS URL на оригиналното изображение в Mozak Storage.","type":"string"},"thumbUrl":{"nullable":true,"description":"HTTPS URL на миниатюрата за списъка.","type":"string"},"headerUrl":{"nullable":true,"description":"HTTPS URL на header за детайла.","type":"string"},"crops":{"type":"object","properties":{"thumb":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"header":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"required":["thumb","header"],"additionalProperties":false,"description":"Изрязвания по вариант (thumb и header са независими)."},"updatedAt":{"nullable":true,"description":"Кога е обновена корицата (ISO 8601).","type":"string"}},"required":["originalUrl","thumbUrl","headerUrl","crops","updatedAt"],"additionalProperties":false,"description":"Корица в Mozak Storage (thumb, header, оригинал)."},"coverUrl":{"nullable":true,"description":"Показван URL на корицата (header, иначе thumb, иначе legacy). Само за четене.","type":"string"},"currentRegulationVersionId":{"nullable":true,"description":"ID на текущата (отворена) публикувана версия в regulationVersions; null ако няма.","type":"string"},"sourceCheckedAt":{"nullable":true,"description":"Кога е проверен източникът (ISO 8601). Само за четене; задава се автоматично при промяна на sourceUrl.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"createdAt":{"nullable":true,"description":"Създадено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"nullable":true,"description":"Обновено на (ISO 8601).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["subject","title","scope","difficulty","regulationsMarkdown","regulationsSummary","defaultLocationText","defaultCity","defaultMapsUrl","defaultVenues","defaultVenuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","gradesMin","gradesMax","officialUrl","organizers","participationMode","teamSizeMin","teamSizeMax","roundType","groupSlug","groupTitle","roundOrder","applicationInstructions","resultsUrl","sourceUrl","admissionsNote","defaultDateMode","id","cover","coverUrl","currentRegulationVersionId","sourceCheckedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["id","competitionId","subject","startAt","endAt","allDay","dateMode","examStartAt","examEndAt","locationText","city","mapsUrl","venues","venuesNote","heldOnlyInCity","price","registrationInfo","registrationDeadlineAt","status","year","createdAt","updatedAt"],"additionalProperties":false,"description":"Издание в календарния фийд."},"description":"Календарен фийд от издания (с опционална родителска серия)."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Лимит на върнатите записи."},"nextCursor":{"nullable":true,"description":"Курсор за следваща страница (base64url) или null.","type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false,"description":"Информация за пагинация."}},"required":["data","pagination"],"additionalProperties":false,"description":"Календарен фийд от издания през всички серии."},"RegulationVersionWrite":{"type":"object","properties":{"validFromYear":{"type":"integer","minimum":1900,"maximum":2100,"description":"Начало на валидност (включително)."},"validToYear":{"description":"Край на валидност (включително). null/липсва = отворен край (текущ регламент).","nullable":true,"type":"integer","minimum":1900,"maximum":2100},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Етикет в UI, напр. „до 2016“ или „от 2017“."},"regulationsMarkdown":{"description":"Официален текст на регламента (Markdown). По подразбиране празен низ.","type":"string","maxLength":50000},"sourceUrl":{"description":"Wayback / официална страница (https).","nullable":true,"type":"string","format":"uri"},"sourceNote":{"description":"Бележка за източника (напр. липсващ параграф).","nullable":true,"type":"string","maxLength":2000},"status":{"description":"По подразбиране draft.","type":"string","enum":["draft","published"]}},"required":["validFromYear","title"],"additionalProperties":false,"description":"Създаване на версия на регламент за състезание."},"RegulationVersionPatch":{"type":"object","properties":{"validFromYear":{"type":"integer","minimum":1900,"maximum":2100,"description":"Календарна година (1900–2100)."},"validToYear":{"nullable":true,"type":"integer","minimum":1900,"maximum":2100,"description":"Календарна година (1900–2100)."},"title":{"type":"string","minLength":1,"maxLength":200},"regulationsMarkdown":{"type":"string","maxLength":50000},"sourceUrl":{"nullable":true,"type":"string","format":"uri","description":"HTTPS URL."},"sourceNote":{"nullable":true,"type":"string","maxLength":2000},"status":{"type":"string","enum":["draft","published"],"description":"draft = само админ; published = публичен календар."}},"additionalProperties":false,"description":"Частичен PATCH на версия на регламент."},"RegulationVersion":{"type":"object","properties":{"id":{"type":"string"},"eventSeriesId":{"type":"string"},"validFromYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"validToYear":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"regulationsMarkdown":{"type":"string"},"sourceUrl":{"nullable":true,"type":"string"},"sourceNote":{"nullable":true,"type":"string"},"status":{"type":"string","enum":["draft","published"],"description":"draft = само админ; published = публичен календар."},"createdAt":{"nullable":true,"type":"string"},"updatedAt":{"nullable":true,"type":"string"}},"required":["id","eventSeriesId","validFromYear","validToYear","title","regulationsMarkdown","sourceUrl","sourceNote","status","createdAt","updatedAt"],"additionalProperties":false},"RegulationVersionList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"eventSeriesId":{"type":"string"},"validFromYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"validToYear":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"regulationsMarkdown":{"type":"string"},"sourceUrl":{"nullable":true,"type":"string"},"sourceNote":{"nullable":true,"type":"string"},"status":{"type":"string","enum":["draft","published"],"description":"draft = само админ; published = публичен календар."},"createdAt":{"nullable":true,"type":"string"},"updatedAt":{"nullable":true,"type":"string"}},"required":["id","eventSeriesId","validFromYear","validToYear","title","regulationsMarkdown","sourceUrl","sourceNote","status","createdAt","updatedAt"],"additionalProperties":false},"description":"Версии на регламент."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Лимит на върнатите записи."},"nextCursor":{"nullable":true,"description":"Курсор за следваща страница (base64url) или null.","type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false,"description":"Информация за пагинация."}},"required":["data","pagination"],"additionalProperties":false,"description":"Списък версии на регламент за състезание."},"CollectionWrite":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"subtitle":{"nullable":true,"type":"string","maxLength":300},"descriptionMarkdown":{"type":"string","maxLength":50000},"kind":{"type":"string","enum":["assessment","competition","topic","curated","campaign"]},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"eventSeriesId":{"nullable":true,"type":"string","minLength":1},"groupBy":{"type":"object","properties":{"primary":{"type":"string","enum":["none","year","grade","stage","difficulty","manual"]},"secondary":{"nullable":true,"type":"string","enum":["none","year","grade","stage","difficulty","manual"]}},"required":["primary","secondary"],"additionalProperties":false},"defaultView":{"type":"string","enum":["list","grouped","matrix"]},"order":{"type":"integer","minimum":0,"maximum":100000}},"required":["title","kind","subject"],"additionalProperties":false},"CollectionPatch":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"slug":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"URL slug в kebab-case (напр. nacionalna-olimpiada-oblasten)."},"subtitle":{"nullable":true,"type":"string","maxLength":300},"descriptionMarkdown":{"type":"string","maxLength":50000},"kind":{"type":"string","enum":["assessment","competition","topic","curated","campaign"]},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"eventSeriesId":{"nullable":true,"type":"string","minLength":1},"groupBy":{"type":"object","properties":{"primary":{"type":"string","enum":["none","year","grade","stage","difficulty","manual"]},"secondary":{"nullable":true,"type":"string","enum":["none","year","grade","stage","difficulty","manual"]}},"required":["primary","secondary"],"additionalProperties":false},"defaultView":{"type":"string","enum":["list","grouped","matrix"]},"order":{"type":"integer","minimum":0,"maximum":100000}},"additionalProperties":false},"CollectionItemsBody":{"type":"object","properties":{"examIds":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1}},"dryRun":{"type":"boolean"}},"required":["examIds"],"additionalProperties":false},"CollectionItemPatch":{"type":"object","properties":{"label":{"nullable":true,"type":"string","maxLength":200},"order":{"type":"integer","minimum":0,"maximum":9007199254740991},"groupKey":{"nullable":true,"type":"string","maxLength":120}},"additionalProperties":false},"CollectionLinkBody":{"type":"object","properties":{"role":{"type":"string","enum":["preparation","archive","edition"]}},"required":["role"],"additionalProperties":false},"PublicDemoPatch":{"type":"object","properties":{"examId":{"nullable":true,"type":"string","minLength":1},"slug":{"type":"string","minLength":1}},"additionalProperties":false},"PublicDemoResponse":{"type":"object","properties":{"examId":{"nullable":true,"type":"string"},"updatedAt":{"nullable":true,"type":"string"},"updatedBy":{"nullable":true,"type":"string"},"exam":{"nullable":true},"action":{"type":"string","enum":["updated"]}},"required":["examId","updatedAt","updatedBy"],"additionalProperties":false},"ExamTaxonomyPatch":{"type":"object","properties":{"title":{"nullable":true,"type":"string","maxLength":300},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]},"officiality":{"type":"string","enum":["official","authored"]},"year":{"nullable":true,"type":"integer","minimum":1900,"maximum":2100},"academicYear":{"nullable":true,"type":"string","pattern":"^\\d{4}\\/\\d{4}$"},"eventSeriesId":{"nullable":true,"type":"string","minLength":1},"eventOccurrenceId":{"nullable":true,"type":"string","minLength":1},"regulationVersionId":{"description":"Версия на регламента (под eventSeries). Ако липсва при зададени eventSeriesId+year — резолвва се автоматично.","nullable":true,"type":"string","minLength":1},"stageKey":{"nullable":true,"type":"string","maxLength":80},"variant":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string","maxLength":80},"grade":{"type":"integer","minimum":1,"maximum":12,"description":"Клас (1–12)."},"applicability":{"maxItems":24,"type":"array","items":{"type":"object","properties":{"grade":{"type":"integer","minimum":1,"maximum":12,"description":"Клас (1–12)."},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"slug":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}},"additionalProperties":false},"ExamBulkTaxonomy":{"type":"object","properties":{"examIds":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1}},"patch":{"type":"object","properties":{"title":{"nullable":true,"type":"string","maxLength":300},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]},"officiality":{"type":"string","enum":["official","authored"]},"year":{"nullable":true,"type":"integer","minimum":1900,"maximum":2100},"academicYear":{"nullable":true,"type":"string","pattern":"^\\d{4}\\/\\d{4}$"},"eventSeriesId":{"nullable":true,"type":"string","minLength":1},"eventOccurrenceId":{"nullable":true,"type":"string","minLength":1},"regulationVersionId":{"description":"Версия на регламента (под eventSeries). Ако липсва при зададени eventSeriesId+year — резолвва се автоматично.","nullable":true,"type":"string","minLength":1},"stageKey":{"nullable":true,"type":"string","maxLength":80},"variant":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string","maxLength":80},"grade":{"type":"integer","minimum":1,"maximum":12,"description":"Клас (1–12)."},"applicability":{"maxItems":24,"type":"array","items":{"type":"object","properties":{"grade":{"type":"integer","minimum":1,"maximum":12,"description":"Клас (1–12)."},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"slug":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}},"additionalProperties":false},"dryRun":{"type":"boolean"}},"required":["examIds","patch"],"additionalProperties":false},"ExamBulkStructure":{"type":"object","properties":{"examIds":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1},"description":"До 100 Firestore exam id-та. Дубликатите се махат."},"patch":{"type":"object","properties":{"grade":{"description":"Клас на теста (1–12).","type":"integer","minimum":1,"maximum":12},"title":{"description":"Заглавие на теста.","nullable":true,"type":"string","maxLength":300},"subject":{"description":"Предмет (mathematics | bulgarian). Writable след upload.","type":"string","enum":["mathematics","bulgarian"]},"difficulty":{"description":"Трудност 1–5; null изчиства.","nullable":true,"type":"integer","minimum":1,"maximum":5},"questionPages":{"description":"Страници с въпроси (роли в PDF).","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"answerKeyPages":{"description":"Страници с ключ за оценяване.","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"solutionPages":{"description":"Страници с пълни решения.","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"structureTests":{"description":"При split PDF — метаданни по под-тест (title, startPage, page ranges).","maxItems":24,"type":"array","items":{"type":"object","additionalProperties":{}}},"applyPoints":{"description":"true = презаписва points на всички задачи според pointRules/defaultPoints. Ползвай след като задачите вече съществуват.","type":"boolean"},"applyAnswerKey":{"description":"true = overwrite на correctAnswer/correctOptionIndex от answerKeyText. Default false.","type":"boolean"},"skipLocked":{"description":"Само с applyAnswerKey: задачи с ръчно заключен отговор (humanLocks.answer) са пропускани. false/липсва + има заключени → 409 HUMAN_LOCKED. true → прилага само на незаключените и връща skippedHumanLocked.","type":"boolean"},"confirm":{"description":"Токен при published exam (двустъпков confirm).","type":"string","minLength":1},"fullSolutionDefaults":{"description":"Defaults for new multiline questions: solutionRequired, solutionPhotoUpload (off|optional|required, default optional), maxSolutionPhotos (1–5, default 1), scoring.mode (all_or_nothing|partial), scoring.answerOnlyPoints, scoring.rubric[{label,points}], scoring.allowManualPoints, scoring.step, solutionHintText. null clears. Point caps are checked when a question is saved, not here.","nullable":true,"type":"object","properties":{"solutionRequired":{"type":"boolean"},"solutionPhotoUpload":{"type":"string","enum":["off","optional","required"]},"maxSolutionPhotos":{"type":"integer","minimum":1,"maximum":5},"scoring":{"type":"object","properties":{"mode":{"type":"string","enum":["all_or_nothing","partial"]},"answerOnlyPoints":{"type":"number","minimum":0,"maximum":1000},"rubric":{"maxItems":12,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":200},"points":{"type":"number","minimum":0,"maximum":1000}},"required":["label","points"],"additionalProperties":false}},"allowManualPoints":{"type":"boolean"},"step":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":100}},"additionalProperties":false},"solutionHintText":{"nullable":true,"type":"string","maxLength":2000}},"additionalProperties":false},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300,"description":"Продължителност на опита в минути (1–300). При качване без поле: 40. Не се извлича от PDF."},"wrongAnswerPoints":{"description":"Точки при напълно грешен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"blankAnswerPoints":{"description":"Точки при празен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"startingPoints":{"description":"Стартови точки към сбора на опита (0…500). Default 0.","type":"integer","minimum":0,"maximum":500},"defaultPoints":{"description":"Равномерни точки на задача, ако pointRules е празен. null = без.","nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"description":"Правила точки по номер. Compact „1-18:1; 19-20:2“ или масив {from,to,points}.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":80,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начален номер на задача (включително)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Краен номер на задача (включително)."},"points":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Точки за задачите в диапазона."}},"required":["from","to","points"],"additionalProperties":false}}]},"gradeRules":{"description":"Скала 2–6. Compact „0-10:2; 11-15:3; …“ или масив {from,to,grade}. Празно = без скала.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":24,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Долен праг на сбор точки (включително)."},"to":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Горен праг на сбор точки (включително)."},"grade":{"type":"integer","minimum":2,"maximum":6,"description":"Оценка 2–6."}},"required":["from","to","grade"],"additionalProperties":false}}]},"answerKeyText":{"description":"Ключ с отговори: „1 Б; 2 Г; 15 189“. Празен string или null изчиства.","nullable":true,"type":"string","maxLength":20000},"mcOtherAnswerMode":{"description":"Режим на MC „Друго“ за целия тест: select_only = само маркиране; requires_text = изисква свободен текст. Default requires_text. Take-test чете exams/{id}.mcOtherAnswerMode, не structureTests.","type":"string","enum":["select_only","requires_text"]},"mcOptionsLayout":{"description":"Подредба на MC опциите: stacked = по един на ред; compact = компактен ред. Default stacked.","type":"string","enum":["stacked","compact"]},"mcAnswerLabelScheme":{"description":"Етикети на MC отговорите: cyrillic_upper (default А Б В…), cyrillic_lower, latin_lower, latin_upper, numeric, custom. При custom подай mcAnswerLabels.","type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"]},"mcAnswerLabels":{"description":"Собствени етикети (1–12, без дубликати) само при mcAnswerLabelScheme=custom. При друг scheme се изчистват.","minItems":1,"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":8}},"notesEnabled":{"description":"Бележки при решаване. Default true. При grade 0 (предучилищна) винаги false.","type":"boolean"}},"additionalProperties":false,"description":"Същият PATCH като /exams/:id/structure. Полето confirm се игнорира — публикуван тест връща confirmation_required за това id; потвърди с update_exam_structure."},"dryRun":{"description":"true = само проверка, че тестовете съществуват; без запис.","type":"boolean"}},"required":["examIds","patch"],"additionalProperties":false,"description":"Масов structure/scoring PATCH (mcOtherAnswerMode, таймер, точки, ключ). Max 100. Scope exams:write."},"ExamBulkStructureResult":{"type":"object","properties":{"dryRun":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"examId":{"type":"string"},"ok":{"type":"boolean"},"dryRun":{"type":"boolean"},"exam":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Каталожно резюме (GET /v1/exams, GET /v1/exams/{id}, MCP get_exam). Без въпроси, ключове и без processing.cost — цената е само в inspect.summary.cost."},"scoring":{"type":"object","properties":{"scoringPolicy":{"type":"object","properties":{"wrongAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"blankAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"startingPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["wrongAnswerPoints","blankAnswerPoints","startingPoints"],"additionalProperties":false,"description":"Точкуване при опит (не пипа точките по задачи)."},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300},"scoringLocked":{"type":"boolean","description":"true = structure pass не презаписва pointRules/gradeRules/defaultPoints от PDF."},"defaultPoints":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начален номер на задача (включително)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Краен номер на задача (включително)."},"points":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Точки за задачите в диапазона."}},"required":["from","to","points"],"additionalProperties":false}},"pointRulesText":{"type":"string","description":"Compact: 1-18:1; 19-20:2"},"gradeRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Долен праг на сбор точки (включително)."},"to":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Горен праг на сбор точки (включително)."},"grade":{"type":"integer","minimum":2,"maximum":6,"description":"Оценка 2–6."}},"required":["from","to","grade"],"additionalProperties":false}},"gradeRulesText":{"type":"string","description":"Compact: 0-10:2; 11-15:3"},"answerKeyText":{"nullable":true,"description":"Ключ: 1 Б; 2 Г; 15 189","type":"string"},"mcOtherAnswerMode":{"type":"string","enum":["select_only","requires_text"],"description":"Режим на MC „Друго“ (exam doc). Default requires_text."},"mcOptionsLayout":{"type":"string","enum":["stacked","compact"],"description":"Подредба на MC опциите. Default stacked."},"mcAnswerLabelScheme":{"type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"],"description":"Етикети на MC отговорите. Default cyrillic_upper."},"mcAnswerLabels":{"type":"array","items":{"type":"string"},"description":"Собствени етикети при scheme=custom; иначе []."},"notesEnabled":{"type":"boolean","description":"Бележки при решаване. Preschool (grade 0) → false."},"difficulty":{"nullable":true,"description":"Трудност 1–5; null = не е зададена.","type":"integer","minimum":1,"maximum":5},"subject":{"nullable":true,"description":"Предмет; null ако липсва в doc.","type":"string","enum":["mathematics","bulgarian"]}},"required":["scoringPolicy","timeLimitMinutes","scoringLocked","defaultPoints","pointRules","pointRulesText","gradeRules","gradeRulesText","answerKeyText","mcOtherAnswerMode","mcOptionsLayout","mcAnswerLabelScheme","mcAnswerLabels","notesEnabled","difficulty","subject"],"additionalProperties":false,"description":"Точкуване, таймер, правила, ключ, MC „Друго“/layout/етикети, бележки, трудност, предмет (inspect)."},"applied":{"type":"object","properties":{"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"answerKey":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["points","answerKey"],"additionalProperties":false},"confirmation":{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["examId","ok","dryRun"],"additionalProperties":false,"description":"Резултат за един тест в bulk structure PATCH."}}},"required":["dryRun","results"],"additionalProperties":false,"description":"POST /v1/exams/bulk/structure — по един ред на examId."},"ExamUpload":{"type":"object","properties":{"grade":{"type":"integer","minimum":1,"maximum":12,"description":"Клас (1–12)."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет: mathematics (математика) или bulgarian (български език)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri"}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1},"fileName":{"type":"string","minLength":1,"maxLength":255}},"required":["kind","base64"],"additionalProperties":false}],"description":"Източник на файл: url (препоръчително) или base64 (до 8 MB)."},"answerKey":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri"}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1},"fileName":{"type":"string","minLength":1,"maxLength":255}},"required":["kind","base64"],"additionalProperties":false}],"description":"Източник на файл: url (препоръчително) или base64 (до 8 MB)."},"collectionId":{"type":"string","minLength":1},"pipeline":{"description":"Per-exam pipeline overrides при качване (merge с глобален config).","type":"object","properties":{"stopAfter":{"nullable":true,"description":"Спира pipeline след дадена стъпка (за итерация). null = без спиране (до край или глобален stopAfter). structure = след JSON структура; bounds = след локализация; extract / improveMarkdown / taskFamily / classify = съответната стъпка.","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"boundsSnap":{"description":"Snap за problem bounds.","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"figuresSnap":{"description":"Snap за figure bounds (отделно от problem).","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"description":"Включва Document AI Layout Parser за bounds pre-pass.","type":"boolean"},"fallbackToLlm":{"description":"При неуспех на Document AI — fallback към LLM bounds/figures.","type":"boolean"}},"additionalProperties":false,"description":"Document AI hybrid настройки."},"boundsVerifyEnabled":{"description":"Overlay review + една корекционна рунда след bounds.","type":"boolean"},"boundsReconcileEnabled":{"description":"Остави false (подразбиране; липсващо поле също е false). Включи само в редкия случай: една колона и задача, която продължава на следващата страница. При две колони задължително false — сливането залепва колоните.","type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"description":"Почиствай всеки нов чертеж при изрязване (по подразбиране true).","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"transparentBackground":{"description":"Прозрачен фон (по подразбиране false).","type":"boolean"},"transparentBackgroundWholeImage":{"description":"С transparentBackground: целият бял фон прозрачен, включително заграден от линиите (по подразбиране false).","type":"boolean"}},"additionalProperties":false,"description":"Автоматично „Почисти“ на всеки нов чертеж (Граници → изрезка, Коригирай, +2px). Суровата изрезка се пази като оригинал."},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"description":"false = пропуска Markdown (improve) за този run; Classify/Answer ползват extract текста.","type":"boolean"},"taskFamily":{"description":"false = пропуска съвпадение със семейство задача (numberSequence и др.).","type":"boolean"},"classify":{"description":"false = пропуска класификация по таксономия; Answer може да върви.","type":"boolean"},"answer":{"description":"false = пропуска solve/escalate (най-скъпата стъпка).","type":"boolean"},"hint":{"description":"false = пропуска post-solve Hint; независимо от Answer.","type":"boolean"},"mcOnDrawing":{"description":"„Отговори върху чертежа“ (по подразбиране false): MC вариантите са фигури с букви A…E / А…Д в чертежа — AI намира зоните и детето докосва фигурата; редът бутони се скрива.","type":"boolean"}},"additionalProperties":false,"description":"Независими ключове за Markdown/Семейство/Classify/Answer/Hint. Липсващо поле = наследява глобалния config (default true). Не замества stopAfter (който реже суфикса)."},"prompts":{"type":"object","properties":{"structure":{"description":"Промптове за стъпка structure.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"bounds":{"description":"Промптове за стъпка bounds.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"figures":{"description":"Промптове за стъпка figures.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"boundsVerify":{"description":"Промптове за стъпка boundsVerify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extract":{"description":"Промптове за стъпка extract.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"improveMarkdown":{"description":"Промптове за стъпка improveMarkdown.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"taskFamily":{"description":"Промптове за стъпка taskFamily (matcher).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"classify":{"description":"Промптове за стъпка classify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"answer":{"description":"Промптове за стъпка answer.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hint":{"description":"Промптове за стъпка hint.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"grading":{"description":"Промптове за стъпка grading.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKey":{"description":"Промптове за стъпка extractAnswerKey.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"description":"System за ключ от подробни решения. Празен user ползва extractAnswerKey.user.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"solvePart":{"description":"Промптове за solve на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hintPart":{"description":"Промптове за hint на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"docAiClassify":{"description":"Промптове за Document AI classify ({{pageNumber}}, {{blocksJson}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"mcOnDrawing":{"description":"Промптове за „Отговори върху чертежа“ (user шаблон: {{problem}}, {{options}}, {{drawingCount}}, {{pdfLabels}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false}},"additionalProperties":false,"description":"Частични prompt overrides по pipeline стъпка."},"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"additionalProperties":false,"description":"LLM доставчик по pipeline стъпка (глобален config)."},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false,"description":"Име на модел по pipeline стъпка (глобален config)."},"reasoningEffort":{"type":"object","properties":{"structure":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"bounds":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"figures":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"boundsVerify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extract":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"improveMarkdown":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"classify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerBase":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerMid":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerSmart":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answer":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerEasy":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"hint":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"grading":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extractAnswerKey":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"mcOnDrawing":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]}},"additionalProperties":false,"description":"reasoning_effort по стъпка (OpenAI)."},"reasoningMode":{"type":"object","properties":{"structure":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"bounds":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"figures":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"boundsVerify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extract":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"improveMarkdown":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"classify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerBase":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerMid":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerSmart":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answer":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerEasy":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"hint":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"grading":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extractAnswerKey":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"mcOnDrawing":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."}},"additionalProperties":false,"description":"Per-step reasoning.mode (pro само за OpenAI Astra/Sol)."},"temperature":{"description":"Температура за solve слотове. null = не се праща към API.","type":"object","properties":{"answerBase":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerMid":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerSmart":{"nullable":true,"type":"number","minimum":0,"maximum":2}},"additionalProperties":false},"solveEscalate":{"description":"Каскада base → mid → smart при разминаване с ключа.","type":"object","properties":{"maxMidAttempts":{"description":"Бюджет mid опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50},"maxSmartAttempts":{"description":"Бюджет smart опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50}},"additionalProperties":false},"questionConcurrency":{"description":"Колко задачи в Pass 2 (extract → improve → solve → classify) да вървят паралелно (1–8). Default 1; parent scan = 3.","type":"integer","minimum":1,"maximum":8}},"additionalProperties":false},"title":{"nullable":true,"type":"string","maxLength":300},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]},"year":{"nullable":true,"type":"integer","minimum":1900,"maximum":2100},"officiality":{"type":"string","enum":["official","authored"]},"eventSeriesId":{"description":"Състезание (eventSeries) за каталог и резолв на регламент.","nullable":true,"type":"string","minLength":1},"regulationVersionId":{"description":"Изрична версия на регламента. Ако липсва при eventSeriesId+year — автоматичен резолв.","nullable":true,"type":"string","minLength":1},"idempotencyKey":{"type":"string","minLength":8,"maxLength":128},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300,"description":"Продължителност на опита в минути (1–300). При качване без поле: 40. Не се извлича от PDF."},"wrongAnswerPoints":{"description":"Точки при напълно грешен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"blankAnswerPoints":{"description":"Точки при празен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"startingPoints":{"description":"Стартови точки към сбора на опита (0…500). Default 0.","type":"integer","minimum":0,"maximum":500},"defaultPoints":{"description":"Равномерни точки на задача, ако pointRules е празен. null = без.","nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"description":"Правила точки по номер. Compact „1-18:1; 19-20:2“ или масив {from,to,points}.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":80,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начален номер на задача (включително)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Краен номер на задача (включително)."},"points":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Точки за задачите в диапазона."}},"required":["from","to","points"],"additionalProperties":false}}]},"gradeRules":{"description":"Скала 2–6. Compact „0-10:2; 11-15:3; …“ или масив {from,to,grade}. Празно = без скала.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":24,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Долен праг на сбор точки (включително)."},"to":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Горен праг на сбор точки (включително)."},"grade":{"type":"integer","minimum":2,"maximum":6,"description":"Оценка 2–6."}},"required":["from","to","grade"],"additionalProperties":false}}]},"answerKeyText":{"description":"Ключ с отговори: „1 Б; 2 Г; 15 189“. Празен string или null изчиства.","nullable":true,"type":"string","maxLength":20000},"mcOtherAnswerMode":{"description":"Режим на MC „Друго“ за целия тест: select_only = само маркиране; requires_text = изисква свободен текст. Default requires_text. Take-test чете exams/{id}.mcOtherAnswerMode, не structureTests.","type":"string","enum":["select_only","requires_text"]},"mcOptionsLayout":{"description":"Подредба на MC опциите: stacked = по един на ред; compact = компактен ред. Default stacked.","type":"string","enum":["stacked","compact"]},"mcAnswerLabelScheme":{"description":"Етикети на MC отговорите: cyrillic_upper (default А Б В…), cyrillic_lower, latin_lower, latin_upper, numeric, custom. При custom подай mcAnswerLabels.","type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"]},"mcAnswerLabels":{"description":"Собствени етикети (1–12, без дубликати) само при mcAnswerLabelScheme=custom. При друг scheme се изчистват.","minItems":1,"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":8}},"notesEnabled":{"description":"Бележки при решаване. Default true. При grade 0 (предучилищна) винаги false.","type":"boolean"}},"required":["grade","subject","source"],"additionalProperties":false,"description":"Качване на тест. Регламентът (timeLimitMinutes, pointRules, gradeRules, attempt knobs, answerKeyText, mcOtherAnswerMode, mcOptionsLayout) е опционален — липсващите полета остават default (40 мин или времето от регламента в PDF, нулеви knobs, празни правила, Друго=requires_text, layout=stacked). Markdown регламент на състезанието е отделен (regulationVersionId)."},"ExamPipelineConfigPatch":{"type":"object","properties":{"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"additionalProperties":false,"description":"LLM доставчик по pipeline стъпка (глобален config)."},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false,"description":"Име на модел по pipeline стъпка (глобален config)."},"stopAfter":{"nullable":true,"description":"Глобално спиране след стъпка. full = пълен pipeline до край (еквивалент на null). За upload/process overrides ползвай pipelineStopAfterSchema (без full).","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify","full"]},"boundsSnap":{"type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false,"description":"Настройки за content-aware snap на problem/figure bounds."},"figuresSnap":{"type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false,"description":"Настройки за content-aware snap на problem/figure bounds."},"documentAi":{"type":"object","properties":{"enabled":{"description":"Включва Document AI Layout Parser за bounds pre-pass.","type":"boolean"},"fallbackToLlm":{"description":"При неуспех на Document AI — fallback към LLM bounds/figures.","type":"boolean"}},"additionalProperties":false,"description":"Document AI hybrid настройки."},"boundsVerifyEnabled":{"type":"boolean"},"boundsReconcileEnabled":{"description":"Остави false (подразбиране; липсващо поле също е false). Включи само в редкия случай: една колона и задача, която продължава на следващата страница. При две колони задължително false — сливането залепва колоните.","type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"description":"Почиствай всеки нов чертеж при изрязване (по подразбиране true).","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"transparentBackground":{"description":"Прозрачен фон (по подразбиране false).","type":"boolean"},"transparentBackgroundWholeImage":{"description":"С transparentBackground: целият бял фон прозрачен, включително заграден от линиите (по подразбиране false).","type":"boolean"}},"additionalProperties":false,"description":"Автоматично „Почисти“ на всеки нов чертеж (Граници → изрезка, Коригирай, +2px). Суровата изрезка се пази като оригинал."},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"description":"false = пропуска Markdown (improve) за този run; Classify/Answer ползват extract текста.","type":"boolean"},"taskFamily":{"description":"false = пропуска съвпадение със семейство задача (numberSequence и др.).","type":"boolean"},"classify":{"description":"false = пропуска класификация по таксономия; Answer може да върви.","type":"boolean"},"answer":{"description":"false = пропуска solve/escalate (най-скъпата стъпка).","type":"boolean"},"hint":{"description":"false = пропуска post-solve Hint; независимо от Answer.","type":"boolean"},"mcOnDrawing":{"description":"„Отговори върху чертежа“ (по подразбиране false): MC вариантите са фигури с букви A…E / А…Д в чертежа — AI намира зоните и детето докосва фигурата; редът бутони се скрива.","type":"boolean"}},"additionalProperties":false,"description":"Независими ключове за Markdown/Семейство/Classify/Answer/Hint. Липсващо поле = наследява глобалния config (default true). Не замества stopAfter (който реже суфикса)."},"prompts":{"type":"object","properties":{"structure":{"description":"Промптове за стъпка structure.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"bounds":{"description":"Промптове за стъпка bounds.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"figures":{"description":"Промптове за стъпка figures.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"boundsVerify":{"description":"Промптове за стъпка boundsVerify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extract":{"description":"Промптове за стъпка extract.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"improveMarkdown":{"description":"Промптове за стъпка improveMarkdown.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"taskFamily":{"description":"Промптове за стъпка taskFamily (matcher).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"classify":{"description":"Промптове за стъпка classify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"answer":{"description":"Промптове за стъпка answer.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hint":{"description":"Промптове за стъпка hint.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"grading":{"description":"Промптове за стъпка grading.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKey":{"description":"Промптове за стъпка extractAnswerKey.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"description":"System за ключ от подробни решения. Празен user ползва extractAnswerKey.user.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"solvePart":{"description":"Промптове за solve на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hintPart":{"description":"Промптове за hint на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"docAiClassify":{"description":"Промптове за Document AI classify ({{pageNumber}}, {{blocksJson}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"mcOnDrawing":{"description":"Промптове за „Отговори върху чертежа“ (user шаблон: {{problem}}, {{options}}, {{drawingCount}}, {{pdfLabels}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false}},"additionalProperties":false,"description":"Частични prompt overrides по pipeline стъпка."},"fullSolutionGrading":{"description":"Separate prompt and main/fallback models for grading a full written solution (text and photos). Empty system or user leaves the grade preliminary. Does not replace prompts.grading.","type":"object","properties":{"system":{"type":"string","maxLength":20000},"user":{"type":"string","maxLength":20000},"provider":{"type":"string","enum":["openai","grok","gemini","claude","inception"]},"model":{"type":"string","minLength":1,"maxLength":120},"fallbackProvider":{"type":"string","enum":["openai","grok","gemini","claude","inception"]},"fallbackModel":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false},"typesafeClassifyPrompts":{"type":"object","properties":{"themeRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"rootRetry":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"structureInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatSlot2PlusInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."}},"additionalProperties":false,"description":"Jev classify choice instructions (classify provider typesafe)."},"typesafeClassifyFlow":{"type":"string","enum":["v1","v2","v3"],"description":"v1 legacy drill; v2 B+ drill; v3 S3 structure-first theme."},"structureOptions":{"maxItems":32,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":40},"label":{"type":"string","minLength":1,"maxLength":200},"criterion":{"type":"string","minLength":1,"maxLength":800},"opens":{"maxItems":64,"type":"array","items":{"type":"string","minLength":1}},"hideForGrades":{"maxItems":12,"type":"array","items":{"type":"integer","minimum":1,"maximum":12}}},"required":["key","label","criterion","opens","hideForGrades"],"additionalProperties":false}},"reasoningEffort":{"type":"object","properties":{"structure":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"bounds":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"figures":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"boundsVerify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extract":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"improveMarkdown":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"classify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerBase":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerMid":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerSmart":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answer":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerEasy":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"hint":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"grading":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extractAnswerKey":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"mcOnDrawing":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]}},"additionalProperties":false,"description":"reasoning_effort по стъпка (OpenAI)."},"reasoningMode":{"type":"object","properties":{"structure":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"bounds":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"figures":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"boundsVerify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extract":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"improveMarkdown":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"classify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerBase":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerMid":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerSmart":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answer":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerEasy":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"hint":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"grading":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extractAnswerKey":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"mcOnDrawing":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."}},"additionalProperties":false,"description":"Per-step reasoning.mode (pro само за OpenAI Astra/Sol)."},"temperature":{"type":"object","properties":{"answerBase":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerMid":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerSmart":{"nullable":true,"type":"number","minimum":0,"maximum":2}},"additionalProperties":false},"solveEscalate":{"type":"object","properties":{"maxMidAttempts":{"type":"integer","minimum":0,"maximum":50},"maxSmartAttempts":{"type":"integer","minimum":0,"maximum":50}},"additionalProperties":false},"questionConcurrency":{"description":"Глобален default за Pass 2 concurrency (1–8).","type":"integer","minimum":1,"maximum":8},"confirm":{"description":"Токен от предишен отговор confirmation_required (глобален config write).","type":"string","minLength":1}},"additionalProperties":false,"description":"PATCH за config/examPipeline. Изисква pipeline:write и двустъпков confirm."},"ExamProcess":{"type":"object","properties":{"mode":{"type":"string","enum":["resume","fullRestart"],"description":"resume = продължи от текущата стъпка; fullRestart = нулирай и пусни отначало."},"pipeline":{"type":"object","properties":{"stopAfter":{"nullable":true,"description":"Спира pipeline след дадена стъпка (за итерация). null = без спиране (до край или глобален stopAfter). structure = след JSON структура; bounds = след локализация; extract / improveMarkdown / taskFamily / classify = съответната стъпка.","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"boundsSnap":{"description":"Snap за problem bounds.","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"figuresSnap":{"description":"Snap за figure bounds (отделно от problem).","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"description":"Включва Document AI Layout Parser за bounds pre-pass.","type":"boolean"},"fallbackToLlm":{"description":"При неуспех на Document AI — fallback към LLM bounds/figures.","type":"boolean"}},"additionalProperties":false,"description":"Document AI hybrid настройки."},"boundsVerifyEnabled":{"description":"Overlay review + една корекционна рунда след bounds.","type":"boolean"},"boundsReconcileEnabled":{"description":"Остави false (подразбиране; липсващо поле също е false). Включи само в редкия случай: една колона и задача, която продължава на следващата страница. При две колони задължително false — сливането залепва колоните.","type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"description":"Почиствай всеки нов чертеж при изрязване (по подразбиране true).","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"transparentBackground":{"description":"Прозрачен фон (по подразбиране false).","type":"boolean"},"transparentBackgroundWholeImage":{"description":"С transparentBackground: целият бял фон прозрачен, включително заграден от линиите (по подразбиране false).","type":"boolean"}},"additionalProperties":false,"description":"Автоматично „Почисти“ на всеки нов чертеж (Граници → изрезка, Коригирай, +2px). Суровата изрезка се пази като оригинал."},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"description":"false = пропуска Markdown (improve) за този run; Classify/Answer ползват extract текста.","type":"boolean"},"taskFamily":{"description":"false = пропуска съвпадение със семейство задача (numberSequence и др.).","type":"boolean"},"classify":{"description":"false = пропуска класификация по таксономия; Answer може да върви.","type":"boolean"},"answer":{"description":"false = пропуска solve/escalate (най-скъпата стъпка).","type":"boolean"},"hint":{"description":"false = пропуска post-solve Hint; независимо от Answer.","type":"boolean"},"mcOnDrawing":{"description":"„Отговори върху чертежа“ (по подразбиране false): MC вариантите са фигури с букви A…E / А…Д в чертежа — AI намира зоните и детето докосва фигурата; редът бутони се скрива.","type":"boolean"}},"additionalProperties":false,"description":"Независими ключове за Markdown/Семейство/Classify/Answer/Hint. Липсващо поле = наследява глобалния config (default true). Не замества stopAfter (който реже суфикса)."},"prompts":{"type":"object","properties":{"structure":{"description":"Промптове за стъпка structure.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"bounds":{"description":"Промптове за стъпка bounds.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"figures":{"description":"Промптове за стъпка figures.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"boundsVerify":{"description":"Промптове за стъпка boundsVerify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extract":{"description":"Промптове за стъпка extract.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"improveMarkdown":{"description":"Промптове за стъпка improveMarkdown.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"taskFamily":{"description":"Промптове за стъпка taskFamily (matcher).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"classify":{"description":"Промптове за стъпка classify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"answer":{"description":"Промптове за стъпка answer.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hint":{"description":"Промптове за стъпка hint.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"grading":{"description":"Промптове за стъпка grading.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKey":{"description":"Промптове за стъпка extractAnswerKey.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"description":"System за ключ от подробни решения. Празен user ползва extractAnswerKey.user.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"solvePart":{"description":"Промптове за solve на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hintPart":{"description":"Промптове за hint на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"docAiClassify":{"description":"Промптове за Document AI classify ({{pageNumber}}, {{blocksJson}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"mcOnDrawing":{"description":"Промптове за „Отговори върху чертежа“ (user шаблон: {{problem}}, {{options}}, {{drawingCount}}, {{pdfLabels}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false}},"additionalProperties":false,"description":"Частични prompt overrides по pipeline стъпка."},"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"additionalProperties":false,"description":"LLM доставчик по pipeline стъпка (глобален config)."},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false,"description":"Име на модел по pipeline стъпка (глобален config)."},"reasoningEffort":{"type":"object","properties":{"structure":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"bounds":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"figures":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"boundsVerify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extract":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"improveMarkdown":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"classify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerBase":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerMid":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerSmart":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answer":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerEasy":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"hint":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"grading":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extractAnswerKey":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"mcOnDrawing":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]}},"additionalProperties":false,"description":"reasoning_effort по стъпка (OpenAI)."},"reasoningMode":{"type":"object","properties":{"structure":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"bounds":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"figures":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"boundsVerify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extract":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"improveMarkdown":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"classify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerBase":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerMid":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerSmart":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answer":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerEasy":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"hint":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"grading":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extractAnswerKey":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"mcOnDrawing":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."}},"additionalProperties":false,"description":"Per-step reasoning.mode (pro само за OpenAI Astra/Sol)."},"temperature":{"description":"Температура за solve слотове. null = не се праща към API.","type":"object","properties":{"answerBase":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerMid":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerSmart":{"nullable":true,"type":"number","minimum":0,"maximum":2}},"additionalProperties":false},"solveEscalate":{"description":"Каскада base → mid → smart при разминаване с ключа.","type":"object","properties":{"maxMidAttempts":{"description":"Бюджет mid опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50},"maxSmartAttempts":{"description":"Бюджет smart опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50}},"additionalProperties":false},"questionConcurrency":{"description":"Колко задачи в Pass 2 (extract → improve → solve → classify) да вървят паралелно (1–8). Default 1; parent scan = 3.","type":"integer","minimum":1,"maximum":8}},"additionalProperties":false,"description":"Per-exam pipeline overrides (upload, process, reprocess). Merge с вече записани overrides и глобален config/examPipeline."},"stopAfter":{"description":"Кратък alias за pipeline.stopAfter.","nullable":true,"type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"confirm":{"description":"Токен при published exam (двустъпков confirm).","type":"string","minLength":1},"skipLocked":{"description":"Задачи с ръчни редакции (humanLocks) са заключени за pipeline. false/липсва + има заключени → 409 HUMAN_LOCKED. true → pipeline тръгва и пропуска заключените вътрешно (не спира изцяло). Проверен от човек тест (humanReview.status=reviewed) винаги → 409, дори с skipLocked.","type":"boolean"}},"required":["mode"],"additionalProperties":false,"description":"Enqueue process — пише processing.apiCommand; LLM се изпълнява в processExamOnUpload."},"ExamReprocess":{"type":"object","properties":{"stage":{"type":"string","enum":["extract","improveMarkdown","taskFamily","classify","answer","mcOnDrawing"],"description":"Коя стъпка да се пусне отново за избраните въпроси."},"questionIds":{"description":"Подмножество question IDs; липсва = всички въпроси на теста.","maxItems":200,"type":"array","items":{"type":"string","minLength":1}},"pipeline":{"type":"object","properties":{"stopAfter":{"nullable":true,"description":"Спира pipeline след дадена стъпка (за итерация). null = без спиране (до край или глобален stopAfter). structure = след JSON структура; bounds = след локализация; extract / improveMarkdown / taskFamily / classify = съответната стъпка.","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"boundsSnap":{"description":"Snap за problem bounds.","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"figuresSnap":{"description":"Snap за figure bounds (отделно от problem).","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"description":"Включва Document AI Layout Parser за bounds pre-pass.","type":"boolean"},"fallbackToLlm":{"description":"При неуспех на Document AI — fallback към LLM bounds/figures.","type":"boolean"}},"additionalProperties":false,"description":"Document AI hybrid настройки."},"boundsVerifyEnabled":{"description":"Overlay review + една корекционна рунда след bounds.","type":"boolean"},"boundsReconcileEnabled":{"description":"Остави false (подразбиране; липсващо поле също е false). Включи само в редкия случай: една колона и задача, която продължава на следващата страница. При две колони задължително false — сливането залепва колоните.","type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"description":"Почиствай всеки нов чертеж при изрязване (по подразбиране true).","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"transparentBackground":{"description":"Прозрачен фон (по подразбиране false).","type":"boolean"},"transparentBackgroundWholeImage":{"description":"С transparentBackground: целият бял фон прозрачен, включително заграден от линиите (по подразбиране false).","type":"boolean"}},"additionalProperties":false,"description":"Автоматично „Почисти“ на всеки нов чертеж (Граници → изрезка, Коригирай, +2px). Суровата изрезка се пази като оригинал."},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"description":"false = пропуска Markdown (improve) за този run; Classify/Answer ползват extract текста.","type":"boolean"},"taskFamily":{"description":"false = пропуска съвпадение със семейство задача (numberSequence и др.).","type":"boolean"},"classify":{"description":"false = пропуска класификация по таксономия; Answer може да върви.","type":"boolean"},"answer":{"description":"false = пропуска solve/escalate (най-скъпата стъпка).","type":"boolean"},"hint":{"description":"false = пропуска post-solve Hint; независимо от Answer.","type":"boolean"},"mcOnDrawing":{"description":"„Отговори върху чертежа“ (по подразбиране false): MC вариантите са фигури с букви A…E / А…Д в чертежа — AI намира зоните и детето докосва фигурата; редът бутони се скрива.","type":"boolean"}},"additionalProperties":false,"description":"Независими ключове за Markdown/Семейство/Classify/Answer/Hint. Липсващо поле = наследява глобалния config (default true). Не замества stopAfter (който реже суфикса)."},"prompts":{"type":"object","properties":{"structure":{"description":"Промптове за стъпка structure.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"bounds":{"description":"Промптове за стъпка bounds.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"figures":{"description":"Промптове за стъпка figures.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"boundsVerify":{"description":"Промптове за стъпка boundsVerify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extract":{"description":"Промптове за стъпка extract.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"improveMarkdown":{"description":"Промптове за стъпка improveMarkdown.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"taskFamily":{"description":"Промптове за стъпка taskFamily (matcher).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"classify":{"description":"Промптове за стъпка classify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"answer":{"description":"Промптове за стъпка answer.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hint":{"description":"Промптове за стъпка hint.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"grading":{"description":"Промптове за стъпка grading.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKey":{"description":"Промптове за стъпка extractAnswerKey.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"description":"System за ключ от подробни решения. Празен user ползва extractAnswerKey.user.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"solvePart":{"description":"Промптове за solve на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hintPart":{"description":"Промптове за hint на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"docAiClassify":{"description":"Промптове за Document AI classify ({{pageNumber}}, {{blocksJson}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"mcOnDrawing":{"description":"Промптове за „Отговори върху чертежа“ (user шаблон: {{problem}}, {{options}}, {{drawingCount}}, {{pdfLabels}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false}},"additionalProperties":false,"description":"Частични prompt overrides по pipeline стъпка."},"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"additionalProperties":false,"description":"LLM доставчик по pipeline стъпка (глобален config)."},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false,"description":"Име на модел по pipeline стъпка (глобален config)."},"reasoningEffort":{"type":"object","properties":{"structure":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"bounds":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"figures":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"boundsVerify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extract":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"improveMarkdown":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"classify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerBase":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerMid":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerSmart":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answer":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerEasy":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"hint":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"grading":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extractAnswerKey":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"mcOnDrawing":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]}},"additionalProperties":false,"description":"reasoning_effort по стъпка (OpenAI)."},"reasoningMode":{"type":"object","properties":{"structure":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"bounds":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"figures":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"boundsVerify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extract":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"improveMarkdown":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"classify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerBase":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerMid":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerSmart":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answer":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerEasy":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"hint":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"grading":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extractAnswerKey":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"mcOnDrawing":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."}},"additionalProperties":false,"description":"Per-step reasoning.mode (pro само за OpenAI Astra/Sol)."},"temperature":{"description":"Температура за solve слотове. null = не се праща към API.","type":"object","properties":{"answerBase":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerMid":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerSmart":{"nullable":true,"type":"number","minimum":0,"maximum":2}},"additionalProperties":false},"solveEscalate":{"description":"Каскада base → mid → smart при разминаване с ключа.","type":"object","properties":{"maxMidAttempts":{"description":"Бюджет mid опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50},"maxSmartAttempts":{"description":"Бюджет smart опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50}},"additionalProperties":false},"questionConcurrency":{"description":"Колко задачи в Pass 2 (extract → improve → solve → classify) да вървят паралелно (1–8). Default 1; parent scan = 3.","type":"integer","minimum":1,"maximum":8}},"additionalProperties":false,"description":"Per-exam pipeline overrides (upload, process, reprocess). Merge с вече записани overrides и глобален config/examPipeline."},"provider":{"description":"Еднократен LLM доставчик за reprocess (не се пази в config).","type":"string","enum":["openai","grok","gemini","claude","inception"]},"model":{"description":"Еднократен модел за reprocess (не се пази в config).","type":"string","minLength":1,"maxLength":128},"reasoningEffort":{"description":"Еднократен reasoning effort за reprocess (none|low|medium|high). Claude → output_config.effort. Не се пази в pipelineOverrides.","nullable":true,"type":"string","enum":["none","low","medium","high"]},"reasoningMode":{"description":"Еднократен OpenAI reasoning.mode (standard|pro). pro изисква Responses API (Astra/Sol). Claude/Grok → 400. Не се пази в pipelineOverrides.","type":"string","enum":["standard","pro"]},"confirm":{"description":"Токен при published exam (двустъпков confirm).","type":"string","minLength":1},"skipLocked":{"description":"Задачи с ръчни редакции (humanLocks) на засегнатите от тази stage полета са заключени. false/липсва + има заключени сред избраните → 409 HUMAN_LOCKED със списък. true → пуска само незаключените и връща skippedHumanLocked.","type":"boolean"}},"required":["stage"],"additionalProperties":false,"description":"Enqueue reprocess на въпроси — stage extract, improveMarkdown, taskFamily, classify или answer."},"ExamStructurePatch":{"type":"object","properties":{"grade":{"description":"Клас на теста (1–12).","type":"integer","minimum":1,"maximum":12},"title":{"description":"Заглавие на теста.","nullable":true,"type":"string","maxLength":300},"subject":{"description":"Предмет (mathematics | bulgarian). Writable след upload.","type":"string","enum":["mathematics","bulgarian"]},"difficulty":{"description":"Трудност 1–5; null изчиства.","nullable":true,"type":"integer","minimum":1,"maximum":5},"questionPages":{"description":"Страници с въпроси (роли в PDF).","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"answerKeyPages":{"description":"Страници с ключ за оценяване.","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"solutionPages":{"description":"Страници с пълни решения.","maxItems":40,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"structureTests":{"description":"При split PDF — метаданни по под-тест (title, startPage, page ranges).","maxItems":24,"type":"array","items":{"type":"object","additionalProperties":{}}},"applyPoints":{"description":"true = презаписва points на всички задачи според pointRules/defaultPoints. Ползвай след като задачите вече съществуват.","type":"boolean"},"applyAnswerKey":{"description":"true = overwrite на correctAnswer/correctOptionIndex от answerKeyText. Default false.","type":"boolean"},"skipLocked":{"description":"Само с applyAnswerKey: задачи с ръчно заключен отговор (humanLocks.answer) са пропускани. false/липсва + има заключени → 409 HUMAN_LOCKED. true → прилага само на незаключените и връща skippedHumanLocked.","type":"boolean"},"confirm":{"description":"Токен при published exam (двустъпков confirm).","type":"string","minLength":1},"fullSolutionDefaults":{"description":"Defaults for new multiline questions: solutionRequired, solutionPhotoUpload (off|optional|required, default optional), maxSolutionPhotos (1–5, default 1), scoring.mode (all_or_nothing|partial), scoring.answerOnlyPoints, scoring.rubric[{label,points}], scoring.allowManualPoints, scoring.step, solutionHintText. null clears. Point caps are checked when a question is saved, not here.","nullable":true,"type":"object","properties":{"solutionRequired":{"type":"boolean"},"solutionPhotoUpload":{"type":"string","enum":["off","optional","required"]},"maxSolutionPhotos":{"type":"integer","minimum":1,"maximum":5},"scoring":{"type":"object","properties":{"mode":{"type":"string","enum":["all_or_nothing","partial"]},"answerOnlyPoints":{"type":"number","minimum":0,"maximum":1000},"rubric":{"maxItems":12,"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":200},"points":{"type":"number","minimum":0,"maximum":1000}},"required":["label","points"],"additionalProperties":false}},"allowManualPoints":{"type":"boolean"},"step":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":100}},"additionalProperties":false},"solutionHintText":{"nullable":true,"type":"string","maxLength":2000}},"additionalProperties":false},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300,"description":"Продължителност на опита в минути (1–300). При качване без поле: 40. Не се извлича от PDF."},"wrongAnswerPoints":{"description":"Точки при напълно грешен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"blankAnswerPoints":{"description":"Точки при празен отговор (−50…50). Default 0. Само при опит.","type":"integer","minimum":-50,"maximum":50},"startingPoints":{"description":"Стартови точки към сбора на опита (0…500). Default 0.","type":"integer","minimum":0,"maximum":500},"defaultPoints":{"description":"Равномерни точки на задача, ако pointRules е празен. null = без.","nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"description":"Правила точки по номер. Compact „1-18:1; 19-20:2“ или масив {from,to,points}.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":80,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начален номер на задача (включително)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Краен номер на задача (включително)."},"points":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Точки за задачите в диапазона."}},"required":["from","to","points"],"additionalProperties":false}}]},"gradeRules":{"description":"Скала 2–6. Compact „0-10:2; 11-15:3; …“ или масив {from,to,grade}. Празно = без скала.","anyOf":[{"type":"string","maxLength":2000},{"maxItems":24,"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Долен праг на сбор точки (включително)."},"to":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Горен праг на сбор точки (включително)."},"grade":{"type":"integer","minimum":2,"maximum":6,"description":"Оценка 2–6."}},"required":["from","to","grade"],"additionalProperties":false}}]},"answerKeyText":{"description":"Ключ с отговори: „1 Б; 2 Г; 15 189“. Празен string или null изчиства.","nullable":true,"type":"string","maxLength":20000},"mcOtherAnswerMode":{"description":"Режим на MC „Друго“ за целия тест: select_only = само маркиране; requires_text = изисква свободен текст. Default requires_text. Take-test чете exams/{id}.mcOtherAnswerMode, не structureTests.","type":"string","enum":["select_only","requires_text"]},"mcOptionsLayout":{"description":"Подредба на MC опциите: stacked = по един на ред; compact = компактен ред. Default stacked.","type":"string","enum":["stacked","compact"]},"mcAnswerLabelScheme":{"description":"Етикети на MC отговорите: cyrillic_upper (default А Б В…), cyrillic_lower, latin_lower, latin_upper, numeric, custom. При custom подай mcAnswerLabels.","type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"]},"mcAnswerLabels":{"description":"Собствени етикети (1–12, без дубликати) само при mcAnswerLabelScheme=custom. При друг scheme се изчистват.","minItems":1,"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":8}},"notesEnabled":{"description":"Бележки при решаване. Default true. При grade 0 (предучилищна) винаги false.","type":"boolean"}},"additionalProperties":false,"description":"Корекция на page roles, предмет, трудност, таймер, точкуване, ключ, MC „Друго“/layout/етикети, бележки. applyPoints/applyAnswerKey презаписват задачи. Публикуван тест иска confirm."},"ExamSummary":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Каталожно резюме (GET /v1/exams, GET /v1/exams/{id}, MCP get_exam). Без въпроси, ключове и без processing.cost — цената е само в inspect.summary.cost."},"ExamList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Каталожно резюме (GET /v1/exams, GET /v1/exams/{id}, MCP get_exam). Без въпроси, ключове и без processing.cost — цената е само в inspect.summary.cost."},"description":"Списък каталожни резюмета."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"nextCursor":{"nullable":true,"type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false,"description":"Отговор на GET /v1/exams (search)."},"ExamPipelineConfig":{"type":"object","properties":{"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answerBase","answerMid","answerSmart","answer","answerEasy","hint","grading","extractAnswerKey","mcOnDrawing"],"additionalProperties":false},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answerBase","answerMid","answerSmart","answer","answerEasy","hint","grading","extractAnswerKey","mcOnDrawing"],"additionalProperties":false},"stopAfter":{"nullable":true,"description":"Глобално спиране след стъпка. full = пълен pipeline до край (еквивалент на null). За upload/process overrides ползвай pipelineStopAfterSchema (без full).","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify","full"]},"prompts":{"type":"object","properties":{"structure":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"bounds":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"figures":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"boundsVerify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extract":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"improveMarkdown":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"taskFamily":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"classify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"answer":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"hint":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"grading":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extractAnswerKey":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"mcOnDrawing":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"solvePart":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"hintPart":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"docAiClassify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answer","hint","grading","extractAnswerKey","extractAnswerKeyWorkedSolutions","mcOnDrawing","solvePart","hintPart","docAiClassify"],"additionalProperties":false},"typesafeClassifyPrompts":{"type":"object","properties":{"themeRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"rootRetry":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"structureInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatSlot2PlusInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."}},"required":["themeRoot","themeChild","storyRoot","storyChild","skillRoot","skillChild","rootRetry","structureInstructions","themeFlatInstructions","themeFlatSlot2PlusInstructions"],"additionalProperties":false},"typesafeClassifyFlow":{"type":"string","enum":["v1","v2","v3"],"description":"v1 legacy drill; v2 B+ drill; v3 S3 structure-first theme."},"structureOptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":40},"label":{"type":"string","minLength":1,"maxLength":200},"criterion":{"type":"string","minLength":1,"maxLength":800},"opens":{"maxItems":64,"type":"array","items":{"type":"string","minLength":1}},"hideForGrades":{"maxItems":12,"type":"array","items":{"type":"integer","minimum":1,"maximum":12}}},"required":["key","label","criterion","opens","hideForGrades"],"additionalProperties":false}},"boundsSnap":{"type":"object","properties":{"enabled":{"type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"type":"number"},"emptyLineRatio":{"type":"number"},"maxGrowPx":{"type":"number"},"maxShrinkPx":{"type":"number"},"emptyMarginPx":{"type":"number"},"maxGapBridgePx":{"type":"number"},"paddingPx":{"type":"number"}},"required":["enabled","sides","bgTolerance","emptyLineRatio","maxGrowPx","maxShrinkPx","emptyMarginPx","maxGapBridgePx","paddingPx"],"additionalProperties":false},"figuresSnap":{"type":"object","properties":{"enabled":{"type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"type":"number"},"emptyLineRatio":{"type":"number"},"maxGrowPx":{"type":"number"},"maxShrinkPx":{"type":"number"},"emptyMarginPx":{"type":"number"},"maxGapBridgePx":{"type":"number"},"paddingPx":{"type":"number"}},"required":["enabled","sides","bgTolerance","emptyLineRatio","maxGrowPx","maxShrinkPx","emptyMarginPx","maxGapBridgePx","paddingPx"],"additionalProperties":false},"boundsVerifyEnabled":{"type":"boolean"},"boundsReconcileEnabled":{"type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"type":"boolean"},"contrast":{"type":"number"},"lineDarken":{"type":"number"},"bgTolerance":{"type":"number"},"saturation":{"type":"number"},"vibrance":{"type":"number"},"transparentBackground":{"type":"boolean"},"transparentBackgroundWholeImage":{"type":"boolean"}},"required":["enabled","contrast","lineDarken","bgTolerance","saturation","vibrance","transparentBackground","transparentBackgroundWholeImage"],"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"type":"boolean"},"fallbackToLlm":{"type":"boolean"}},"required":["enabled","fallbackToLlm"],"additionalProperties":false},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"type":"boolean"},"taskFamily":{"type":"boolean"},"classify":{"type":"boolean"},"answer":{"type":"boolean"},"hint":{"type":"boolean"},"mcOnDrawing":{"type":"boolean"}},"required":["improveMarkdown","taskFamily","classify","answer","hint","mcOnDrawing"],"additionalProperties":false,"description":"Независими ключове: Markdown / Семейство / Classify / Answer / Hint / Отговори върху чертежа."},"questionConcurrency":{"type":"integer","minimum":1,"maximum":8,"description":"Pass 2 concurrency (extract → improve → solve → classify), 1–8."},"promptVersion":{"type":"string","description":"Последен cfg-* идентификатор на запис."},"effectiveNotes":{"type":"array","items":{"type":"string"},"description":"Бележки: DocAI skip, code-only промптове, лимити."}},"required":["providers","models","stopAfter","prompts","typesafeClassifyPrompts","typesafeClassifyFlow","structureOptions","boundsSnap","figuresSnap","boundsVerifyEnabled","boundsReconcileEnabled","drawingAutoClean","documentAi","stepsEnabled","questionConcurrency","promptVersion","effectiveNotes"],"additionalProperties":false,"description":"Глобален exam pipeline config (GET /v1/exam-pipeline)."},"ExamPipelineConfigPatchResult":{"anyOf":[{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},{"type":"object","properties":{"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answerBase","answerMid","answerSmart","answer","answerEasy","hint","grading","extractAnswerKey","mcOnDrawing"],"additionalProperties":false},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answerBase","answerMid","answerSmart","answer","answerEasy","hint","grading","extractAnswerKey","mcOnDrawing"],"additionalProperties":false},"stopAfter":{"nullable":true,"description":"Глобално спиране след стъпка. full = пълен pipeline до край (еквивалент на null). За upload/process overrides ползвай pipelineStopAfterSchema (без full).","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify","full"]},"prompts":{"type":"object","properties":{"structure":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"bounds":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"figures":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"boundsVerify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extract":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"improveMarkdown":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"taskFamily":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"classify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"answer":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"hint":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"grading":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extractAnswerKey":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"mcOnDrawing":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"solvePart":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"hintPart":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false},"docAiClassify":{"type":"object","properties":{"system":{"type":"string"},"user":{"type":"string"}},"required":["system","user"],"additionalProperties":false}},"required":["structure","bounds","figures","boundsVerify","extract","improveMarkdown","taskFamily","classify","answer","hint","grading","extractAnswerKey","extractAnswerKeyWorkedSolutions","mcOnDrawing","solvePart","hintPart","docAiClassify"],"additionalProperties":false},"typesafeClassifyPrompts":{"type":"object","properties":{"themeRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"storyChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillRoot":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"skillChild":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"rootRetry":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"structureInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."},"themeFlatSlot2PlusInstructions":{"type":"string","minLength":1,"maxLength":4000,"description":"Jev choice instruction. `{parent}` is replaced with the parent category name."}},"required":["themeRoot","themeChild","storyRoot","storyChild","skillRoot","skillChild","rootRetry","structureInstructions","themeFlatInstructions","themeFlatSlot2PlusInstructions"],"additionalProperties":false},"typesafeClassifyFlow":{"type":"string","enum":["v1","v2","v3"],"description":"v1 legacy drill; v2 B+ drill; v3 S3 structure-first theme."},"structureOptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":40},"label":{"type":"string","minLength":1,"maxLength":200},"criterion":{"type":"string","minLength":1,"maxLength":800},"opens":{"maxItems":64,"type":"array","items":{"type":"string","minLength":1}},"hideForGrades":{"maxItems":12,"type":"array","items":{"type":"integer","minimum":1,"maximum":12}}},"required":["key","label","criterion","opens","hideForGrades"],"additionalProperties":false}},"boundsSnap":{"type":"object","properties":{"enabled":{"type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"type":"number"},"emptyLineRatio":{"type":"number"},"maxGrowPx":{"type":"number"},"maxShrinkPx":{"type":"number"},"emptyMarginPx":{"type":"number"},"maxGapBridgePx":{"type":"number"},"paddingPx":{"type":"number"}},"required":["enabled","sides","bgTolerance","emptyLineRatio","maxGrowPx","maxShrinkPx","emptyMarginPx","maxGapBridgePx","paddingPx"],"additionalProperties":false},"figuresSnap":{"type":"object","properties":{"enabled":{"type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"type":"number"},"emptyLineRatio":{"type":"number"},"maxGrowPx":{"type":"number"},"maxShrinkPx":{"type":"number"},"emptyMarginPx":{"type":"number"},"maxGapBridgePx":{"type":"number"},"paddingPx":{"type":"number"}},"required":["enabled","sides","bgTolerance","emptyLineRatio","maxGrowPx","maxShrinkPx","emptyMarginPx","maxGapBridgePx","paddingPx"],"additionalProperties":false},"boundsVerifyEnabled":{"type":"boolean"},"boundsReconcileEnabled":{"type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"type":"boolean"},"contrast":{"type":"number"},"lineDarken":{"type":"number"},"bgTolerance":{"type":"number"},"saturation":{"type":"number"},"vibrance":{"type":"number"},"transparentBackground":{"type":"boolean"},"transparentBackgroundWholeImage":{"type":"boolean"}},"required":["enabled","contrast","lineDarken","bgTolerance","saturation","vibrance","transparentBackground","transparentBackgroundWholeImage"],"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"type":"boolean"},"fallbackToLlm":{"type":"boolean"}},"required":["enabled","fallbackToLlm"],"additionalProperties":false},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"type":"boolean"},"taskFamily":{"type":"boolean"},"classify":{"type":"boolean"},"answer":{"type":"boolean"},"hint":{"type":"boolean"},"mcOnDrawing":{"type":"boolean"}},"required":["improveMarkdown","taskFamily","classify","answer","hint","mcOnDrawing"],"additionalProperties":false,"description":"Независими ключове: Markdown / Семейство / Classify / Answer / Hint / Отговори върху чертежа."},"questionConcurrency":{"type":"integer","minimum":1,"maximum":8,"description":"Pass 2 concurrency (extract → improve → solve → classify), 1–8."},"promptVersion":{"type":"string","description":"Последен cfg-* идентификатор на запис."},"effectiveNotes":{"type":"array","items":{"type":"string"},"description":"Бележки: DocAI skip, code-only промптове, лимити."},"action":{"type":"string","enum":["updated"],"description":"Config е записан успешно."}},"required":["providers","models","stopAfter","prompts","typesafeClassifyPrompts","typesafeClassifyFlow","structureOptions","boundsSnap","figuresSnap","boundsVerifyEnabled","boundsReconcileEnabled","drawingAutoClean","documentAi","stepsEnabled","questionConcurrency","promptVersion","effectiveNotes","action"],"additionalProperties":false,"description":"Успешен PATCH на глобален pipeline config."}],"description":"PATCH /v1/exam-pipeline — или confirm, или updated config."},"ConfirmationRequired":{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},"ExamInspect":{"type":"object","properties":{"summary":{"description":"При include=summary. Тук е cost; не се връща от GET /v1/exams/{id}.","type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"nullable":true,"type":"string","enum":["mathematics","bulgarian"]},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false},"pipelineOverrides":{"nullable":true,"description":"Записани per-exam overrides или null.","type":"object","properties":{"stopAfter":{"nullable":true,"description":"Спира pipeline след дадена стъпка (за итерация). null = без спиране (до край или глобален stopAfter). structure = след JSON структура; bounds = след локализация; extract / improveMarkdown / taskFamily / classify = съответната стъпка.","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"boundsSnap":{"description":"Snap за problem bounds.","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"figuresSnap":{"description":"Snap за figure bounds (отделно от problem).","type":"object","properties":{"enabled":{"description":"Включва/изключва snap след AI bounds.","type":"boolean"},"sides":{"type":"object","properties":{"left":{"description":"Прилепване към ляв ръб на страницата.","type":"boolean"},"right":{"description":"Прилепване към десен ръб на страницата.","type":"boolean"},"top":{"description":"Прилепване към горен ръб на страницата.","type":"boolean"},"bottom":{"description":"Прилепване към долен ръб на страницата.","type":"boolean"}},"additionalProperties":false,"description":"Кои страни на bounding box да се „залепят“ към празно поле."},"bgTolerance":{"description":"Толеранс за фон (0–1) при откриване на празни зони.","type":"number"},"emptyLineRatio":{"description":"Минимален дял празни пиксели по ръб за snap.","type":"number"},"maxGrowPx":{"description":"Макс. разширение на box в пиксели.","type":"number"},"maxShrinkPx":{"description":"Макс. свиване на box в пиксели.","type":"number"},"emptyMarginPx":{"description":"Минимален празен margin от ръба.","type":"number"},"maxGapBridgePx":{"description":"Макс. разстояние за „мост“ през тънка линия при snap.","type":"number"},"paddingPx":{"description":"Вътрешен padding след snap.","type":"number"}},"additionalProperties":false},"documentAi":{"type":"object","properties":{"enabled":{"description":"Включва Document AI Layout Parser за bounds pre-pass.","type":"boolean"},"fallbackToLlm":{"description":"При неуспех на Document AI — fallback към LLM bounds/figures.","type":"boolean"}},"additionalProperties":false,"description":"Document AI hybrid настройки."},"boundsVerifyEnabled":{"description":"Overlay review + една корекционна рунда след bounds.","type":"boolean"},"boundsReconcileEnabled":{"description":"Остави false (подразбиране; липсващо поле също е false). Включи само в редкия случай: една колона и задача, която продължава на следващата страница. При две колони задължително false — сливането залепва колоните.","type":"boolean"},"drawingAutoClean":{"type":"object","properties":{"enabled":{"description":"Почиствай всеки нов чертеж при изрязване (по подразбиране true).","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"transparentBackground":{"description":"Прозрачен фон (по подразбиране false).","type":"boolean"},"transparentBackgroundWholeImage":{"description":"С transparentBackground: целият бял фон прозрачен, включително заграден от линиите (по подразбиране false).","type":"boolean"}},"additionalProperties":false,"description":"Автоматично „Почисти“ на всеки нов чертеж (Граници → изрезка, Коригирай, +2px). Суровата изрезка се пази като оригинал."},"stepsEnabled":{"type":"object","properties":{"improveMarkdown":{"description":"false = пропуска Markdown (improve) за този run; Classify/Answer ползват extract текста.","type":"boolean"},"taskFamily":{"description":"false = пропуска съвпадение със семейство задача (numberSequence и др.).","type":"boolean"},"classify":{"description":"false = пропуска класификация по таксономия; Answer може да върви.","type":"boolean"},"answer":{"description":"false = пропуска solve/escalate (най-скъпата стъпка).","type":"boolean"},"hint":{"description":"false = пропуска post-solve Hint; независимо от Answer.","type":"boolean"},"mcOnDrawing":{"description":"„Отговори върху чертежа“ (по подразбиране false): MC вариантите са фигури с букви A…E / А…Д в чертежа — AI намира зоните и детето докосва фигурата; редът бутони се скрива.","type":"boolean"}},"additionalProperties":false,"description":"Независими ключове за Markdown/Семейство/Classify/Answer/Hint. Липсващо поле = наследява глобалния config (default true). Не замества stopAfter (който реже суфикса)."},"prompts":{"type":"object","properties":{"structure":{"description":"Промптове за стъпка structure.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"bounds":{"description":"Промптове за стъпка bounds.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"figures":{"description":"Промптове за стъпка figures.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"boundsVerify":{"description":"Промптове за стъпка boundsVerify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extract":{"description":"Промптове за стъпка extract.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"improveMarkdown":{"description":"Промптове за стъпка improveMarkdown.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"taskFamily":{"description":"Промптове за стъпка taskFamily (matcher).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"classify":{"description":"Промптове за стъпка classify.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"answer":{"description":"Промптове за стъпка answer.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hint":{"description":"Промптове за стъпка hint.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"grading":{"description":"Промптове за стъпка grading.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKey":{"description":"Промптове за стъпка extractAnswerKey.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"extractAnswerKeyWorkedSolutions":{"description":"System за ключ от подробни решения. Празен user ползва extractAnswerKey.user.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"solvePart":{"description":"Промптове за solve на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"hintPart":{"description":"Промптове за hint на една подточка.","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"docAiClassify":{"description":"Промптове за Document AI classify ({{pageNumber}}, {{blocksJson}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false},"mcOnDrawing":{"description":"Промптове за „Отговори върху чертежа“ (user шаблон: {{problem}}, {{options}}, {{drawingCount}}, {{pdfLabels}}).","type":"object","properties":{"system":{"description":"System промпт за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000},"user":{"description":"User промпт / template за стъпката (1–20 000 символа).","type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false}},"additionalProperties":false,"description":"Частични prompt overrides по pipeline стъпка."},"providers":{"type":"object","properties":{"structure":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"bounds":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"figures":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"boundsVerify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extract":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"improveMarkdown":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"taskFamily":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"classify":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerBase":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerMid":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerSmart":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answer":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"answerEasy":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"hint":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"grading":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"extractAnswerKey":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."},"mcOnDrawing":{"type":"string","enum":["openai","grok","gemini","claude","inception"],"description":"LLM доставчик: openai, grok, gemini, claude или inception (Mercury 3, само текст)."}},"additionalProperties":false,"description":"LLM доставчик по pipeline стъпка (глобален config)."},"models":{"type":"object","properties":{"structure":{"type":"string","minLength":1,"maxLength":120},"bounds":{"type":"string","minLength":1,"maxLength":120},"figures":{"type":"string","minLength":1,"maxLength":120},"boundsVerify":{"type":"string","minLength":1,"maxLength":120},"extract":{"type":"string","minLength":1,"maxLength":120},"improveMarkdown":{"type":"string","minLength":1,"maxLength":120},"taskFamily":{"type":"string","minLength":1,"maxLength":120},"classify":{"type":"string","minLength":1,"maxLength":120},"answerBase":{"type":"string","minLength":1,"maxLength":120},"answerMid":{"type":"string","minLength":1,"maxLength":120},"answerSmart":{"type":"string","minLength":1,"maxLength":120},"answer":{"type":"string","minLength":1,"maxLength":120},"answerEasy":{"type":"string","minLength":1,"maxLength":120},"hint":{"type":"string","minLength":1,"maxLength":120},"grading":{"type":"string","minLength":1,"maxLength":120},"extractAnswerKey":{"type":"string","minLength":1,"maxLength":120},"mcOnDrawing":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false,"description":"Име на модел по pipeline стъпка (глобален config)."},"reasoningEffort":{"type":"object","properties":{"structure":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"bounds":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"figures":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"boundsVerify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extract":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"improveMarkdown":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"classify":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerBase":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerMid":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerSmart":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answer":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"answerEasy":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"hint":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"grading":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"extractAnswerKey":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]},"mcOnDrawing":{"nullable":true,"description":"OpenAI reasoning_effort. null = не се праща (default на доставчика).","type":"string","enum":["none","low","medium","high"]}},"additionalProperties":false,"description":"reasoning_effort по стъпка (OpenAI)."},"reasoningMode":{"type":"object","properties":{"structure":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"bounds":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"figures":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"boundsVerify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extract":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"improveMarkdown":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"classify":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerBase":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerMid":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerSmart":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answer":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"answerEasy":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"hint":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"grading":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"extractAnswerKey":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."},"mcOnDrawing":{"type":"string","enum":["standard","pro"],"description":"OpenAI reasoning.mode: standard (default) или pro (Astra/Sol via Responses API). Независим от reasoningEffort. Същите $/MTok, повече tokens."}},"additionalProperties":false,"description":"Per-step reasoning.mode (pro само за OpenAI Astra/Sol)."},"temperature":{"description":"Температура за solve слотове. null = не се праща към API.","type":"object","properties":{"answerBase":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerMid":{"nullable":true,"type":"number","minimum":0,"maximum":2},"answerSmart":{"nullable":true,"type":"number","minimum":0,"maximum":2}},"additionalProperties":false},"solveEscalate":{"description":"Каскада base → mid → smart при разминаване с ключа.","type":"object","properties":{"maxMidAttempts":{"description":"Бюджет mid опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50},"maxSmartAttempts":{"description":"Бюджет smart опити за целия тест (0 = изключен).","type":"integer","minimum":0,"maximum":50}},"additionalProperties":false},"questionConcurrency":{"description":"Колко задачи в Pass 2 (extract → improve → solve → classify) да вървят паралелно (1–8). Default 1; parent scan = 3.","type":"integer","minimum":1,"maximum":8}},"additionalProperties":false},"promptOverrideKeys":{"type":"array","items":{"type":"string"},"description":"Стъпки с локален промпт override."},"stopAfter":{"nullable":true,"description":"Локален stopAfter за този run, или null.","type":"string","enum":["structure","bounds","extract","improveMarkdown","taskFamily","classify"]},"models":{"nullable":true,"description":"Модели по стъпка от последния пълен run.","type":"object","additionalProperties":{"type":"string"}},"promptVersion":{"nullable":true,"description":"cfg-* версия от последния пълен run.","type":"string"},"llmProvider":{"nullable":true,"description":"Основен LLM доставчик от последния пълен run.","type":"string"},"cost":{"nullable":true,"description":"processing.cost: натрупани USD от всеки pipeline run и reprocess (нищо не ги нулира). lastReprocess е само последната рунда. null ако още няма нито pipeline, нито reprocess с LLM. get_exam няма това поле.","type":"object","properties":{"currency":{"type":"string","enum":["USD"],"description":"Валута на оценката (винаги USD)."},"totalUsd":{"type":"number","description":"Сбор от rows[].usd. Всеки pipeline run и всеки reprocess добавят. Никой run не нулира обекта."},"rows":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","description":"Ключ на стъпка: structure, extract, answerBase, documentAi, …"},"calls":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой извиквания в този ред."},"provider":{"type":"string","description":"LLM/DocAI доставчик (openai, grok, gemini, claude, inception, documentai, …)."},"model":{"type":"string","description":"Модел или DocAI процесор."},"promptRole":{"type":"string","description":"Български етикет (Структура, Решаване, Document AI, …)."},"inputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Входни токени (0 за Document AI)."},"outputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Изходни токени (0 за Document AI)."},"usd":{"type":"number","description":"Оценка в USD за този ред."},"source":{"description":"Произход: пълен pipeline, reprocess или manual (ръчен AI на задача, прерисуване на чертеж, преглед на markdown). Липсва в стари документи = pipeline.","type":"string","enum":["pipeline","reprocess","manual"]}},"required":["step","calls","provider","model","promptRole","inputTokens","outputTokens","usd"],"additionalProperties":false,"description":"Един ред в оценката на разходи."},"description":"Агрегирани редове по source+стъпка+provider+model."},"attempts":{"type":"object","properties":{"base":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво base."},"mid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво mid."},"smart":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво smart."}},"required":["base","mid","smart"],"additionalProperties":false,"description":"Сбор на solve опитите от всеки pipeline run (reprocess не ги пипа)."},"attemptBudget":{"type":"object","properties":{"maxMid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Изпитен бюджет за mid опити."},"maxSmart":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Изпитен бюджет за smart опити."}},"required":["maxMid","maxSmart"],"additionalProperties":false,"description":"Exam-wide лимит за escalate към mid/smart."},"lastReprocess":{"description":"Само последната reprocess рунда. Pipeline run не я маха.","type":"object","properties":{"stage":{"type":"string","enum":["extract","improveMarkdown","taskFamily","classify","answer","mcOnDrawing"],"description":"Stage на тази reprocess рунда."},"at":{"type":"string","description":"ISO-8601 момент на persist за рундата."},"requestId":{"nullable":true,"description":"processing.apiCommand.requestId или генериран round id.","type":"string"},"totalUsd":{"type":"number","description":"USD само за тази reprocess рунда (не кумулативът)."},"rows":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","description":"Ключ на стъпка: structure, extract, answerBase, documentAi, …"},"calls":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой извиквания в този ред."},"provider":{"type":"string","description":"LLM/DocAI доставчик (openai, grok, gemini, claude, inception, documentai, …)."},"model":{"type":"string","description":"Модел или DocAI процесор."},"promptRole":{"type":"string","description":"Български етикет (Структура, Решаване, Document AI, …)."},"inputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Входни токени (0 за Document AI)."},"outputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Изходни токени (0 за Document AI)."},"usd":{"type":"number","description":"Оценка в USD за този ред."},"source":{"description":"Произход: пълен pipeline, reprocess или manual (ръчен AI на задача, прерисуване на чертеж, преглед на markdown). Липсва в стари документи = pipeline.","type":"string","enum":["pipeline","reprocess","manual"]}},"required":["step","calls","provider","model","promptRole","inputTokens","outputTokens","usd"],"additionalProperties":false,"description":"Един ред в оценката на разходи."},"description":"Редове само от тази рунда (source=reprocess)."},"attempts":{"type":"object","properties":{"base":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво base."},"mid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво mid."},"smart":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой solve опити на ниво smart."}},"required":["base","mid","smart"],"additionalProperties":false,"description":"Solve опити в тази рунда (не се смесват с pipeline attempts)."},"applied":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Успешни задачи в рундата."},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Неуспешни задачи в рундата."},"reasoningMode":{"description":"Еднократен OpenAI reasoning.mode за тази reprocess рунда (ако е подаден).","type":"string","enum":["standard","pro"]},"error":{"description":"При failed > 0 или LLM throw. Празни rows + attempts.base > 0 без error = стар bug (swallow).","type":"object","properties":{"message":{"type":"string","description":"Съобщение (вкл. Anthropic status/type/request_id)."},"provider":{"type":"string"},"model":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"requestId":{"description":"Anthropic request_id когато е наличен.","type":"string"},"questionIds":{"type":"array","items":{"type":"string"}}},"required":["message"],"additionalProperties":false}},"required":["stage","at","requestId","totalUsd","rows","attempts","applied","failed"],"additionalProperties":false}},"required":["currency","totalUsd","rows","attempts","attemptBudget"],"additionalProperties":false},"scoringPolicy":{"type":"object","properties":{"wrongAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"blankAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"startingPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["wrongAnswerPoints","blankAnswerPoints","startingPoints"],"additionalProperties":false,"description":"Точкуване при опит (не пипа точките по задачи)."},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300},"scoringLocked":{"type":"boolean"},"defaultPoints":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"to":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["from","to","points"],"additionalProperties":false}},"pointRulesText":{"type":"string"},"gradeRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"to":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["from","to","grade"],"additionalProperties":false}},"gradeRulesText":{"type":"string"},"answerKeyText":{"nullable":true,"type":"string"},"mcOtherAnswerMode":{"type":"string","enum":["select_only","requires_text"]},"mcOptionsLayout":{"type":"string","enum":["stacked","compact"]},"mcAnswerLabelScheme":{"type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"]},"mcAnswerLabels":{"type":"array","items":{"type":"string"}},"notesEnabled":{"type":"boolean"},"fullSolutionDefaults":{"nullable":true,"description":"Exam-level defaults for new multiline questions. null when unset. Same fields as question fullSolution.","type":"object","properties":{"solutionRequired":{"type":"boolean"},"solutionPhotoUpload":{"type":"string","enum":["off","optional","required"]},"maxSolutionPhotos":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"scoring":{"type":"object","properties":{"mode":{"type":"string","enum":["all_or_nothing","partial"]},"answerOnlyPoints":{"type":"number"},"rubric":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"points":{"type":"number"}},"required":["label","points"],"additionalProperties":false}},"allowManualPoints":{"type":"boolean"},"step":{"type":"number"}},"required":["mode","answerOnlyPoints","rubric","allowManualPoints","step"],"additionalProperties":false},"solutionHintText":{"nullable":true,"type":"string"}},"required":["solutionRequired","solutionPhotoUpload","maxSolutionPhotos","scoring","solutionHintText"],"additionalProperties":false},"difficulty":{"nullable":true,"type":"integer","minimum":1,"maximum":5},"questionCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Общ брой задачи (за humanReviewedQuestionCount / N)."},"humanReviewedQuestionCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой задачи с отметка „проверена“ (D12)."},"humanLockedQuestionCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой задачи с поне един заключен вид (D4/D5)."}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview","pipelineOverrides","promptOverrideKeys","stopAfter","models","promptVersion","llmProvider","cost","scoringPolicy","timeLimitMinutes","scoringLocked","defaultPoints","pointRules","pointRulesText","gradeRules","gradeRulesText","answerKeyText","mcOtherAnswerMode","mcOptionsLayout","mcAnswerLabelScheme","mcAnswerLabels","notesEnabled","fullSolutionDefaults","difficulty","questionCount","humanReviewedQuestionCount","humanLockedQuestionCount"],"additionalProperties":false},"structure":{"type":"object","properties":{"structureTests":{"nullable":true,"type":"array","items":{"type":"object","additionalProperties":{}}},"questionPages":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"answerKeyPages":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"solutionPages":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начална страница (1-based)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Крайна страница (включително)."}},"required":["from","to"],"additionalProperties":false,"description":"Диапазон страници в PDF."}},"schoolGrade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"splitFromExamId":{"nullable":true,"type":"string"},"splitIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"structureJsonUrl":{"nullable":true,"description":"Signed URL (~15 мин).","type":"string","format":"uri"}},"required":["structureTests","questionPages","answerKeyPages","solutionPages","schoolGrade","splitFromExamId","splitIndex","structureJsonUrl"],"additionalProperties":false},"bounds":{"type":"object","properties":{"pages":{"type":"array","items":{"type":"object","properties":{"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"model":{"nullable":true,"type":"string"},"problemCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"figureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"overlayUrl":{"nullable":true,"type":"string","format":"uri"},"boundsJsonUrl":{"nullable":true,"type":"string","format":"uri"}},"required":["page","model","problemCount","figureCount","overlayUrl","boundsJsonUrl"],"additionalProperties":false}}},"required":["pages"],"additionalProperties":false},"questions":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"order":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"sequenceNumber":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points":{"nullable":true,"type":"number"},"problemText":{"nullable":true,"type":"string"},"problemRichText":{"nullable":true,"type":"string"},"answerOptions":{"nullable":true,"type":"array","items":{}},"correctAnswer":{"nullable":true,"type":"string"},"correctOptionIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"solution":{"nullable":true,"type":"string"},"hint":{"nullable":true,"type":"string"},"cropUrl":{"nullable":true,"type":"string","format":"uri"},"humanLocks":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]},"description":"Заключени видове на тази задача (D4); [] = незаключена."},"humanReviewed":{"type":"boolean","description":"Отметка „проверена“ на задачата (D12)."}},"required":["id","order","sequenceNumber","points","problemText","problemRichText","answerOptions","correctAnswer","correctOptionIndex","solution","hint","cropUrl","humanLocks","humanReviewed"],"additionalProperties":false}},"nextCursor":{"nullable":true,"type":"string"}},"required":["items","nextCursor"],"additionalProperties":false},"issues":{"type":"array","items":{"type":"object","additionalProperties":{}}},"siblingExamIds":{"type":"array","items":{"type":"string"},"description":"IDs на split sibling exams (винаги присъства)."}},"required":["siblingExamIds"],"additionalProperties":false,"description":"Inspect payload — секции по include=."},"ExamProcessQueued":{"type":"object","properties":{"queued":{"type":"boolean","enum":[true],"description":"Командата е записана; poll GET /v1/exams/:id."},"command":{"type":"object","properties":{"requestId":{"type":"string","description":"UUID на заявката (идемпотентност / одит)."},"kind":{"type":"string","enum":["resume","fullRestart","reprocess"],"description":"Вид команда в processing.apiCommand."},"stage":{"type":"string","enum":["extract","improveMarkdown","taskFamily","classify","answer","mcOnDrawing"]},"questionIds":{"type":"array","items":{"type":"string"}},"provider":{"type":"string"},"model":{"type":"string"},"reasoningEffort":{"description":"Еднократен effort за reprocess (от MCP/REST top-level).","nullable":true,"type":"string","enum":["none","low","medium","high"]},"reasoningMode":{"description":"Еднократен reasoning.mode за reprocess (OpenAI Astra/Sol).","type":"string","enum":["standard","pro"]}},"required":["requestId","kind"],"additionalProperties":false,"description":"Записана команда за processExamOnUpload trigger."},"exam":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Актуално каталожно резюме след enqueue."},"skippedHumanLocked":{"description":"Само при skipLocked=true за reprocess — задачите, пропуснати заради заключени полета.","type":"array","items":{"type":"object","properties":{"questionId":{"type":"string"},"sequenceNumber":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kinds":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]}}},"required":["questionId","sequenceNumber","kinds"],"additionalProperties":false,"description":"Заключени видове на една задача (D4). Кодовете: stem=Условие, solution=Решение, answer=Отговор, options=Опции, drawings=Чертежи, bounds=Граници."}}},"required":["queued","command","exam"],"additionalProperties":false,"description":"Отговор 202 при успешен enqueue на process/reprocess."},"ExamProcessResult":{"anyOf":[{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},{"type":"object","properties":{"queued":{"type":"boolean","enum":[true],"description":"Командата е записана; poll GET /v1/exams/:id."},"command":{"type":"object","properties":{"requestId":{"type":"string","description":"UUID на заявката (идемпотентност / одит)."},"kind":{"type":"string","enum":["resume","fullRestart","reprocess"],"description":"Вид команда в processing.apiCommand."},"stage":{"type":"string","enum":["extract","improveMarkdown","taskFamily","classify","answer","mcOnDrawing"]},"questionIds":{"type":"array","items":{"type":"string"}},"provider":{"type":"string"},"model":{"type":"string"},"reasoningEffort":{"description":"Еднократен effort за reprocess (от MCP/REST top-level).","nullable":true,"type":"string","enum":["none","low","medium","high"]},"reasoningMode":{"description":"Еднократен reasoning.mode за reprocess (OpenAI Astra/Sol).","type":"string","enum":["standard","pro"]}},"required":["requestId","kind"],"additionalProperties":false,"description":"Записана команда за processExamOnUpload trigger."},"exam":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Актуално каталожно резюме след enqueue."},"skippedHumanLocked":{"description":"Само при skipLocked=true за reprocess — задачите, пропуснати заради заключени полета.","type":"array","items":{"type":"object","properties":{"questionId":{"type":"string"},"sequenceNumber":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kinds":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]}}},"required":["questionId","sequenceNumber","kinds"],"additionalProperties":false,"description":"Заключени видове на една задача (D4). Кодовете: stem=Условие, solution=Решение, answer=Отговор, options=Опции, drawings=Чертежи, bounds=Граници."}}},"required":["queued","command","exam"],"additionalProperties":false,"description":"Отговор 202 при успешен enqueue на process/reprocess."}],"description":"POST process — confirm или queued."},"ExamReprocessResult":{"anyOf":[{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},{"type":"object","properties":{"queued":{"type":"boolean","enum":[true],"description":"Командата е записана; poll GET /v1/exams/:id."},"command":{"type":"object","properties":{"requestId":{"type":"string","description":"UUID на заявката (идемпотентност / одит)."},"kind":{"type":"string","enum":["resume","fullRestart","reprocess"],"description":"Вид команда в processing.apiCommand."},"stage":{"type":"string","enum":["extract","improveMarkdown","taskFamily","classify","answer","mcOnDrawing"]},"questionIds":{"type":"array","items":{"type":"string"}},"provider":{"type":"string"},"model":{"type":"string"},"reasoningEffort":{"description":"Еднократен effort за reprocess (от MCP/REST top-level).","nullable":true,"type":"string","enum":["none","low","medium","high"]},"reasoningMode":{"description":"Еднократен reasoning.mode за reprocess (OpenAI Astra/Sol).","type":"string","enum":["standard","pro"]}},"required":["requestId","kind"],"additionalProperties":false,"description":"Записана команда за processExamOnUpload trigger."},"exam":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Актуално каталожно резюме след enqueue."},"skippedHumanLocked":{"description":"Само при skipLocked=true за reprocess — задачите, пропуснати заради заключени полета.","type":"array","items":{"type":"object","properties":{"questionId":{"type":"string"},"sequenceNumber":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kinds":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]}}},"required":["questionId","sequenceNumber","kinds"],"additionalProperties":false,"description":"Заключени видове на една задача (D4). Кодовете: stem=Условие, solution=Решение, answer=Отговор, options=Опции, drawings=Чертежи, bounds=Граници."}}},"required":["queued","command","exam"],"additionalProperties":false,"description":"Отговор 202 при успешен enqueue на process/reprocess."}],"description":"POST reprocess — confirm или queued."},"ExamStructurePatchResult":{"anyOf":[{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"],"description":"Изисква повторно извикване с confirm."},"message":{"type":"string","description":"Човешко съобщение на български."},"confirmToken":{"type":"string","description":"Токен за полето confirm (валиден ~10 мин)."},"expiresInMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Минути до изтичане на токена."}},"required":["action","message","confirmToken","expiresInMinutes"],"additionalProperties":false,"description":"Двустъпков confirm при published exam или глобален pipeline write."},{"type":"object","properties":{"updated":{"type":"boolean","enum":[true]},"exam":{"type":"object","properties":{"id":{"type":"string","description":"Firestore document ID."},"title":{"nullable":true,"description":"Заглавие или null.","type":"string"},"displayTitle":{"type":"string","description":"Показвано заглавие в каталога."},"slug":{"type":"string","description":"URL slug."},"subject":{"type":"string","enum":["mathematics","bulgarian"],"description":"Предмет."},"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Основен клас."},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове (applicability)."},"examKind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"description":"Вид тест."},"officiality":{"type":"string","enum":["official","authored"],"description":"official или authored."},"year":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"academicYear":{"nullable":true,"type":"string"},"eventSeriesId":{"nullable":true,"type":"string"},"eventOccurrenceId":{"nullable":true,"type":"string"},"regulationVersionId":{"nullable":true,"type":"string"},"stageKey":{"nullable":true,"type":"string"},"variant":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"moduleIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"organizationKey":{"nullable":true,"type":"string"},"applicabilityKeys":{"type":"array","items":{"type":"string"}},"collectionIds":{"type":"array","items":{"type":"string"}},"primaryCollectionId":{"nullable":true,"type":"string"},"catalogStatus":{"type":"string","enum":["draft","published"]},"visibility":{"type":"string","enum":["private","public"]},"processingStatus":{"nullable":true,"description":"Статус на AI pipeline: uploaded | processing | processed | failed | paused. За polling след upload/process/reprocess. Не включва цена.","type":"string","enum":["uploaded","processing","processed","failed","paused"]},"processingStage":{"nullable":true,"description":"Текуща стъпка (structure, bounds, extract, answer, …) или null когато е готово.","type":"string"},"processingError":{"nullable":true,"description":"Съобщение при failed; иначе null.","type":"string"},"processingPageCount":{"nullable":true,"description":"Брой страници в PDF след ingest.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"humanReviewed":{"type":"boolean","description":"humanReview.status === 'reviewed' — филтрирай с search_exams humanReviewed."},"humanReview":{"nullable":true,"description":"„Проверен от човек“ маркер (admin UI); без uid/име (D11). null = никога не е маркиран.","type":"object","properties":{"status":{"type":"string","enum":["reviewed","unreviewed"]},"reviewedAt":{"nullable":true,"type":"string"},"changedAfterReview":{"type":"boolean","description":"true = проверен, но съдържанието му е променено след маркирането (D14)."}},"required":["status","reviewedAt","changedAfterReview"],"additionalProperties":false},"suggestedApplicability":{"description":"Предложена допълнителна applicability (само при GET единичен exam).","nullable":true,"type":"object","properties":{"grade":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kind":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"]}},"required":["grade","kind"],"additionalProperties":false}},"required":["id","title","displayTitle","slug","subject","grade","grades","examKind","officiality","year","academicYear","eventSeriesId","eventOccurrenceId","regulationVersionId","stageKey","variant","moduleIndex","organizationKey","applicabilityKeys","collectionIds","primaryCollectionId","catalogStatus","visibility","processingStatus","processingStage","processingError","processingPageCount","humanReviewed","humanReview"],"additionalProperties":false,"description":"Каталожно резюме без ключ и въпроси."},"scoring":{"type":"object","properties":{"scoringPolicy":{"type":"object","properties":{"wrongAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"blankAnswerPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"startingPoints":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["wrongAnswerPoints","blankAnswerPoints","startingPoints"],"additionalProperties":false,"description":"Точкуване при опит (не пипа точките по задачи)."},"timeLimitMinutes":{"type":"integer","minimum":1,"maximum":300},"scoringLocked":{"type":"boolean","description":"true = structure pass не презаписва pointRules/gradeRules/defaultPoints от PDF."},"defaultPoints":{"nullable":true,"type":"integer","minimum":1,"maximum":9007199254740991},"pointRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Начален номер на задача (включително)."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Краен номер на задача (включително)."},"points":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Точки за задачите в диапазона."}},"required":["from","to","points"],"additionalProperties":false}},"pointRulesText":{"type":"string","description":"Compact: 1-18:1; 19-20:2"},"gradeRules":{"type":"array","items":{"type":"object","properties":{"from":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Долен праг на сбор точки (включително)."},"to":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Горен праг на сбор точки (включително)."},"grade":{"type":"integer","minimum":2,"maximum":6,"description":"Оценка 2–6."}},"required":["from","to","grade"],"additionalProperties":false}},"gradeRulesText":{"type":"string","description":"Compact: 0-10:2; 11-15:3"},"answerKeyText":{"nullable":true,"description":"Ключ: 1 Б; 2 Г; 15 189","type":"string"},"mcOtherAnswerMode":{"type":"string","enum":["select_only","requires_text"],"description":"Режим на MC „Друго“ (exam doc). Default requires_text."},"mcOptionsLayout":{"type":"string","enum":["stacked","compact"],"description":"Подредба на MC опциите. Default stacked."},"mcAnswerLabelScheme":{"type":"string","enum":["cyrillic_upper","cyrillic_lower","latin_lower","latin_upper","numeric","custom"],"description":"Етикети на MC отговорите. Default cyrillic_upper."},"mcAnswerLabels":{"type":"array","items":{"type":"string"},"description":"Собствени етикети при scheme=custom; иначе []."},"notesEnabled":{"type":"boolean","description":"Бележки при решаване. Preschool (grade 0) → false."},"difficulty":{"nullable":true,"description":"Трудност 1–5; null = не е зададена.","type":"integer","minimum":1,"maximum":5},"subject":{"nullable":true,"description":"Предмет; null ако липсва в doc.","type":"string","enum":["mathematics","bulgarian"]}},"required":["scoringPolicy","timeLimitMinutes","scoringLocked","defaultPoints","pointRules","pointRulesText","gradeRules","gradeRulesText","answerKeyText","mcOtherAnswerMode","mcOptionsLayout","mcAnswerLabelScheme","mcAnswerLabels","notesEnabled","difficulty","subject"],"additionalProperties":false,"description":"Записаното точкуване след PATCH."},"applied":{"type":"object","properties":{"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой задачи с обновени точки (0 ако applyPoints=false)."},"answerKey":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой въпроси с overwrite от ключа (0 ако applyAnswerKey=false)."}},"required":["points","answerKey"],"additionalProperties":false},"skippedHumanLocked":{"description":"applyAnswerKey с skipLocked=true — задачите, пропуснати заради заключен отговор.","type":"array","items":{"type":"object","properties":{"questionId":{"type":"string"},"sequenceNumber":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"kinds":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]}}},"required":["questionId","sequenceNumber","kinds"],"additionalProperties":false,"description":"Заключени видове на една задача (D4). Кодовете: stem=Условие, solution=Решение, answer=Отговор, options=Опции, drawings=Чертежи, bounds=Граници."}}},"required":["updated","exam","scoring","applied"],"additionalProperties":false,"description":"Успешен PATCH на structure (без confirm)."}],"description":"PATCH structure — confirm или updated."},"CoverWrite":{"type":"object","properties":{"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","description":"HTTPS URL на изображение за импорт (препоръчително за MCP агенти)."}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1,"description":"Изображение като base64 (до 8 MB декодирано). За MCP агенти използвай малки файлове или предпочитай source.kind=url."}},"required":["kind","base64"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["legacy"]}},"required":["kind"],"additionalProperties":false}],"description":"Източник: url (препоръчително), base64 (малки файлове) или legacy."},"sources":{"type":"object","properties":{"thumb":{"description":"Източник само за миниатюра (1:1, списък).","oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","description":"HTTPS URL на изображение за импорт (препоръчително за MCP агенти)."}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1,"description":"Изображение като base64 (до 8 MB декодирано). За MCP агенти използвай малки файлове или предпочитай source.kind=url."}},"required":["kind","base64"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["legacy"]}},"required":["kind"],"additionalProperties":false}]},"header":{"description":"Източник само за header (16:5, детайл).","oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","description":"HTTPS URL на изображение за импорт (препоръчително за MCP агенти)."}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1,"description":"Изображение като base64 (до 8 MB декодирано). За MCP агенти използвай малки файлове или предпочитай source.kind=url."}},"required":["kind","base64"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["legacy"]}},"required":["kind"],"additionalProperties":false}]}},"additionalProperties":false},"crops":{"description":"Опционални изрязвания по вариант. Ако липсват, се ползва централно изрязване към aspect на варианта.","type":"object","properties":{"thumb":{"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"header":{"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"additionalProperties":false}},"additionalProperties":false},"Cover":{"type":"object","properties":{"originalUrl":{"nullable":true,"description":"HTTPS URL на оригиналното изображение в Mozak Storage.","type":"string"},"thumbUrl":{"nullable":true,"description":"HTTPS URL на миниатюрата за списъка.","type":"string"},"headerUrl":{"nullable":true,"description":"HTTPS URL на header за детайла.","type":"string"},"crops":{"type":"object","properties":{"thumb":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"header":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":32,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":32,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"required":["thumb","header"],"additionalProperties":false,"description":"Изрязвания по вариант (thumb и header са независими)."},"updatedAt":{"nullable":true,"description":"Кога е обновена корицата (ISO 8601).","type":"string"}},"required":["originalUrl","thumbUrl","headerUrl","crops","updatedAt"],"additionalProperties":false,"description":"Публични URL-и на корицата. Storage пътища не се връщат."},"ExamDecoration":{"type":"object","properties":{"id":{"type":"string"},"imageUrl":{"type":"string"},"horizontal":{"type":"string","enum":["left","middle","right"],"description":"Хоризонтална позиция: left / middle / right."},"vertical":{"type":"string","enum":["top","middle","bottom"],"description":"Вертикална позиция: top / middle / bottom."},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"description":"Размер на екрана (множител); по подразбиране 1.","type":"number","minimum":0.25,"maximum":5},"crop":{"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":1,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":1,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"imageWidth":{"type":"integer","minimum":0,"maximum":9007199254740991},"imageHeight":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","imageUrl","horizontal","vertical","opacity","imageWidth","imageHeight"],"additionalProperties":false},"ExamDecorationAdd":{"type":"object","properties":{"examId":{"description":"Ако липсва — глобално; ако е подаден — собствен списък за този тест.","type":"string","minLength":1},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","description":"HTTPS URL на изображение (препоръчително за MCP агенти)."}},"required":["kind","url"]},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1,"description":"Изображение като base64 (до 8 MB декодирано). Предпочитай source.kind=url."}},"required":["kind","base64"]}],"description":"Източник: url (препоръчително) или base64 (малки файлове)."},"horizontal":{"type":"string","enum":["left","middle","right"],"description":"Хоризонтална позиция: left / middle / right."},"vertical":{"type":"string","enum":["top","middle","bottom"],"description":"Вертикална позиция: top / middle / bottom."},"opacity":{"description":"Прозрачност 0–1; подразбиране 1.","type":"number","minimum":0,"maximum":1},"scale":{"description":"Размер на екрана (множител 0.25–5); подразбиране 1.","type":"number","minimum":0.25,"maximum":5},"crop":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":1,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":1,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."}},"required":["source"]},"ExamDecorationAddBatch":{"type":"object","properties":{"examId":{"type":"string","minLength":1},"horizontal":{"type":"string","enum":["left","middle","right"],"description":"Хоризонтална позиция: left / middle / right."},"vertical":{"type":"string","enum":["top","middle","bottom"],"description":"Вертикална позиция: top / middle / bottom."},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","minimum":0.25,"maximum":5},"crop":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":1,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":1,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"sources":{"minItems":1,"maxItems":12,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri","description":"HTTPS URL на изображение (препоръчително за MCP агенти)."}},"required":["kind","url"]},{"type":"object","properties":{"kind":{"type":"string","enum":["base64"]},"base64":{"type":"string","minLength":1,"description":"Изображение като base64 (до 8 MB декодирано). Предпочитай source.kind=url."}},"required":["kind","base64"]}],"description":"Източник: url (препоръчително) или base64 (малки файлове)."},"description":"Едно или повече изображения (общо до лимита на списъка)."}},"required":["sources"],"additionalProperties":false},"ExamDecorationUpdate":{"type":"object","properties":{"examId":{"type":"string","minLength":1},"horizontal":{"type":"string","enum":["left","middle","right"],"description":"Хоризонтална позиция: left / middle / right."},"vertical":{"type":"string","enum":["top","middle","bottom"],"description":"Вертикална позиция: top / middle / bottom."},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","minimum":0.25,"maximum":5},"crop":{"nullable":true,"type":"object","properties":{"x":{"type":"number","description":"X на изрязването в пиксели спрямо оригинала."},"y":{"type":"number","description":"Y на изрязването в пиксели спрямо оригинала."},"width":{"type":"number","minimum":1,"description":"Ширина на изрязването в пиксели."},"height":{"type":"number","minimum":1,"description":"Височина на изрязването в пиксели."}},"required":["x","y","width","height"],"additionalProperties":false,"description":"Правоъгълник за изрязване спрямо оригиналното изображение."},"clearCrop":{"description":"Ако е true — премахва изрязването (цялото изображение).","type":"boolean"}}},"QuestionSummary":{"type":"object","properties":{"id":{"type":"string","description":"ID на задачата."},"originExamId":{"nullable":true,"description":"Тестът, от който е родена задачата.","type":"string"},"origin":{"type":"object","properties":{"displayTitle":{"nullable":true,"description":"Заглавие на origin теста.","type":"string"},"grade":{"nullable":true,"description":"Основен клас.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове."},"subject":{"nullable":true,"description":"Предмет.","type":"string"},"examKind":{"nullable":true,"description":"Вид тест.","type":"string"},"year":{"nullable":true,"description":"Година.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"officiality":{"nullable":true,"description":"Официалност.","type":"string"},"eventSeriesId":{"nullable":true,"description":"Серия състезание.","type":"string"},"difficulty":{"nullable":true,"description":"Трудност 1–5.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processingStatus":{"nullable":true,"description":"Статус на pipeline.","type":"string"}},"required":["displayTitle","grade","grades","subject","examKind","year","officiality","eventSeriesId","difficulty","processingStatus"],"additionalProperties":false,"description":"Денормализиран snapshot от origin теста."},"problemText":{"nullable":true,"description":"Условие (plain text).","type":"string"},"problemRichText":{"nullable":true,"description":"Условие (rich markdown).","type":"string"},"systemTagIds":{"type":"array","items":{"type":"string"},"description":"Системни тагове."},"stats":{"type":"object","properties":{"attemptCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой опити."},"correctCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой верни отговори."},"incorrectCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой грешни отговори."},"skippedCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой пропуснати."},"correctRate":{"description":"correctCount / attemptCount, или null ако няма опити.","nullable":true,"type":"number"}},"required":["attemptCount","correctCount","incorrectCount","skippedCount"],"additionalProperties":false,"description":"Глобални статистики за задачата."},"hasHint":{"type":"boolean"},"hasSolution":{"type":"boolean"},"hasParts":{"type":"boolean"},"hasCrop":{"type":"boolean"},"cropUrl":{"nullable":true,"description":"Signed URL към crop (≈15 мин).","type":"string"},"membership":{"type":"object","properties":{"order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ред в теста."},"sequenceNumber":{"nullable":true,"description":"Номер в бланката.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points":{"type":"number","description":"Точки в този тест."}},"required":["order","sequenceNumber","points"],"additionalProperties":false,"description":"Членство в exams/{examId}/items (само при филтър examId)."}},"required":["id","originExamId","origin","problemText","problemRichText","systemTagIds","stats","hasHint","hasSolution","hasParts","hasCrop","cropUrl"],"additionalProperties":false,"description":"Резюме на задача без ключове/решение."},"QuestionList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"ID на задачата."},"originExamId":{"nullable":true,"description":"Тестът, от който е родена задачата.","type":"string"},"origin":{"type":"object","properties":{"displayTitle":{"nullable":true,"description":"Заглавие на origin теста.","type":"string"},"grade":{"nullable":true,"description":"Основен клас.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове."},"subject":{"nullable":true,"description":"Предмет.","type":"string"},"examKind":{"nullable":true,"description":"Вид тест.","type":"string"},"year":{"nullable":true,"description":"Година.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"officiality":{"nullable":true,"description":"Официалност.","type":"string"},"eventSeriesId":{"nullable":true,"description":"Серия състезание.","type":"string"},"difficulty":{"nullable":true,"description":"Трудност 1–5.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processingStatus":{"nullable":true,"description":"Статус на pipeline.","type":"string"}},"required":["displayTitle","grade","grades","subject","examKind","year","officiality","eventSeriesId","difficulty","processingStatus"],"additionalProperties":false,"description":"Денормализиран snapshot от origin теста."},"problemText":{"nullable":true,"description":"Условие (plain text).","type":"string"},"problemRichText":{"nullable":true,"description":"Условие (rich markdown).","type":"string"},"systemTagIds":{"type":"array","items":{"type":"string"},"description":"Системни тагове."},"stats":{"type":"object","properties":{"attemptCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой опити."},"correctCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой верни отговори."},"incorrectCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой грешни отговори."},"skippedCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой пропуснати."},"correctRate":{"description":"correctCount / attemptCount, или null ако няма опити.","nullable":true,"type":"number"}},"required":["attemptCount","correctCount","incorrectCount","skippedCount"],"additionalProperties":false,"description":"Глобални статистики за задачата."},"hasHint":{"type":"boolean"},"hasSolution":{"type":"boolean"},"hasParts":{"type":"boolean"},"hasCrop":{"type":"boolean"},"cropUrl":{"nullable":true,"description":"Signed URL към crop (≈15 мин).","type":"string"},"membership":{"type":"object","properties":{"order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ред в теста."},"sequenceNumber":{"nullable":true,"description":"Номер в бланката.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points":{"type":"number","description":"Точки в този тест."}},"required":["order","sequenceNumber","points"],"additionalProperties":false,"description":"Членство в exams/{examId}/items (само при филтър examId)."}},"required":["id","originExamId","origin","problemText","problemRichText","systemTagIds","stats","hasHint","hasSolution","hasParts","hasCrop","cropUrl"],"additionalProperties":false,"description":"Резюме на задача без ключове/решение."},"description":"Списък задачи."},"pagination":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"nextCursor":{"nullable":true,"type":"string"}},"required":["limit","nextCursor"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false,"description":"Страница с задачи."},"QuestionDetail":{"type":"object","properties":{"id":{"type":"string","description":"ID на задачата."},"originExamId":{"nullable":true,"description":"Тестът, от който е родена задачата.","type":"string"},"origin":{"type":"object","properties":{"displayTitle":{"nullable":true,"description":"Заглавие на origin теста.","type":"string"},"grade":{"nullable":true,"description":"Основен клас.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"grades":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Всички класове."},"subject":{"nullable":true,"description":"Предмет.","type":"string"},"examKind":{"nullable":true,"description":"Вид тест.","type":"string"},"year":{"nullable":true,"description":"Година.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"officiality":{"nullable":true,"description":"Официалност.","type":"string"},"eventSeriesId":{"nullable":true,"description":"Серия състезание.","type":"string"},"difficulty":{"nullable":true,"description":"Трудност 1–5.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processingStatus":{"nullable":true,"description":"Статус на pipeline.","type":"string"}},"required":["displayTitle","grade","grades","subject","examKind","year","officiality","eventSeriesId","difficulty","processingStatus"],"additionalProperties":false,"description":"Денормализиран snapshot от origin теста."},"problemText":{"nullable":true,"description":"Условие (plain text).","type":"string"},"problemRichText":{"nullable":true,"description":"Условие (rich markdown).","type":"string"},"systemTagIds":{"type":"array","items":{"type":"string"},"description":"Системни тагове."},"stats":{"type":"object","properties":{"attemptCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой опити."},"correctCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой верни отговори."},"incorrectCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой грешни отговори."},"skippedCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой пропуснати."},"correctRate":{"description":"correctCount / attemptCount, или null ако няма опити.","nullable":true,"type":"number"}},"required":["attemptCount","correctCount","incorrectCount","skippedCount"],"additionalProperties":false,"description":"Глобални статистики за задачата."},"hasHint":{"type":"boolean"},"hasSolution":{"type":"boolean"},"hasParts":{"type":"boolean"},"hasCrop":{"type":"boolean"},"cropUrl":{"nullable":true,"description":"Signed URL към crop (≈15 мин).","type":"string"},"membership":{"type":"object","properties":{"order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Ред в теста."},"sequenceNumber":{"nullable":true,"description":"Номер в бланката.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points":{"type":"number","description":"Точки в този тест."}},"required":["order","sequenceNumber","points"],"additionalProperties":false,"description":"Членство в exams/{examId}/items (само при филтър examId)."},"problemRichTextEdited":{"nullable":true,"description":"Редактирано rich условие.","type":"string"},"answerMetricKind":{"nullable":true,"description":"Вид метрика на отговора.","type":"string"},"siUnitType":{"nullable":true,"description":"SI единица (ако има).","type":"string"},"answerOptions":{"nullable":true,"description":"Варианти за избор (без correctOptionIndex).","type":"array","items":{"type":"string"}},"mcOtherDisabled":{"type":"boolean","description":"true = тази задача няма «Друго», независимо от режима на теста."},"mcSelectMultiple":{"type":"boolean","description":"true = ученикът избира няколко варианта. Ключът не е в този отговор."},"sections":{"nullable":true,"type":"array","items":{"type":"object","additionalProperties":{}}},"drawings":{"nullable":true,"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cropUrl":{"nullable":true,"type":"string"}},"required":["cropUrl"],"additionalProperties":{}}},"solutionLocked":{"nullable":true,"description":"Админ заключване на решението (legacy — виж humanLocks).","type":"boolean"},"humanLocks":{"type":"array","items":{"type":"string","enum":["stem","solution","answer","options","drawings","bounds"]},"description":"Заключени видове от ръчна редакция в админ UI (D4); [] = незаключена."},"humanReviewed":{"type":"boolean","description":"Отметка „проверена“ на задачата (D12)."},"solutionVisibleToLearners":{"nullable":true,"description":"Дали учениците виждат решението.","type":"boolean"},"answerOptionRegions":{"nullable":true,"description":"„Отговори върху чертежа“: зона на всеки MC вариант (подравнено с answerOptions).","type":"array","items":{"nullable":true,"type":"object","properties":{"drawingIndex":{"type":"integer","minimum":1,"maximum":12,"description":"1-базиран номер на чертежа."},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":0.03,"maximum":1},"height":{"type":"number","minimum":0.03,"maximum":1}},"required":["drawingIndex","x","y","width","height"],"additionalProperties":false}},"answerOptionRegionsSource":{"nullable":true,"description":"ai = от pipeline стъпката; admin = ръчно / API (не се презаписва от pipeline).","type":"string"},"mcOnDrawing":{"nullable":true,"description":"Последно изпълнение на стъпката: applied | notApplicable | failed | skipped.","type":"object","properties":{"status":{"type":"string"},"reason":{"type":"string"}},"required":["status","reason"],"additionalProperties":false}},"required":["id","originExamId","origin","problemText","problemRichText","systemTagIds","stats","hasHint","hasSolution","hasParts","hasCrop","cropUrl","problemRichTextEdited","answerMetricKind","siUnitType","answerOptions","mcOtherDisabled","mcSelectMultiple","sections","drawings","solutionLocked","humanLocks","humanReviewed","solutionVisibleToLearners","answerOptionRegions","answerOptionRegionsSource","mcOnDrawing"],"additionalProperties":false,"description":"Детайл на задача без ключове/решение."},"QuestionStats":{"type":"object","properties":{"attemptCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой опити."},"correctCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой верни отговори."},"incorrectCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой грешни отговори."},"skippedCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Брой пропуснати."},"correctRate":{"description":"correctCount / attemptCount, или null ако няма опити.","nullable":true,"type":"number"}},"required":["attemptCount","correctCount","incorrectCount","skippedCount"],"additionalProperties":false,"description":"Статистики за една задача."},"QuestionSolution":{"type":"object","properties":{"questionId":{"type":"string"},"hint":{"nullable":true,"type":"string"},"solution":{"nullable":true,"type":"string"},"correctAnswer":{"nullable":true,"type":"string"},"correctOptionIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"correctOptionIndices":{"nullable":true,"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"mcSelectMultiple":{"type":"boolean"},"otherOptionIndex":{"nullable":true,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"mcOtherDisabled":{"type":"boolean","description":"true = тази задача няма «Друго», независимо от режима на теста."},"acceptedAnswers":{"nullable":true,"type":"array","items":{}},"correctAnswerDisplay":{"nullable":true,"type":"string"},"expectedNumericValue":{"nullable":true,"type":"number"},"sections":{"nullable":true,"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["questionId","hint","solution","correctAnswer","correctOptionIndex","correctOptionIndices","mcSelectMultiple","otherOptionIndex","mcOtherDisabled","acceptedAnswers","correctAnswerDisplay","expectedNumericValue","sections"],"additionalProperties":false,"description":"Привилегировано решение и ключове (questions:inspect)."},"QuestionSolutionPatch":{"type":"object","properties":{"solution":{"description":"Задай решение (trim). null или \"\" изтрива полето.","nullable":true,"type":"string","maxLength":50000},"hint":{"description":"Задай подсказка (trim). null или \"\" изтрива полето.","nullable":true,"type":"string","maxLength":20000},"clearSolution":{"description":"true = изтрий solution (FieldValue.delete).","type":"boolean"},"clearHint":{"description":"true = изтрий hint (FieldValue.delete).","type":"boolean"},"parts":{"description":"Per-part solution/hint. Изисква задача със sections/items.","minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"idOrLabel":{"type":"string","minLength":1,"description":"id или label на част (matchSolvePartKey)."},"solution":{"description":"Задай решение (trim). null или \"\" изтрива полето.","nullable":true,"type":"string","maxLength":50000},"hint":{"description":"Задай подсказка (trim). null или \"\" изтрива полето.","nullable":true,"type":"string","maxLength":20000},"clearSolution":{"description":"true = изтрий solution (FieldValue.delete).","type":"boolean"},"clearHint":{"description":"true = изтрий hint (FieldValue.delete).","type":"boolean"}},"required":["idOrLabel"],"additionalProperties":false}},"confirm":{"description":"Токен при публикуван origin тест (като structure PATCH). Без него → confirmation_required.","type":"string","minLength":1}},"additionalProperties":false},"QuestionAnswerOptionRegionsPatch":{"type":"object","properties":{"regions":{"nullable":true,"description":"По една зона на MC вариант в реда на answerOptions (варианти само от една главна буква). null = изключи.","minItems":2,"maxItems":8,"type":"array","items":{"type":"object","properties":{"drawingIndex":{"type":"integer","minimum":1,"maximum":12,"description":"1-базиран номер на чертежа."},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":0.03,"maximum":1},"height":{"type":"number","minimum":0.03,"maximum":1}},"required":["drawingIndex","x","y","width","height"],"additionalProperties":false}},"confirm":{"description":"Токен при публикуван origin тест.","type":"string","minLength":1}},"required":["regions"],"additionalProperties":false,"description":"„Отговори върху чертежа“: задай или изчисти зоните (източник admin)."},"QuestionAnswerOptionRegionsPatchResult":{"type":"object","properties":{"id":{"type":"string"},"answerOptionRegions":{"nullable":true,"type":"array","items":{"type":"object","properties":{"drawingIndex":{"type":"integer","minimum":1,"maximum":12,"description":"1-базиран номер на чертежа."},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":0.03,"maximum":1},"height":{"type":"number","minimum":0.03,"maximum":1}},"required":["drawingIndex","x","y","width","height"],"additionalProperties":false}}},"required":["id","answerOptionRegions"],"additionalProperties":false,"description":"Записани зони."},"QuestionSolutionVisibilityPatch":{"type":"object","properties":{"visible":{"type":"boolean","description":"true = показвай hint/solution на ученици; false = скрий (текстът остава)."},"confirm":{"description":"Токен при публикуван origin тест.","type":"string","minLength":1}},"required":["visible"],"additionalProperties":false,"description":"Показва или скрива решението за learners без да трие текста."},"QuestionSolutionVisibilityPatchResult":{"type":"object","properties":{"id":{"type":"string"},"solutionVisibleToLearners":{"type":"boolean"}},"required":["id","solutionVisibleToLearners"],"additionalProperties":false,"description":"Резултат от visibility toggle."},"QuestionDrawings":{"type":"object","properties":{"questionId":{"type":"string"},"originExamId":{"nullable":true,"type":"string"},"drawings":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"1 = `drawing`, 2 = `drawing-2`, …"},"storagePath":{"nullable":true,"type":"string"},"url":{"nullable":true,"description":"Подписан URL (1ч) към текущия PNG.","type":"string"},"hasOriginal":{"type":"boolean","description":"Има запазен оригинал (сурова изрезка преди почистване/подобряване)."},"originalUrl":{"nullable":true,"description":"Подписан URL (1ч) към оригинала.","type":"string"},"bounds":{"nullable":true,"description":"Кутия на фигурата спрямо изрезката (0–1).","type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"}},"required":["x","y","width","height"],"additionalProperties":false}},"required":["index","storagePath","url","hasOriginal","originalUrl","bounds"],"additionalProperties":false}}},"required":["questionId","originExamId","drawings"],"additionalProperties":false,"description":"Чертежите на задача."},"QuestionDrawingChangeResult":{"anyOf":[{"type":"object","properties":{"questionId":{"type":"string"},"drawingIndex":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"mode":{"type":"string","enum":["edit","clean","redraw","restoreOriginal"]},"committed":{"type":"boolean"},"url":{"nullable":true,"description":"Подписан URL (1ч) на записания PNG (при commit).","type":"string"},"hasOriginal":{"type":"boolean","description":"Има запазен оригинал (restore е възможен)."},"previewId":{"description":"Само при преглед: подай го с commit=true, за да запишеш точно този резултат.","type":"string"},"previewUrl":{"description":"Само при преглед: подписан URL (1ч) към прегледа.","nullable":true,"type":"string"},"previewPngBase64":{"description":"PNG (base64) — само при includePng=true.","type":"string"}},"required":["questionId","drawingIndex","mode","committed","url","hasOriginal"],"additionalProperties":false},{"type":"object","properties":{"action":{"type":"string","enum":["confirmation_required"]},"confirmToken":{"type":"string"},"expiresInMinutes":{"type":"number"},"message":{"type":"string"}},"required":["action","confirmToken","expiresInMinutes","message"],"additionalProperties":false}],"description":"Резултат от промяна на чертеж (или confirmation_required при публикуван тест)."},"QuestionDrawingUpload":{"type":"object","properties":{"pngBase64":{"type":"string","minLength":40,"maxLength":7500000,"description":"Нов PNG на чертежа, base64 (до 5 MB декодиран; допуска data:image/png;base64, префикс)."},"confirm":{"description":"Confirm токен при публикуван origin тест (първо извикай без него → confirmation_required).","type":"string","minLength":1},"includePng":{"description":"Върни и PNG-то като base64 (по подразбиране само подписан url / previewUrl).","type":"boolean"}},"required":["pngBase64"],"additionalProperties":false},"QuestionDrawingClean":{"type":"object","properties":{"commit":{"description":"true = запиши; false/липсва = само преглед (previewPngBase64), нищо не се пази.","type":"boolean"},"contrast":{"description":"Контраст: 1 = без промяна … 2 = силно (по подразбиране 1.2).","type":"number","minimum":1,"maximum":2},"lineDarken":{"description":"Потъмняване на линиите: 1 = без промяна … 0.7 = много тъмни (по подразбиране 0.95).","type":"number","minimum":0.7,"maximum":1},"bgTolerance":{"description":"Праг за хартия: колко различен цвят още е фон (0–80, по подразбиране 28).","type":"integer","minimum":0,"maximum":80},"saturation":{"description":"Наситеност на рисунката (не на фона): −100 = черно-бяло, 0 = без промяна, 100 = двойна (по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"vibrance":{"description":"Vibrance: като наситеността, но действа най-силно на бледите цветове (−100…100, по подразбиране 0).","type":"integer","minimum":-100,"maximum":100},"source":{"description":"От какво да се почисти: current (текущия PNG, по подразбиране) или original (запазената сурова изрезка — без натрупване, ако чертежът вече е почистен автоматично).","type":"string","enum":["current","original"]},"enhance":{"description":"false = без контраст/потъмняване (напр. само прозрачност). По подразбиране true.","type":"boolean"},"transparentBackground":{"description":"Хартията (фонът) става прозрачна.","type":"boolean"},"transparentBackgroundWholeImage":{"description":"Целият бял фон прозрачен (включително заграден от рисунката, не само отстрани). Има смисъл само с transparentBackground: true; без него се игнорира. По подразбиране false.","type":"boolean"},"regions":{"description":"Почисти само в тези правоъгълници (0–1 спрямо чертежа). Празно = целия чертеж.","maxItems":12,"type":"array","items":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":0.01,"maximum":1},"height":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","width","height"],"additionalProperties":false}},"previewPngBase64":{"description":"При commit: запиши този PNG (base64) вместо да се изчислява наново. За MCP предпочитай previewId.","type":"string","maxLength":7500000},"previewId":{"description":"При commit: запиши точно прегледа от предишно извикване с commit=false (previewId от отговора) — без нов AI разход.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"confirm":{"description":"Confirm токен при публикуван origin тест (първо извикай без него → confirmation_required).","type":"string","minLength":1},"includePng":{"description":"Върни и PNG-то като base64 (по подразбиране само подписан url / previewUrl).","type":"boolean"}},"additionalProperties":false},"QuestionDrawingRedraw":{"type":"object","properties":{"commit":{"description":"true = запиши; false/липсва = само преглед (previewPngBase64), нищо не се пази.","type":"boolean"},"prompt":{"description":"Инструкции за AI прерисуването (по желание).","type":"string","maxLength":4000},"provider":{"description":"Модел за изображения (по подразбиране gemini).","type":"string","enum":["gemini","openai"]},"includeProblemStem":{"description":"Добави условието на задачата към промпта (по подразбиране true).","type":"boolean"},"referenceDrawingIndexes":{"description":"Други чертежи на същата задача (1 = drawing, 2 = drawing-2, …), изпратени като референтни изображения. Празно = без референции.","maxItems":8,"type":"array","items":{"type":"integer","minimum":1,"maximum":12}},"referenceImagePaths":{"description":"Други изображения от задачата (картинки на токени / платно) по storage път. Само пътища, които принадлежат на задачата.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":500}},"transparentBackground":{"description":"Хартията (фонът) става прозрачна.","type":"boolean"},"previewPngBase64":{"description":"При commit: запиши този PNG (base64) вместо да се изчислява наново. За MCP предпочитай previewId.","type":"string","maxLength":7500000},"previewId":{"description":"При commit: запиши точно прегледа от предишно извикване с commit=false (previewId от отговора) — без нов AI разход.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"confirm":{"description":"Confirm токен при публикуван origin тест (първо извикай без него → confirmation_required).","type":"string","minLength":1},"includePng":{"description":"Върни и PNG-то като base64 (по подразбиране само подписан url / previewUrl).","type":"boolean"}},"additionalProperties":false},"QuestionDrawingRestore":{"type":"object","properties":{"commit":{"description":"true = запиши; false/липсва = само преглед (previewPngBase64), нищо не се пази.","type":"boolean"},"confirm":{"description":"Confirm токен при публикуван origin тест (първо извикай без него → confirmation_required).","type":"string","minLength":1},"includePng":{"description":"Върни и PNG-то като base64 (по подразбиране само подписан url / previewUrl).","type":"boolean"}},"additionalProperties":false},"QuestionTagsPatch":{"type":"object","properties":{"addTagIds":{"description":"Системни тагове за добавяне (merge).","maxItems":20,"type":"array","items":{"type":"string","minLength":1}},"removeTagIds":{"description":"Системни тагове за премахване.","maxItems":20,"type":"array","items":{"type":"string","minLength":1}},"dryRun":{"description":"Ако true — валидира и връща резултат без запис.","type":"boolean"}},"additionalProperties":false},"QuestionTagsPatchResult":{"type":"object","properties":{"id":{"type":"string"},"systemTagIds":{"type":"array","items":{"type":"string"}},"added":{"type":"array","items":{"type":"string"}},"removed":{"type":"array","items":{"type":"string"}},"dryRun":{"type":"boolean"}},"required":["id","systemTagIds","added","removed","dryRun"],"additionalProperties":false,"description":"Резултат от merge на системни тагове."},"QuestionAdminNote":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"createdAt":{"nullable":true,"description":"ISO време на записа.","type":"string"},"createdByUid":{"type":"string"},"createdByLabel":{"type":"string"},"source":{"type":"string","enum":["ui","mcp"]}},"required":["id","text","createdAt","createdByUid","createdByLabel","source"],"additionalProperties":false,"description":"Админ бележка към задача (само за админи и коректори)."},"QuestionAdminNoteList":{"type":"object","properties":{"id":{"type":"string","description":"question id"},"notes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"createdAt":{"nullable":true,"description":"ISO време на записа.","type":"string"},"createdByUid":{"type":"string"},"createdByLabel":{"type":"string"},"source":{"type":"string","enum":["ui","mcp"]}},"required":["id","text","createdAt","createdByUid","createdByLabel","source"],"additionalProperties":false,"description":"Админ бележка към задача (само за админи и коректори)."}}},"required":["id","notes"],"additionalProperties":false,"description":"Бележки към задача, най-старата първа."},"QuestionAdminNoteCreate":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":4000,"description":"Текст за човека, който проверява задачата."}},"required":["text"],"additionalProperties":false,"description":"Нова админ бележка."},"QuestionAdminNoteDelete":{"type":"object","properties":{"id":{"type":"string"},"noteId":{"type":"string"},"deleted":{"type":"boolean","enum":[true]}},"required":["id","noteId","deleted"],"additionalProperties":false,"description":"Изтрита админ бележка."},"TaxonomyNodeCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"axis":{"type":"string","enum":["theme","story","skill"]},"parentId":{"nullable":true,"type":"string","minLength":1},"code":{"nullable":true,"type":"string","minLength":1,"maxLength":40},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":{"nullable":true,"type":"string","maxLength":280},"color":{"type":"string","minLength":1,"maxLength":20}},"required":["name","axis"],"additionalProperties":false},"TaxonomyNodePatch":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"description":{"nullable":true,"type":"string","maxLength":280},"color":{"type":"string","minLength":1,"maxLength":20},"code":{"nullable":true,"type":"string","minLength":1,"maxLength":40},"sortOrder":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"additionalProperties":false},"TaxonomyNodeMove":{"type":"object","properties":{"parentId":{"nullable":true,"type":"string","minLength":1}},"required":["parentId"],"additionalProperties":false},"TaxonomyNodeArchive":{"type":"object","properties":{"archived":{"type":"boolean"}},"additionalProperties":false},"TaxonomyNodeMerge":{"type":"object","properties":{"toTagId":{"type":"string","minLength":1}},"required":["toTagId"],"additionalProperties":false},"QuestionClassificationPut":{"type":"object","properties":{"themes":{"maxItems":4,"type":"array","items":{"type":"object","properties":{"tagId":{"type":"string","minLength":1},"rank":{"type":"integer","minimum":1,"maximum":8}},"required":["tagId","rank"],"additionalProperties":false}},"storyTagId":{"nullable":true,"type":"string","minLength":1},"skillTagIds":{"maxItems":2,"type":"array","items":{"type":"string","minLength":1}},"confidence":{"nullable":true,"type":"number","minimum":0,"maximum":1},"source":{"type":"string","enum":["ai","human","import"]}},"required":["themes"],"additionalProperties":false},"QuestionClassifyBody":{"type":"object","properties":{"questionIds":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}}},"additionalProperties":false},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}},"security":[{"ApiKeyHeader":[]},{"BearerAuth":[]},{"ApiKeyQuery":[]}],"paths":{"/":{"get":{"tags":["System"],"summary":"API landing page","security":[],"responses":{"200":{"description":"HTML landing page"}}}},"/postman.json":{"get":{"tags":["System"],"summary":"Postman collection","security":[],"responses":{"200":{"description":"Postman Collection v2.1 JSON"}}}},"/health":{"get":{"tags":["System"],"summary":"Health check","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}}}}}}}},"/v1/competitions":{"get":{"tags":["Competitions"],"summary":"List competitions","description":"Списък серии. Параметър q: думите се търсят с AND (не е нужно да са съседни); фраза в кавички е точно съвпадение.","parameters":[{"name":"subject","in":"query","description":"Филтър по предмет: mathematics (математика) или bulgarian (български език).","schema":{"type":"string","enum":["mathematics","bulgarian"],"default":"<string>"}},{"name":"scope","in":"query","description":"Обхват на състезанието: school (училищно), city (градско), national (национално) или international (международно).","schema":{"type":"string","enum":["school","city","national","international"],"default":"<string>"}},{"name":"slug","in":"query","description":"Точно съвпадение по URL slug (kebab-case, напр. kangaroo-math).","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","default":"<string>"}},{"name":"q","in":"query","description":"Свободен текст (до 120 символа). Думите се търсят поотделно с AND — всички трябва да се срещнат, не е нужно да са съседни (напр. матем хитър). Фраза в кавички изисква точно съвпадение на тази последователност (напр. \"хитър петър\"). Търсенето е без значение на главни/малки букви. Синоними: МБГ/MWB → „Математика без граници“.","schema":{"type":"string","maxLength":120,"default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"List of competitions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompetitionList"}}}},"401":{"description":"Unauthorized"}}},"post":{"tags":["Competitions"],"summary":"Create competition","description":"Създава нова серия състезание (eventSeries). Slug е по избор — ако липсва, се генерира от заглавието.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompetitionWrite"},"examples":{"minimal":{"summary":"Минимален пример (задължителни полета)","value":{"subject":"mathematics","title":"Коледно състезание","scope":"national","difficulty":3,"price":{"type":"free"}}},"full":{"summary":"Пълен пример с класове, кръгове и организатори","value":{"subject":"mathematics","title":"Национална олимпиада — областен кръг","slug":"nacionalna-olimpiada-oblasten","scope":"national","difficulty":4,"regulationsMarkdown":"## Правила\n\n- Без калкулатор\n- 4 часа","regulationsSummary":"Областен кръг на националната олимпиада по математика.","defaultLocationText":"Учебна сграда","defaultCity":"Пловдив","defaultMapsUrl":"https://maps.google.com/?q=Plovdiv","defaultVenues":[{"city":"Пловдив","place":"Учебна сграда","mapsUrl":"https://maps.google.com/?q=Plovdiv","gradesNote":"5–12 клас","isPrimary":true}],"price":{"type":"free"},"registrationInfo":"Записване през училището до **1 април**.","registrationDeadlineAt":"2027-04-01T12:00:00+03:00","gradesMin":5,"gradesMax":12,"officialUrl":"https://example.com/olympiad","organizers":[{"name":"МОН","role":"Организатор","email":"info@example.com","phone":null}],"participationMode":"individual","roundType":"regional","groupSlug":"nom-math","groupTitle":"НОМ по математика","roundOrder":2,"defaultDateMode":"sitting","heldOnlyInCity":"Пловдив"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Competition"}}}},"401":{"description":"Unauthorized"},"409":{"description":"Conflict"}}}},"/v1/competitions/{id}":{"get":{"tags":["Competitions"],"summary":"Get competition","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"include","in":"query","description":"Вложен списък в отговора: editions (издания) или collections (свързани колекции с linkRole).","schema":{"type":"string","enum":["editions","collections"],"default":"<string>"}}],"responses":{"200":{"description":"Competition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Competition"}}}},"404":{"description":"Not found"}}},"patch":{"tags":["Competitions"],"summary":"Update competition","description":"Частична промяна на серия. Подай поне едно поле.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompetitionPatch"},"examples":{"partial":{"summary":"Пример за частична промяна (PATCH)","value":{"title":"Национална олимпиада — областен кръг (обновено)","difficulty":5,"price":{"type":"paid","amountEur":15,"note":"Такса за правоучастие"}}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Competition"}}}},"404":{"description":"Not found"}}},"delete":{"tags":["Competitions"],"summary":"Delete competition","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"responses":{"204":{"description":"Deleted"}}}},"/v1/competitions/{id}/cover":{"post":{"tags":["Competitions"],"summary":"Set competition cover","description":"Requires calendar:write. Импортира изображение (HTTPS URL или base64 до 8 MB) в Mozak Storage и генерира thumb (128×128, 1:1) и header (16:5, макс. 1200px). Storage пътища не се връщат.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverWrite"},"examples":{"fromUrl":{"summary":"Импорт от HTTPS URL","value":{"source":{"kind":"url","url":"https://example.com/covers/olympiad.jpg"}}},"fromLegacy":{"summary":"Генерирай варианти от вече качен Storage файл","value":{"source":{"kind":"legacy"}}}}}}},"responses":{"200":{"description":"Processed cover URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cover"}}}},"404":{"description":"Not found"}}},"delete":{"tags":["Competitions"],"summary":"Clear competition cover","description":"Requires calendar:write. Изтрива файловете от Storage и нулира cover.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"responses":{"204":{"description":"Cleared"}}}},"/v1/competitions/{id}/editions":{"get":{"tags":["Editions"],"summary":"List editions for competition","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"status","in":"query","description":"Филтър по статус на изданието: draft (чернова) или published (публикувано).","schema":{"type":"string","enum":["draft","published"],"default":"<string>"}},{"name":"from","in":"query","description":"Начало на времеви интервал (ISO 8601 с часова зона, напр. 2026-03-01T00:00:00+02:00).","schema":{"type":"string","format":"date-time","default":"<dateTime>"}},{"name":"to","in":"query","description":"Край на времеви интервал (ISO 8601 с часова зона). Включва издания, започващи преди този момент.","schema":{"type":"string","format":"date-time","default":"<dateTime>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Edition list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionList"}}}},"404":{"description":"Competition not found"}}},"post":{"tags":["Editions"],"summary":"Create edition","description":"Създава издание (eventOccurrence) за дадена серия.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionWrite"},"examples":{"minimal":{"summary":"Минимален пример (часово събитие)","value":{"startAt":"2027-04-12T10:00:00+03:00","endAt":"2027-04-12T14:00:00+03:00","allDay":false,"status":"published"}},"multiDay":{"summary":"Многодневно събитие с отделен изпитен час","value":{"startAt":"2027-10-10T00:00:00+03:00","endAt":"2027-10-12T23:59:59+03:00","allDay":true,"dateMode":"multi_day_event","examStartAt":"2027-10-11T09:00:00+03:00","examEndAt":"2027-10-11T13:00:00+03:00","venuesNote":"В собственото училище","price":{"type":"paid","amountEur":12,"note":null},"status":"published"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Edition"}}}},"404":{"description":"Competition not found"}}}},"/v1/competitions/{id}/editions/{editionId}":{"get":{"tags":["Editions"],"summary":"Get edition","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"editionId","in":"path","required":true,"description":"Идентификатор на изданието (Firestore document ID).","schema":{"type":"string","example":"def456","default":"<string>"},"example":"def456"}],"responses":{"200":{"description":"Edition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Edition"}}}},"404":{"description":"Not found"}}},"patch":{"tags":["Editions"],"summary":"Update edition","description":"Частична промяна на издание. Подай поне едно поле.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"editionId","in":"path","required":true,"description":"Идентификатор на изданието (Firestore document ID).","schema":{"type":"string","example":"def456","default":"<string>"},"example":"def456"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionPatch"},"examples":{"partial":{"summary":"Пример за частична промяна (PATCH)","value":{"locationText":"СМГ „Паисий Хилендарски“","city":"София","heldOnlyInCity":"Плевен","status":"published"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Edition"}}}},"404":{"description":"Not found"}}},"delete":{"tags":["Editions"],"summary":"Delete edition","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"editionId","in":"path","required":true,"description":"Идентификатор на изданието (Firestore document ID).","schema":{"type":"string","example":"def456","default":"<string>"},"example":"def456"}],"responses":{"204":{"description":"Deleted"}}}},"/v1/competitions/{id}/regulation-versions":{"get":{"tags":["RegulationVersions"],"summary":"List regulation versions for competition","description":"Версии на markdown регламент по години. Не съдържа scoring (точки/минути) — те са на exams.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"responses":{"200":{"description":"Version list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersionList"}}}},"404":{"description":"Competition not found"}}},"post":{"tags":["RegulationVersions"],"summary":"Create regulation version","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersionWrite"},"examples":{"default":{"summary":"Публикувана версия с отворен край","value":{"title":"от 2017","validFromYear":2017,"validToYear":null,"regulationsMarkdown":"## Регламент\n\n…","status":"published"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersion"}}}},"400":{"description":"Validation / year overlap"},"404":{"description":"Competition not found"}}}},"/v1/competitions/{id}/regulation-versions/{versionId}":{"get":{"tags":["RegulationVersions"],"summary":"Get regulation version","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersion"}}}},"404":{"description":"Not found"}}},"patch":{"tags":["RegulationVersions"],"summary":"Update regulation version","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersionPatch"},"examples":{"default":{"summary":"Затваряне на период","value":{"validToYear":2016,"title":"до 2016"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegulationVersion"}}}},"400":{"description":"Validation / year overlap"},"404":{"description":"Not found"}}},"delete":{"tags":["RegulationVersions"],"summary":"Delete regulation version","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"}}}},"/v1/editions":{"get":{"tags":["Editions"],"summary":"Calendar feed across competitions","parameters":[{"name":"subject","in":"query","description":"Филтър по предмет: mathematics (математика) или bulgarian (български език).","schema":{"type":"string","enum":["mathematics","bulgarian"],"default":"<string>"}},{"name":"status","in":"query","description":"Филтър по статус на изданието: draft (чернова) или published (публикувано).","schema":{"type":"string","enum":["draft","published"],"default":"<string>"}},{"name":"from","in":"query","description":"Начало на времеви интервал (ISO 8601 с часова зона, напр. 2026-03-01T00:00:00+02:00).","schema":{"type":"string","format":"date-time","default":"<dateTime>"}},{"name":"to","in":"query","description":"Край на времеви интервал (ISO 8601 с часова зона). Включва издания, започващи преди този момент.","schema":{"type":"string","format":"date-time","default":"<dateTime>"}},{"name":"scope","in":"query","description":"Обхват на състезанието: school (училищно), city (градско), national (национално) или international (международно).","schema":{"type":"string","enum":["school","city","national","international"],"default":"<string>"}},{"name":"city","in":"query","description":"Филтър по град на изданието (частично съвпадение, до 120 символа).","schema":{"type":"string","maxLength":120,"default":"<string>"}},{"name":"expand","in":"query","description":"Разширява всеки елемент с данни за родителската серия. Единствена стойност: competition.","schema":{"type":"string","enum":["competition"],"default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Edition feed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionFeed"}}}}}}},"/v1/collections":{"get":{"tags":["Collections"],"summary":"List exam collections","description":"Requires collections:read. q: думи с AND; кавички = точна фраза. Само метаданни на колекции, без съдържание на тестове.","parameters":[{"name":"subject","in":"query","description":"Филтър по предмет: mathematics (математика) или bulgarian (български език).","schema":{"type":"string","enum":["mathematics","bulgarian"],"default":"<string>"}},{"name":"kind","in":"query","description":"Вид колекция: assessment, competition, topic, curated или campaign.","schema":{"type":"string","enum":["assessment","competition","topic","curated","campaign"],"default":"<string>"}},{"name":"status","in":"query","description":"Статус на колекцията: draft (чернова) или published (публикувана).","schema":{"type":"string","enum":["draft","published"],"default":"<string>"}},{"name":"q","in":"query","description":"Свободен текст (до 120 символа). Думите се търсят поотделно с AND — всички трябва да се срещнат, не е нужно да са съседни (напр. матем хитър). Фраза в кавички изисква точно съвпадение на тази последователност (напр. \"хитър петър\"). Търсенето е без значение на главни/малки букви. Синоними: МБГ/MWB → „Математика без граници“.","schema":{"type":"string","maxLength":120,"default":"<string>"}},{"name":"eventSeriesId","in":"query","description":"Филтър по свързана серия състезание (eventSeries document ID).","schema":{"type":"string","default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Collection list"},"401":{"description":"Unauthorized"}}},"post":{"tags":["Collections"],"summary":"Create draft collection","description":"Requires collections:write. Always created as draft. App shows changes live; SEO pages update after generate:collections + hosting deploy.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionWrite"}}}},"responses":{"201":{"description":"Created"},"401":{"description":"Unauthorized"}}}},"/v1/collections/{id}":{"get":{"tags":["Collections"],"summary":"Get collection","description":"Requires collections:read. Метаданни на колекцията. ?include=items добавя тестовете в колекцията (без съдържание на въпроси).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"},{"name":"include","in":"query","description":"Включва членовете на колекцията в отговора. Единствена стойност: items.","schema":{"type":"string","enum":["items"],"default":"<string>"}}],"responses":{"200":{"description":"Collection"},"404":{"description":"Not found"}}},"patch":{"tags":["Collections"],"summary":"Update collection metadata","description":"Requires collections:write. Partial merge — send at least one field.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionPatch"}}}},"responses":{"200":{"description":"Updated"},"404":{"description":"Not found"}}}},"/v1/collections/{id}/cover":{"post":{"tags":["Collections"],"summary":"Set collection cover","description":"Requires collections:write. Генерира thumb 25:9 (500×180, карта в списъка) и header 22:5 (1100×250, банер на детайла).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverWrite"},"examples":{"fromUrl":{"summary":"Импорт от HTTPS URL","value":{"source":{"kind":"url","url":"https://example.com/covers/olympiad.jpg"}}}}}}},"responses":{"200":{"description":"Processed cover URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cover"}}}},"404":{"description":"Not found"}}},"delete":{"tags":["Collections"],"summary":"Clear collection cover","description":"Requires collections:write.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"responses":{"204":{"description":"Cleared"}}}},"/v1/collections/{id}/publish":{"post":{"tags":["Collections"],"summary":"Publish collection","description":"Requires collections:write. Emails all superAdmins. Collection must have at least one exam.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"responses":{"200":{"description":"Published"},"400":{"description":"Empty collection"}}}},"/v1/collections/{id}/unpublish":{"post":{"tags":["Collections"],"summary":"Unpublish collection","description":"Requires collections:write. No delete endpoint — use unpublish.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"responses":{"200":{"description":"Unpublished"}}}},"/v1/collections/{id}/items":{"get":{"tags":["Collections"],"summary":"List collection items","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"responses":{"200":{"description":"Items"}}},"post":{"tags":["Collections"],"summary":"Add exams to collection","description":"Requires collections:write. Supports dryRun. Max 200 examIds.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemsBody"}}}},"responses":{"200":{"description":"Membership mutation result"}}},"delete":{"tags":["Collections"],"summary":"Remove exams from collection","description":"Requires collections:write. Supports dryRun.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemsBody"}}}},"responses":{"200":{"description":"Membership mutation result"}}}},"/v1/collections/{id}/items/{examId}":{"patch":{"tags":["Collections"],"summary":"Update item label/order/groupKey","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на колекцията (examCollections document ID).","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"},{"name":"examId","in":"path","required":true,"description":"Идентификатор на тест в колекция (items subcollection).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemPatch"}}}},"responses":{"200":{"description":"Updated item"}}}},"/v1/competitions/{id}/collection-links":{"get":{"tags":["Collections"],"summary":"List collection links for a competition","description":"Requires collections:read or calendar:read.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"}],"responses":{"200":{"description":"Links"}}}},"/v1/competitions/{id}/collection-links/{collectionId}":{"put":{"tags":["Collections"],"summary":"Link collection to competition","description":"Requires calendar:write or collections:write. Fills eventSeriesId only when null.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"collectionId","in":"path","required":true,"description":"Идентификатор на колекция във връзка към състезание.","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionLinkBody"}}}},"responses":{"200":{"description":"Linked"}}},"delete":{"tags":["Collections"],"summary":"Unlink collection from competition","description":"Requires calendar:write or collections:write. Clears eventSeriesId only if it pointed at this competition.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на серията състезание (Firestore document ID).","schema":{"type":"string","example":"abc123","default":"<string>"},"example":"abc123"},{"name":"collectionId","in":"path","required":true,"description":"Идентификатор на колекция във връзка към състезание.","schema":{"type":"string","example":"col123","default":"<string>"},"example":"col123"}],"responses":{"204":{"description":"Unlinked"}}}},"/v1/public-demo":{"get":{"tags":["Exams"],"summary":"Get public demo test pointer","description":"Requires exams:read. Връща config/publicDemo (examId + каталожно резюме). Без въпроси и ключове.","responses":{"200":{"description":"Текущ демо тест","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDemoResponse"}}}}}},"patch":{"tags":["Exams"],"summary":"Set or clear public demo test","description":"Requires exams:write. Задава examId или slug; examId: null изчиства. Вдига visibility: public на избрания тест.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDemoPatch"}}}},"responses":{"200":{"description":"Обновен демо тест","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDemoResponse"}}}}}}},"/v1/exam-pipeline":{"get":{"tags":["Pipeline"],"summary":"Get global exam pipeline config","description":"Requires pipeline:read. Глобални defaults (providers, models, prompts). Не съдържа per-exam processing.cost — това е на inspect.","responses":{"200":{"description":"Глобален pipeline config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamPipelineConfig"}}}}}},"patch":{"tags":["Pipeline"],"summary":"Update global exam pipeline config","description":"Requires pipeline:write. Two-step confirm (first call returns confirmToken). Affects all uploads.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamPipelineConfigPatch"}}}},"responses":{"200":{"description":"Обновен config или confirmation_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamPipelineConfigPatchResult"}}}}}}},"/v1/questions":{"get":{"tags":["Questions"],"summary":"Search questions","description":"Requires questions:read. Търсене в банката задачи без ключове/решения. Филтри: originExamId (роден от), examId (член в items), subject/grade/examKind/year/officiality/eventSeriesId от origin snapshot, systemTagId. Най-много един array-contains (systemTagId или originGrades). Cursor = question id.","parameters":[{"name":"q","in":"query","description":"Свободен текст (до 120 символа). Думите се търсят поотделно с AND — всички трябва да се срещнат, не е нужно да са съседни (напр. матем хитър). Фраза в кавички изисква точно съвпадение на тази последователност (напр. \"хитър петър\"). Търсенето е без значение на главни/малки букви. Синоними: МБГ/MWB → „Математика без граници“.","schema":{"type":"string","maxLength":120,"default":"<string>"}},{"name":"originExamId","in":"query","description":"Филтър: задачи, родени от този тест (originExamId).","schema":{"type":"string","default":"<string>"}},{"name":"examId","in":"query","description":"Филтър: задачи от exams/{examId}/items (редът на теста).","schema":{"type":"string","default":"<string>"}},{"name":"subject","in":"query","description":"Филтър по предмет: mathematics (математика) или bulgarian (български език).","schema":{"type":"string","enum":["mathematics","bulgarian"],"default":"<string>"}},{"name":"grade","in":"query","description":"Филтър по клас (1–12) — тестът трябва да покрива този клас.","schema":{"type":"integer","minimum":1,"maximum":12,"default":"<integer>"}},{"name":"examKind","in":"query","description":"Вид тест: entrance, exit, term, unit, nvo, dzi, competition, thematic, other.","schema":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"default":"<string>"}},{"name":"year","in":"query","description":"Календарна година на теста (1900–2100).","schema":{"type":"integer","minimum":1900,"maximum":2100,"default":"<integer>"}},{"name":"officiality","in":"query","description":"Официалност: official (официален) или authored (авторски).","schema":{"type":"string","enum":["official","authored"],"default":"<string>"}},{"name":"eventSeriesId","in":"query","description":"Филтър по свързана серия състезание (eventSeries document ID).","schema":{"type":"string","default":"<string>"}},{"name":"systemTagId","in":"query","description":"Филтър: systemTagIds array-contains.","schema":{"type":"string","default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Списък задачи без ключове","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionList"}}}}}}},"/v1/questions/{id}":{"get":{"tags":["Questions"],"summary":"Get question (no keys)","description":"Requires questions:read. Детайл без hint/solution/ключове. Включва answerOptions без correct indices, sections (с items) редактирани, signed crop/drawings URLs, solutionLocked/solutionVisibleToLearners.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Детайл без ключове","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDetail"}}}},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/stats":{"get":{"tags":["Questions"],"summary":"Get question stats","description":"Requires questions:read. Глобални броячи attempt/correct/incorrect/skipped (+ correctRate).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Статистики","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionStats"}}}},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/admin-notes":{"get":{"tags":["Questions"],"summary":"List admin notes on a question","description":"Requires questions:inspect or questions:write. Бележки за админи и коректори (не за ученици). Най-старата първа. MCP: list_question_admin_notes.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Бележки","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAdminNoteList"}}}},"404":{"description":"Не е намерена"}}},"post":{"tags":["Questions"],"summary":"Add an admin note on a question","description":"Requires questions:write. Бележка за човека, който проверява задачата. Не пипа условието, ключа или решението. Най-много 40 бележки. MCP: add_question_admin_note.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAdminNoteCreate"}}}},"responses":{"201":{"description":"Нова бележка","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAdminNote"}}}},"400":{"description":"Празен или твърде дълъг текст"},"404":{"description":"Не е намерена"},"409":{"description":"Достигнат е лимитът от 40 бележки"}}}},"/v1/questions/{id}/admin-notes/{noteId}":{"delete":{"tags":["Questions"],"summary":"Delete an admin note","description":"Requires questions:write. Триене на една бележка. MCP: delete_question_admin_note.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}},{"name":"noteId","in":"path","required":true,"schema":{"type":"string"},"description":"Идентификатор на бележката."}],"responses":{"200":{"description":"Изтрита бележка","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAdminNoteDelete"}}}},"404":{"description":"Задачата или бележката не е намерена"}}}},"/v1/questions/{id}/solution":{"get":{"tags":["Questions"],"summary":"Get question solution and keys","description":"Requires questions:inspect. Връща hint, solution, ключове и per-part ключове. Не дублира цялото условие.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Решение и ключове","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionSolution"}}}},"404":{"description":"Не е намерена"}}},"patch":{"tags":["Questions"],"summary":"Set or clear question solution/hint","description":"Requires questions:write. Задай или изтрий hint/solution (top-level и/или parts). null/\"\"/clear* = FieldValue.delete. Не пипа ключа. При публикуван origin тест — confirm. След запис refresh на exams.issues. 409 HUMAN_LOCKED, ако решението е редактирано ръчно в админ UI (без skipLocked — единична задача).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionSolutionPatch"}}}},"responses":{"200":{"description":"Обновено решение (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionSolution"}}}},"400":{"description":"Невалидно тяло / непозната част"},"403":{"description":"Невалиден confirm"},"404":{"description":"Не е намерена"},"409":{"description":"HUMAN_LOCKED — решението е редактирано ръчно"}}}},"/v1/questions/{id}/drawings":{"get":{"tags":["Questions"],"summary":"List question drawings","description":"Requires questions:read. Чертежите на задачата: подписан url (1ч) на текущия PNG, hasOriginal/originalUrl (сурова изрезка преди почистване/подобряване), bounds. MCP: list_question_drawings.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Чертежи","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawings"}}}},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/drawings/{index}":{"put":{"tags":["Questions"],"summary":"Upload a new drawing PNG","description":"Requires questions:write. Замества чертеж N с pngBase64 (PNG до 5 MB). Първата промяна пази оригинала. При публикуван origin тест — confirm. MCP: upload_question_drawing.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}},{"name":"index","in":"path","required":true,"description":"Номер на чертежа (1–12).","schema":{"type":"integer","minimum":1,"maximum":12}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingUpload"}}}},"responses":{"200":{"description":"Резултат (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingChangeResult"}}}},"400":{"description":"Невалидно тяло / стойност извън диапазона / PNG (не е PNG, > 5 MB)"},"403":{"description":"Невалиден confirm"},"404":{"description":"Няма задача / файл на чертежа / previewId"},"409":{"description":"Няма чертеж с този номер / няма оригинал (restore)"},"500":{"description":"Почистването / прерисуването не успя"}}}},"/v1/questions/{id}/drawings/{index}/clean":{"post":{"tags":["Questions"],"summary":"Classical clean of a drawing (preview or commit)","description":"Requires questions:write. Без AI: contrast 1–2 (1.2), lineDarken 0.7–1 (0.95), bgTolerance 0–80 (28), saturation −100…100 (0), vibrance −100…100 (0), enhance, transparentBackground, transparentBackgroundWholeImage (само с transparentBackground), regions, source (current|original). commit=false → previewId + previewUrl; commit=true + previewId записва точно прегледа (оригиналът се пази). При публикуван origin тест — confirm. MCP: clean_question_drawing.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}},{"name":"index","in":"path","required":true,"description":"Номер на чертежа (1–12).","schema":{"type":"integer","minimum":1,"maximum":12}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingClean"}}}},"responses":{"200":{"description":"Резултат (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingChangeResult"}}}},"400":{"description":"Невалидно тяло / стойност извън диапазона / PNG (не е PNG, > 5 MB)"},"403":{"description":"Невалиден confirm"},"404":{"description":"Няма задача / файл на чертежа / previewId"},"409":{"description":"Няма чертеж с този номер / няма оригинал (restore)"},"500":{"description":"Почистването / прерисуването не успя"}}}},"/v1/questions/{id}/drawings/{index}/redraw":{"post":{"tags":["Questions"],"summary":"AI redraw of a drawing (preview or commit)","description":"Requires questions:write. AI image модел (разход): prompt, provider gemini|openai, includeProblemStem, referenceDrawingIndexes, referenceImagePaths, transparentBackground. Преглед → commit с previewId без нов разход. Над api.mozak.be (Hosting) заявката е ограничена до ~60 s. При публикуван origin тест — confirm. MCP: redraw_question_drawing.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}},{"name":"index","in":"path","required":true,"description":"Номер на чертежа (1–12).","schema":{"type":"integer","minimum":1,"maximum":12}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingRedraw"}}}},"responses":{"200":{"description":"Резултат (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingChangeResult"}}}},"400":{"description":"Невалидно тяло / стойност извън диапазона / PNG (не е PNG, > 5 MB)"},"403":{"description":"Невалиден confirm"},"404":{"description":"Няма задача / файл на чертежа / previewId"},"409":{"description":"Няма чертеж с този номер / няма оригинал (restore)"},"500":{"description":"Почистването / прерисуването не успя"}}}},"/v1/questions/{id}/drawings/{index}/restore":{"post":{"tags":["Questions"],"summary":"Restore the original drawing","description":"Requires questions:write. Връща чертеж N към запазения оригинал (*-drawing-original.png); 409 ако няма. При публикуван origin тест — confirm. MCP: restore_question_drawing_original.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}},{"name":"index","in":"path","required":true,"description":"Номер на чертежа (1–12).","schema":{"type":"integer","minimum":1,"maximum":12}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingRestore"}}}},"responses":{"200":{"description":"Резултат (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionDrawingChangeResult"}}}},"400":{"description":"Невалидно тяло / стойност извън диапазона / PNG (не е PNG, > 5 MB)"},"403":{"description":"Невалиден confirm"},"404":{"description":"Няма задача / файл на чертежа / previewId"},"409":{"description":"Няма чертеж с този номер / няма оригинал (restore)"},"500":{"description":"Почистването / прерисуването не успя"}}}},"/v1/questions/{id}/answer-option-regions":{"put":{"tags":["Questions"],"summary":"Set MC answer zones on the drawing","description":"Requires questions:write. „Отговори върху чертежа“: по една зона на MC вариант (в реда на answerOptions; варианти само от една главна буква) или regions=null за изключване. Източник admin — pipeline не ги презаписва; AI: reprocess със stage=mcOnDrawing. При публикуван origin тест — confirm. MCP: set_question_answer_option_regions.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAnswerOptionRegionsPatch"}}}},"responses":{"200":{"description":"Записани зони (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionAnswerOptionRegionsPatchResult"}}}},"400":{"description":"Невалидни зони / варианти не са букви"},"403":{"description":"Невалиден confirm"},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/solution-visibility":{"patch":{"tags":["Questions"],"summary":"Toggle solution visibility for learners","description":"Requires questions:write. Показва или скрива hint/solution за learners (solutionVisibleToLearners) без да трие текста. visible:true е отказ (400), ако няма текст на решение. При публикуван origin тест — confirm.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionSolutionVisibilityPatch"}}}},"responses":{"200":{"description":"Visibility toggle (или confirmation_required)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionSolutionVisibilityPatchResult"}}}},"403":{"description":"Невалиден confirm"},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/tags":{"patch":{"tags":["Questions"],"summary":"Merge question system tags","description":"Requires questions:write. Merge addTagIds/removeTagIds (не replace). Валидира съществуващи неархивирани тагове; лимит 20; dryRun опционално.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionTagsPatch"}}}},"responses":{"200":{"description":"Резултат от merge","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionTagsPatchResult"}}}},"404":{"description":"Не е намерена"}}}},"/v1/questions/classify":{"post":{"tags":["Taxonomy"],"summary":"Classify questions (batch)","description":"Requires taxonomy:write. Пуска AI classify за до 50 задачи. Не създава отметки; липсващи възли отиват в taxonomyProposals.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionClassifyBody"}}}},"responses":{"200":{"description":"Резултати по задача (ok, classification, proposalIds, skipped)"}}}},"/v1/questions/{id}/classification":{"get":{"tags":["Taxonomy"],"summary":"Get question classification","description":"Requires taxonomy:read. Връща classification и systemTagIds (листа + предци).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Класификация и systemTagIds"},"404":{"description":"Не е намерена"}}},"put":{"tags":["Taxonomy"],"summary":"Set question classification","description":"Requires taxonomy:write. Ръчно записва подредени теми, сюжет и умения. systemTagIds се разширяват с предци. Не пипа свободни (некласификационни) тагове.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionClassificationPut"}}}},"responses":{"200":{"description":"Записана класификация"},"404":{"description":"Не е намерена"}}}},"/v1/questions/{id}/classify":{"post":{"tags":["Taxonomy"],"summary":"Classify one question","description":"Requires taxonomy:write. AI класификация по съществуващия речник. Празен речник → skipped empty_taxonomy, без auto-create.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Класификация или skipped"},"404":{"description":"Не е намерена"}}}},"/v1/taxonomy/nodes":{"get":{"tags":["Taxonomy"],"summary":"List taxonomy nodes","description":"Requires taxonomy:read. Филтри: axis (theme|story|skill), parentId, root=true (само корени), includeArchived.","parameters":[{"name":"axis","in":"query","description":"Ос на дървото: theme (тема), story (сюжет) или skill (умение).","schema":{"type":"string","enum":["theme","story","skill"]}},{"name":"parentId","in":"query","description":"Само преки деца на този възел (Firestore id).","schema":{"type":"string"}},{"name":"root","in":"query","description":"true = само корени (parentId null), независимо от parentId.","schema":{"type":"string","enum":["true","false"]}},{"name":"includeArchived","in":"query","description":"true = включи архивирани възли в списъка.","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Списък възли"}}},"post":{"tags":["Taxonomy"],"summary":"Create taxonomy node","description":"Requires taxonomy:write. Създава възел в tags с axis/parentId/code. Не сее дървото.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyNodeCreate"}}}},"responses":{"201":{"description":"Създаден възел"}}}},"/v1/taxonomy/nodes/{id}":{"get":{"tags":["Taxonomy"],"summary":"Get taxonomy node","description":"Requires taxonomy:read.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Възел"},"404":{"description":"Не е намерен"}}},"patch":{"tags":["Taxonomy"],"summary":"Update taxonomy node","description":"Requires taxonomy:write. Име, код, описание, цвят, sortOrder — без преместване.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyNodePatch"}}}},"responses":{"200":{"description":"Обновен възел"},"404":{"description":"Не е намерен"}}}},"/v1/taxonomy/nodes/{id}/move":{"post":{"tags":["Taxonomy"],"summary":"Move taxonomy node","description":"Requires taxonomy:write. Сменя parentId. Не пренаписва systemTagIds по вече класифицирани задачи.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyNodeMove"}}}},"responses":{"200":{"description":"Преместен възел"}}}},"/v1/taxonomy/nodes/{id}/archive":{"post":{"tags":["Taxonomy"],"summary":"Archive or restore taxonomy node","description":"Requires taxonomy:write.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyNodeArchive"}}}},"responses":{"200":{"description":"Възел"}}}},"/v1/taxonomy/nodes/{id}/merge":{"post":{"tags":["Taxonomy"],"summary":"Merge taxonomy node","description":"Requires taxonomy:write. Fan-out върху exams/questions systemTagIds и classification.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyNodeMerge"}}}},"responses":{"200":{"description":"Резултат от merge"}}}},"/v1/taxonomy/proposals":{"get":{"tags":["Taxonomy"],"summary":"List taxonomy proposals","description":"Requires taxonomy:read. Опашка от LLM предложения за нови възли (без auto-create).","parameters":[{"name":"status","in":"query","description":"Филтър по статус: pending, accepted или rejected.","schema":{"type":"string","enum":["pending","accepted","rejected"]}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}}],"responses":{"200":{"description":"Списък предложения"}}}},"/v1/taxonomy/proposals/{id}/accept":{"post":{"tags":["Taxonomy"],"summary":"Accept taxonomy proposal","description":"Requires taxonomy:write. Създава възела; не го слага автоматично върху задачата.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Прието предложение и създаден възел"}}}},"/v1/taxonomy/proposals/{id}/reject":{"post":{"tags":["Taxonomy"],"summary":"Reject taxonomy proposal","description":"Requires taxonomy:write. Затваря опашката без нова отметка.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на задачата (questions document ID).","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Отхвърлено предложение"}}}},"/v1/exam-decorations":{"get":{"tags":["Exams"],"summary":"List exam margin decorations","description":"Requires exams:read. Без examId — глобален списък; с examId — за теста (inheritsGlobal ако ползва глобалния).","parameters":[{"name":"examId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Decoration list"}}},"post":{"tags":["Exams"],"summary":"Add exam margin decoration","description":"Requires exams:write. Качва изображение (url или base64). Позиция left/middle/right × top/middle/bottom, opacity, опционален crop.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamDecorationAdd"},"examples":{"fromUrl":{"summary":"Импорт от HTTPS URL","value":{"source":{"kind":"url","url":"https://example.com/leaves.webp"},"horizontal":"right","vertical":"bottom","opacity":1}}}}}},"responses":{"201":{"description":"Created decoration"}}}},"/v1/exam-decorations/batch":{"post":{"tags":["Exams"],"summary":"Add multiple exam margin decorations","description":"Requires exams:write. Качва няколко изображения с обща позиция, opacity, scale и crop.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamDecorationAddBatch"},"examples":{"batchUrls":{"summary":"Няколко URL с обща позиция","value":{"sources":[{"kind":"url","url":"https://example.com/a.webp"},{"kind":"url","url":"https://example.com/b.webp"}],"horizontal":"left","vertical":"bottom","opacity":1,"scale":1}}}}}},"responses":{"201":{"description":"Created decorations"}}}},"/v1/exam-decorations/inherit":{"post":{"tags":["Exams"],"summary":"Inherit global decorations for an exam","description":"Requires exams:write. Премахва собствения списък на теста.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["examId"],"properties":{"examId":{"type":"string"}}}}}},"responses":{"200":{"description":"Now inherits global"}}}},"/v1/exam-decorations/{decorationId}":{"patch":{"tags":["Exams"],"summary":"Update exam margin decoration","description":"Requires exams:write. Позиция / opacity / crop без повторно качване.","parameters":[{"name":"decorationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamDecorationUpdate"},"examples":{"move":{"summary":"Премести долу вляво","value":{"horizontal":"left","vertical":"bottom","opacity":0.9}}}}}},"responses":{"200":{"description":"Updated decoration"}}},"delete":{"tags":["Exams"],"summary":"Remove exam margin decoration","description":"Requires exams:write.","parameters":[{"name":"decorationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"examId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Remaining list"}}}},"/v1/exams":{"get":{"tags":["Exams"],"summary":"Search exams","description":"Requires exams:read or collections:read. По подразбиране processingStatus=processed (готови тестове). Includes catalog drafts. Never returns question content or answer keys. q: думи с AND; кавички = точна фраза.","parameters":[{"name":"q","in":"query","description":"Свободен текст (до 120 символа). Думите се търсят поотделно с AND — всички трябва да се срещнат, не е нужно да са съседни (напр. матем хитър). Фраза в кавички изисква точно съвпадение на тази последователност (напр. \"хитър петър\"). Търсенето е без значение на главни/малки букви. Синоними: МБГ/MWB → „Математика без граници“.","schema":{"type":"string","maxLength":120,"default":"<string>"}},{"name":"subject","in":"query","description":"Филтър по предмет: mathematics (математика) или bulgarian (български език).","schema":{"type":"string","enum":["mathematics","bulgarian"],"default":"<string>"}},{"name":"grade","in":"query","description":"Филтър по клас (1–12) — тестът трябва да покрива този клас.","schema":{"type":"integer","minimum":1,"maximum":12,"default":"<integer>"}},{"name":"examKind","in":"query","description":"Вид тест: entrance, exit, term, unit, nvo, dzi, competition, thematic, other.","schema":{"type":"string","enum":["entrance","exit","term","unit","nvo","dzi","competition","thematic","other"],"default":"<string>"}},{"name":"year","in":"query","description":"Календарна година на теста (1900–2100).","schema":{"type":"integer","minimum":1900,"maximum":2100,"default":"<integer>"}},{"name":"officiality","in":"query","description":"Официалност: official (официален) или authored (авторски).","schema":{"type":"string","enum":["official","authored"],"default":"<string>"}},{"name":"eventSeriesId","in":"query","description":"Филтър по свързана серия състезание (eventSeries document ID).","schema":{"type":"string","default":"<string>"}},{"name":"collectionId","in":"query","description":"Филтър: тестове, членуващи в тази колекция (array-contains).","schema":{"type":"string","default":"<string>"}},{"name":"hasCollection","in":"query","description":"true = само тестове с поне една колекция; false = без колекция.","schema":{"type":"string","enum":["true","false"],"default":"<string>"}},{"name":"catalogStatus","in":"query","description":"Каталожен статус на теста: draft или published.","schema":{"type":"string","enum":["draft","published"],"default":"<string>"}},{"name":"processingStatus","in":"query","description":"Статус на AI pipeline. По подразбиране processed (готови тестове). uploaded/processing за polling на качвания в ход.","schema":{"type":"string","enum":["uploaded","processing","processed","failed","paused"],"default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Каталожни резюмета (без cost)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamList"}}}}}},"post":{"tags":["Exams"],"summary":"Upload exam and start pipeline","description":"Requires exams:write. Ingests PDF/DOC/DOCX/image via url or base64. Optional: answer key file, pipeline overrides, collectionId (needs collections:write), and exam regulation fields (all optional): timeLimitMinutes (1–300, default 40; when omitted, the structure pass fills it from the PDF regulation, e.g. „Време за работа: 90 минути“), pointRules, gradeRules, wrongAnswerPoints, blankAnswerPoints, startingPoints, answerKeyText, regulationVersionId (markdown регламент; иначе се резолва по eventSeriesId+year). If pointRules/gradeRules/defaultPoints are set, scoringLocked=true so structure pass does not overwrite them from the PDF. Omitted pipeline.stepsEnabled.answer stores answer and hint false; solutions are filled when a parent assigns the test unless answer is true. Returns draft summary; poll GET /v1/exams/{id} until processingStatus=processed (or failed). Cost: after full run in GET /v1/exams/{id}/inspect?include=summary → summary.cost. 400 on invalid regulation (e.g. timeLimitMinutes out of range). 403 if collectionId without collections:write.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamUpload"}}}},"responses":{"201":{"description":"Created exam (processing queued)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamSummary"}}}},"400":{"description":"Validation error (invalid file, pipeline, or regulation fields)"},"403":{"description":"Missing collections:write for collectionId"}}}},"/v1/exams/bulk/taxonomy":{"post":{"tags":["Exams"],"summary":"Bulk update exam taxonomy","description":"Requires exams:write. Max 100 ids. Supports dryRun. Merge semantics per exam.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamBulkTaxonomy"}}}},"responses":{"200":{"description":"Per-document results"}}}},"/v1/exams/bulk/structure":{"post":{"tags":["Exams"],"summary":"Bulk patch exam structure and scoring","description":"Requires exams:write. Max 100 ids. Same patch as PATCH /v1/exams/{id}/structure (timeLimitMinutes, scoring, mcOtherAnswerMode, mcOptionsLayout, applyPoints, applyAnswerKey). dryRun checks existence only. confirm in patch is ignored; published exams return confirmation_required per id — finish with PATCH /structure + confirm. Per-id errors do not abort the rest.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamBulkStructure"}}}},"responses":{"200":{"description":"Per-document results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamBulkStructureResult"}}}}}}},"/v1/exams/{id}":{"get":{"tags":["Exams"],"summary":"Get exam taxonomy summary","description":"Requires exams:read or collections:read. Каталожно резюме без въпроси и ключове. За polling: processingStatus, processingStage, processingError, processingPageCount. Няма цена — LLM/DocAI оценка е само в GET /v1/exams/{id}/inspect?include=summary → summary.cost (scope exams:inspect).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"responses":{"200":{"description":"Exam summary (без cost)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamSummary"}}}},"404":{"description":"Not found"}}},"patch":{"tags":["Exams"],"summary":"Merge-update exam taxonomy","description":"Requires exams:write. Merge, not replace. Does not mutate visibility, systemTagIds, collectionIds, or question content. Published exam slug is preserved unless slug is sent explicitly.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamTaxonomyPatch"}}}},"responses":{"200":{"description":"Updated exam summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamSummary"}}}}}}},"/v1/exams/{id}/publish":{"post":{"tags":["Exams"],"summary":"Publish exam catalog status","description":"Requires exams:write. catalogStatus=published. Без имейл (за разлика от колекции).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"responses":{"200":{"description":"Published exam summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamSummary"}}}}}}},"/v1/exams/{id}/unpublish":{"post":{"tags":["Exams"],"summary":"Unpublish exam catalog status","description":"Requires exams:write. Връща теста в draft.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"responses":{"200":{"description":"Unpublished exam summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamSummary"}}}}}}},"/v1/exams/{id}/inspect":{"get":{"tags":["Exams"],"summary":"Inspect exam pipeline artifacts","description":"Requires exams:inspect. include=summary,structure,bounds,questions,issues (по подразбиране summary,structure,issues). Въпроси/ключове и signed URL (~15 мин). summary.cost е натрупаната оценка от всеки pipeline run; POST /reprocess и ръчен AI в админа добавят към нея. summary също: scoringPolicy, timeLimitMinutes, scoringLocked, pointRules, gradeRules, answerKeyText.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"},{"name":"include","in":"query","description":"Какво да върне inspect: summary, structure, bounds, questions, issues (запетая). Без параметър: summary,structure,issues.","schema":{"type":"string","default":"<string>"}},{"name":"limit","in":"query","description":"Максимален брой резултати на страница (1–100). По подразбиране: 50.","schema":{"type":"integer","minimum":1,"maximum":100,"default":"<integer>"}},{"name":"cursor","in":"query","description":"Курсор за следваща страница от предишен отговор (стойността на nextCursor). Оставете празно за първа страница.","schema":{"type":"string","default":"<string>"}}],"responses":{"200":{"description":"Inspect payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamInspect"}}}},"404":{"description":"Not found"}}}},"/v1/exams/{id}/structure":{"patch":{"tags":["Exams"],"summary":"Patch exam structure, scoring, and time limit","description":"Requires exams:write. Partial PATCH: page roles, timeLimitMinutes (1–300), scoring knobs, pointRules, gradeRules, answerKeyText. applyPoints=true rewrites item points after questions exist (400 if no pointRules/defaultPoints). applyAnswerKey=true overwrites correct answers (400 if no answerKeyText; 409 HUMAN_LOCKED if any target answer is human-locked and skipLocked is not true — skipLocked=true applies to the rest and reports skippedHumanLocked). Published exams: first call returns confirmation_required; repeat with confirm token. 404 if exam missing. 403 invalid confirm.","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamStructurePatch"}}}},"responses":{"200":{"description":"Обновена structure или confirmation_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamStructurePatchResult"}}}},"409":{"description":"HUMAN_LOCKED — applyAnswerKey с заключени отговори (виж error.details)"}}}},"/v1/exams/{id}/process":{"post":{"tags":["Exams"],"summary":"Enqueue exam pipeline process","description":"Requires exams:write. Enqueue resume или fullRestart (202). LLM върви в processExamOnUpload, не в API gateway. Poll GET /v1/exams/{id} за processingStatus. След успешен run processing.cost се натрупва (чети през inspect). Публикуван тест иска confirm. Заключени задачи (humanLocks) или „проверен от човек“ тест (humanReview.status=reviewed) → 409 HUMAN_LOCKED; skipLocked=true пуска pipeline-а, който пропуска заключените задачи вътрешно (не важи за reviewed).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamProcess"}}}},"responses":{"200":{"description":"Published exam — изисква confirm токен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationRequired"}}}},"202":{"description":"Командата е в опашката","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamProcessQueued"}}}},"409":{"description":"HUMAN_LOCKED — заключени задачи или проверен от човек тест (виж error.details)"}}}},"/v1/exams/{id}/reprocess":{"post":{"tags":["Exams"],"summary":"Enqueue question reprocess","description":"Requires exams:write. Enqueue extract | improveMarkdown | answer за избрани задачи (optional provider+model+reasoningEffort = one-shot: един solve call на задача, без mid/smart escalate; provider: openai|grok|gemini|claude). Poll GET /v1/exams/{id}. След LLM натрупва processing.cost (append) и пише lastReprocess (failed/error при LLM fail) — чети през inspect. Пълен process също натрупва cost. Публикуван тест иска confirm. Заключени задачи (humanLocks на полетата от тази stage) → 409 HUMAN_LOCKED; skipLocked=true пропуска само тях (skippedHumanLocked в отговора).","parameters":[{"name":"id","in":"path","required":true,"description":"Идентификатор на теста (exams document ID).","schema":{"type":"string","example":"exam123","default":"<string>"},"example":"exam123"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamReprocess"}}}},"responses":{"200":{"description":"Published exam — изисква confirm токен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationRequired"}}}},"202":{"description":"Командата е в опашката","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamProcessQueued"}}}},"409":{"description":"HUMAN_LOCKED — заключени задачи (виж error.details)"}}}}}}