VeriDepth API Catalog

http://192.168.224.11/VeriDepthServer  ·  БД: VeriDepthDB @ 192.168.224.10
Аутентификация

Все запросы требуют заголовок Authorization: Bearer <токен>

Токены хранятся в src/Presentation.ViewModels/ServerApiCredentials.cs

КонстантаПрефиксПрава
CalibrationBearercal_Чтение и запись калибровок
TrainingEvidenceBearertek_Загрузка captures, records
TrainingEvidenceInventoryBearerteinv_Чтение, листинг, summary
DistributionBearerdist-Загрузка дистрибутивов

Флаги DB: CanUploadTrainingEvidence, CanHardDeleteTrainingEvidence, CanUploadDistributions. Превышение лимита → 429.

Calibration API  /api/calibrations/v1
GET /api/calibrations/v1/devices/{serial}/active Активный профиль калибровки

Возвращает полный активный профиль (включая profileJson) для серийного номера прибора.

ПутьОписание
serial*Серийный номер прибора (напр. 0454628)
200: { "schemaVersion":"calibration-profile/v1", "calibrationId":"cal-...", "deviceSerial":"0454628",
       "computedAt":"2026-06-18T01:44:53Z", "rmsStereoPx":0.803, "baselineMm":3.556,
       "k5Passed":true, "isRecommendedActive":true, "profileJson":{...} }
404: { "errorCode":"calibration_not_found" }
GET /api/calibrations/v1/devices/by-eeprom/{eepromSha}/active Активный профиль по SHA заводской EEPROM

Поиск калибровки по SHA заводской EEPROM прибора. Используется клиентом, когда серийник из EEPROM невалиден (например, прибор 1/11 репортит серийник "11" — номер модели, не уникальный).
Формат eepromSha: 64 hex-символа нижнего регистра, SHA-256 от строки "<block1_hex>\r\n<block2_hex>" (два 80-байтных EEPROM-блока, формат legacy_eeprom_block_pair).
Таблица соответствий: dbo.DeviceEepromKey. Текущие записи: прибор 0454628 (sha 00585a32…).

200: полный active-профиль (тот же формат что /devices/{serial}/active)
404: { "errorCode":"calibration_not_found" }  — нет маппинга или нет active-калибровки
422: { "errorCode":"calibration_schema_invalid" }  — eepromSha не 64 hex

Б-044 / 2026-07-01. Клиентский резолвер: если /devices/{serial}/active → 404, вычислить eepromSha и обратиться к этому эндпоинту.

GET /api/calibrations/v1/devices/by-eeprom/{eepromSha}/identity Личность прибора по SHA EEPROM (без калибровки)

Возвращает серийный номер прибора по SHA заводской EEPROM, БЕЗ требования наличия активной калибровки — в отличие от /active, отвечает 200 даже если калибровки ещё нет. Используется для онбординга нового прибора (клиент узнаёт свой серийник по хэшу EEPROM до первой калибровки).
Формат eepromSha: тот же, что у /active (64 hex нижнего регистра).

200: { "deviceSerial":"0454628", "eepromSha":"00585a32...", "createdAt":"2026-07-01T12:46:55Z" }
404: { "errorCode":"eeprom_key_not_found" }  — хэш не зарегистрирован
422: { "errorCode":"calibration_schema_invalid" }  — eepromSha не 64 hex

B18 / 2026-07-07.

POST /api/calibrations/v1/devices/by-eeprom/{eepromSha}/register Регистрация серийника прибора по SHA EEPROM

Сохраняет соответствие SHA заводской EEPROM → серийный номер прибора (заполняет dbo.DeviceEepromKey). Используется, когда хэш ещё неизвестен серверу: пользователь вводит серийник вручную, клиент регистрирует пару, дальше /identity и /active резолвят её автоматически.
Идемпотентно: повторная регистрация того же хэша с тем же серийником → 200. С ДРУГИМ серийником → 409 (перезапись запрещена, конфликт).

Поле телаОписание
deviceSerial*Серийный номер прибора (ASCII, до 250 симв.)
noteОпциональная заметка (до 500 симв.)
201: { "deviceSerial":"0454628", "eepromSha":"00585a32...", "createdAt":"...", "alreadyRegistered":false }
200: { "deviceSerial":"0454628", "eepromSha":"...", "alreadyRegistered":true }  — уже была та же пара
409: { "errorCode":"eeprom_key_conflict", "deviceSerial":"<существующий>" }  — хэш занят ДРУГИМ серийником
422: { "errorCode":"calibration_schema_invalid" }  — eepromSha не 64 hex, либо deviceSerial отсутствует/невалиден

B18 / 2026-07-07. Валидация серийника против ERP (ItemSn) НЕ выполняется — VeriDepthDB изолирована от IntekDB по Б-044.

GET /api/calibrations/v1/devices/{serial}/calibrations История калибровок

Список всех калибровок прибора (метаданные, без profileJson). Используется клиентом для версионного резолва.

200: { "deviceSerial":"0454628", "calibrations":[
         { "calibrationId":"cal-...", "isActive":true, "uploadedAt":"...", "rmsStereoPx":0.803, "baselineMm":3.556 }
       ] }
POST /api/calibrations/v1/devices/{serial}/calibrations Загрузить новую калибровку
ЗаголовокЗначение
Content-Type*application/json
X-Content-SHA256*SHA-256 hex тела запроса

Тело — JSON схемы calibration-profile/v1. Обязательные поля: schemaVersion, calibrationId, deviceSerial, rmsStereoPx, baselineMm, k5Passed, profileJson.

201: { "calibrationId":"cal-...", "storedAt":"...", "isActive":true }
409: { "errorCode":"calibration_already_exists" }
409: { "errorCode":"device_not_registered", "deviceSerial":"..." }  — серийник не найден в реестре приборов IntekDB.ItemSn
422: { "errorCode":"calibration_schema_invalid", "details":"..." }

ItemSnID резолвится автоматически из IntekDB.dbo.ItemSn по DeviceSerial (кросс-БД, один сервер) — ручная регистрация в ItemSnCalibration не нужна, если прибор уже стоит на учёте в ERP.

DELETE /api/calibrations/v1/devices/{serial}/calibrations/{calibrationId} Soft-delete калибровки

Помечает калибровку удалённой (IsDeleted=1). Данные сохраняются в БД.

200: { "deleted":true }
404: { "errorCode":"calibration_not_found" }
Training Evidence API  /api/training-evidence/v1
POST /api/training-evidence/v1/captures Загрузить PNG-захват
ЗаголовокОписание
Content-Type*image/png
X-Content-SHA256*SHA-256 hex тела (64 символа)
X-Artifact-UidСтабильный UID артефакта (опц.)

Тело — бинарный PNG. Сервер извлекает DeviceId, CalibrationRef, HardwareDeviceId из tEXt Metadata внутри PNG. Повторная загрузка идемпотентна.

201/200: { "sha256":"...", "sizeBytes":1048576, "alreadyExisted":false,
           "extractedDeviceId":"0454628", "evidenceDeviceId":"0454628",
           "hardwareDeviceId":"intek-1_11:vid_192a_pid_0803",
           "extractedCalibrationRef":"cal-...", "artifactUid":null }

→ Просмотреть все загруженные captures

POST /api/training-evidence/v1/captures  video/x-msvideo Загрузить видео-скан stereo_scan_video/v1
ЗаголовокОписание
Content-Type*video/x-msvideo
X-Format-Version*stereo-scan-video/v1
X-Content-SHA256*SHA-256 hex тела
X-Device-Id*ID устройства (напр. 0454628)
X-Hardware-Device-IdHardware ID (опц.)
X-Calibration-RefID калибровки (опц.)
X-Artifact-UidСтабильный UID артефакта (опц.)

Тело — AVI-файл, стерео side-by-side (левый|правый кадр, RGB24). Метаданные из заголовков.

201/200: { "sha256":"...", "sizeBytes":123456, "alreadyExisted":false,
           "formatVersion":"stereo-scan-video/v1", "sourceClass":"scan",
           "evidenceDeviceId":"...", "artifactUid":"..." }
GET /api/training-evidence/v1/captures/{sha256} Скачать capture по SHA-256

Возвращает бинарный файл (PNG или AVI) с оригинальным Content-Type.

200: <binary body>
404: { "errorCode":"capture_not_found" }
POST /api/training-evidence/v1/captures/{sha256}/preview?engine={engineId} Загрузить 3D-превью PNG для движка
ПараметрТипОписание
sha256*pathSHA-256 оригинального capture (64 hex-символа)
engine*queryИдентификатор движка: cre, sgbm, hitnet и т.д. Regex: ^[a-z0-9-]{1,32}$
тело*Content-Type: image/pngPNG-рендер 3D-превью от клиентского Audit3DPreviewRenderer

Хранится в dbo.ApiBinaryBlob с scope te-preview-{engineId}. Идемпотентно (upsert по sha256+engine). Требует флаг CanUploadTrainingEvidence.

200: { "stored":true, "captureSha256":"...", "engineId":"cre", "previewSizeBytes":45678 }
400: { "errorCode":"empty_body" | "invalid_payload" | "invalid_engine" }
403: { "errorCode":"forbidden" }

→ Просмотреть галерею 3D-превью

GET /api/training-evidence/v1/captures/{sha256}/preview?engine={engineId} Скачать 3D-превью PNG для движка
ПараметрТипОписание
sha256*pathSHA-256 оригинального capture
engine*queryИдентификатор движка (тот же, что при POST)
200: <image/png binary>  — превью от указанного движка
404: { "errorCode":"preview_not_found" }  — превью ещё не загружено
400: { "errorCode":"invalid_engine" }

Для отображения в браузере без токена используйте PreviewImage.aspx?sha={sha}&engine={engineId} (admin-только).

POST /api/training-evidence/v1/records Загрузить запись измерения
ЗаголовокЗначение
Content-Type*application/json

Тело — JSON схемы training-evidence/v1. Обязательные поля:

{ "schemaVersion":"training-evidence/v1", "evidenceId":"gtpkg-...",
  "captureSha256":"<sha256 PNG или видео>",
  "deviceId":"0454628", "sourceClass":"point_to_point",
  "conditionBucket":"standard", "consent":"explicit_opt_in",
  "measurementJson":{...}, "groundTruthJson":{...} }
201/200: { "evidenceId":"...", "alreadyExisted":false }
404: { "errorCode":"capture_not_found" }
422: { "errorCode":"schema_invalid", "details":"..." }
GET /api/training-evidence/v1/records Список записей измерений
Query-параметрОписаниеПо умолч.
limitКол-во (1–500)100
offsetСмещение0
deviceIdФильтр по ID устройства
sourceClasspoint_to_point, scan, …
conditionBucketУсловие съёмки
trainableForOwnDeviceBuckettrue/false
hasGroundTruthtrue/false
captureStatusnot_found — осиротевшие (нет живого capture)
GET /api/training-evidence/v1/summary Статистика базы
200: { "totalRecords":26, "totalCaptures":569, "referencedCaptures":23, "unreferencedCaptures":546,
       "byDevice":{...}, "bySourceClass":{...},
       "withGroundTruth":26, "trainableForOwnDeviceBucket":22 }
Distribution API  /api/distributions/v1

⚠ Endpoint /latest возвращает только версии, у которых есть оба артефакта: windows и linux-x64.

GET /api/distributions/v1/latest Последний релиз
200: { "version":"0.9.7.25", "releasedAt":"...",
       "windowsUrl":"/api/distributions/v1/0.9.7.25/windows",
       "linuxUrl":"/api/distributions/v1/0.9.7.25/linux-x64",
       "windowsSha256":"...", "linuxSha256":"...",
       "windowsSizeBytes":156429678, "linuxSizeBytes":53124200 }
404: нет версии с обоими артефактами
GET /api/distributions/v1/latest/{platform}  |  /latest?platform={platform} Последний релиз для ОДНОЙ платформы

В отличие от /latest, не требует наличия ОБОИХ артефактов — берёт самый новый релиз, у которого есть указанная платформа. platform: windows или linux-x64. Именно этот путь использует установщик клиента (DistributionUpdateClient.cs).

200: { "version":"0.9.7.25", "platform":"windows", "downloadUrl":"...", "sha256":"...",
       "sizeBytes":78750873, "filename":"...", "releasedAt":"...", "releaseNotes":"..." }
400: distribution_schema_invalid (platform не windows/linux-x64)
404: distribution_not_found (нет ни одного релиза с этой платформой)

B24.2 / 2026-07-07. Портировано с itcworld (эталонная рабочая копия).

GET /api/distributions/v1/versions Список всех релизов

Все релизы (не только с обоими артефактами), отсортированы по семантической версии убыв.

200: { "items": [ { "version":"...", "releasedAt":"...", "releaseNotes":"...",
       "windows":{...}, "linux_x64":{...} }, ... ] }

B24.2 / 2026-07-07.

GET /api/distributions/v1/{version} Метаданные конкретной версии

Та же структура что /latest. Версия в формате N.N.N.N.

400: distribution_schema_invalid (неверный формат версии)
404: distribution_not_found
GET /api/distributions/v1/{version}/windows  |  /{version}/linux-x64 Скачать дистрибутив

Возвращает бинарный архив (zip / tar.gz) для указанной версии и платформы.

POST /api/distributions/v1/ Загрузить дистрибутив (admin)

Требует CanUploadDistributions=1.

ЗаголовокЗначение
Content-Type*application/zip (windows) или application/x-tar (linux)
X-Version*Версия, напр. 0.9.7.26
X-Platform*windows или linux-x64
X-Content-SHA256*SHA-256 hex тела
Коды ошибок

Все ошибки: { "errorCode":"...", "message":"...", "details":"..." }

errorCodeHTTPЗначение
calibration_not_found404Калибровка не найдена
calibration_already_exists409CalibrationID уже в базе
calibration_schema_invalid422Нарушение схемы calibration-profile/v1
capture_not_found404Capture по SHA256 не найден
schema_invalid400/422Неверный формат запроса
payload_integrity_mismatch400SHA256 тела не совпал с X-Content-SHA256
method_not_allowed405Метод не поддерживается для этого пути
forbidden403Ключ не имеет нужного флага
distribution_not_found404Дистрибутив не найден
server_error500Внутренняя ошибка (детали в details)
Что планируется
#ЗадачаСтатус
Ф-2Re-key 701 PNG (через пересылку, без нового endpoint)Через POST /captures
Ф-3Relink 14 осиротевших recordsЧерез re-POST /records
Ф-6Rich EndpointArray (координаты в мм)Стоп-гейт Владельца