API-сторона решения unified-upload-flow1. Унифицированный пользовательский UX (один drop-zone) опирается на новый отдельный endpoint, который не ломает существующий B2B контракт — мы пока сохраняем прежний формат.
API-сторона решения unified-upload-flow. Унифицированный пользовательский UX (один drop-zone) опирается на новый отдельный endpoint, который не ломает существующий B2B контракт.
Контекст
Существующий API для B2B-клиентов:
- Один файл на входе → один TestID на выходе
- Каждый TestID → один отчёт через downstream pipeline
- Клиенты (лаборатории, EHR-партнёры) уже интегрированы и зависят от этого контракта
B2C-сторона хочет:
- Принимать много разнотипных файлов разом (PDF/image анализы, выписки, рецепты, фото и т.д.)
- Ничего конкретного как «test» не возвращать пользователю — test перестаёт быть юнитом вывода (см. recognition-enrichment-hourglass и unified-upload-flow)
- Хранить всё в FHIR, отдавать пользователю плоский список файлов и их статусов через отдельный запрос
- Lazy-генерировать тренды/обзоры по конкретному файлу при открытии
Если пытаться расширить существующий endpoint (multi-file response, опциональный TestID и т.д.) — поломаем B2B контракт. Если делать parallel endpoint — никто никого не ломает.
Выбрали: новый endpoint, B2B неизменен
B2B (existing): POST /api/recognize 1 file → TestID
B2C (new): POST /api/upload N files → 200 OK (нет TestID)
GET /api/files → плоский список с статусами
Имена выбраны семантически: recognize — историческое имя для «один файл → структурированный результат с TestID», B2B-клиенты на этом уже интегрированы. upload — для нового multi-file flow. Альтернатива ingest для нового endpoint отвергнута из-за конфликта с inngest (легко перепутать в коде / логах / разговоре).
Что внутри новой ручки
- Принимает N файлов разных форматов
- Сохраняет всё в FHIR (DocumentReference / etc., см. fhir-document-reference)
- Запускает recognition flow per файл асинхронно (см. recognition-enrichment-hourglass — это вход в верхний конус)
- Возвращает только 200 OK; статусы файлов фронтенд берёт через GET
- Без grouping / batch ID на старте — добавим если станет нужно
Почему
- Backward-compat пока сохраняем — клиенты на existing API уже интегрированы; не ломаем формат, пока нет причины (semantic versioning без bump major)
- Развязывает руки B2C — можно эволюционировать новый endpoint свободно (lazy processing, новые форматы, semantic batch grouping) без оглядки на B2B
- Симметрия с архитектурой — separate endpoint = отдельный «вход в верхний конус» песочных часов; B2B path остаётся там же где был
- Минимальная сложность — Вася просил не overengineer’ить (без grouping, batch ID, smart routing) пока не понадобится
Следствия
- Новый endpoint требует поддержки async file status в FHIR — каждый файл переходит status
uploaded → recognizing → recognized | failed. См. fhir-document-reference (carry-over: уточнить status field schema). - Frontend получает список файлов отдельным GET-запросом, не из upload response — другой UX-паттерн чем existing B2B clients
- Когда endpoint готов — Ильдар прицепляет enrichment-ветку поверх (см. recognition-enrichment-hourglass нижний конус)
- B2C сценарий перестаёт быть test-центричным; recognition стартует per file, а не «per TestID» — это часть paradigm shift из health-report-vision
Открытые вопросы
- Async progress для пользователя — websocket / polling / SSE? Не зафиксировано.
- File grouping logic — multipage PDF одного теста vs N фото одного теста vs два разных теста в один загруз. Серьёзный вопрос, отложен в multi-image-file-grouping (status: draft, не сформулировано).
- Authorization модель — те же scopes, что у
/api/recognize(per-org / per-patient — без изменений в access control).
Связанные решения
- multi-image-file-grouping — как группировать N файлов одного документа — draft
Связано
- unified-upload-flow — UX-сторона того же решения
- recognition-enrichment-hourglass — место в архитектуре (расширение верхнего конуса песочных часов)
- recognition — что происходит после upload (recognition flow per файл)
- fhir-document-reference — куда сохраняются raw файлы
- ai-enrichment-separate-step — pattern «асинхронные шаги через FHIR как shared state»
- health-report-vision — paradigm shift, который unified upload и этот endpoint практически продвигают
Источники
Сноски
-
2026-04-27 Daily + Sprint Review & Planning, https://github.com/Realai-plus/meeting-digests/blob/main/data/digest/2026/04/2026-04-27T08%3A00%3A00.000Z_Daily_%2B_Sprint_Review%26Planning_01KPX39F5EMF092HA0PGKSX1FV.md — решение про отдельный endpoint, имя
upload(vs отвергнутогоingest), Артём в работу на конец недели. ↩