Перейти к основному содержимому

Детали реализации

Структура базы данных

Таблица Album

Хранит информацию об альбомах и настройках распознавания.

Поля:

  • AlbumId — идентификатор альбома
  • TenantId — идентификатор тенанта
  • Name — название альбома
  • EventDate — дата события
  • CreatedOn, UpdatedOn, Version — системные поля
  • Strategy - стратегия распознавания (строка, название пайплайна)
  • State — состояние распознавание (включено/выключено)
  • StartNumberCapacity — разрядность номеров
  • NormalizationPolicy — политика нормализации номеров
  • Priority — приоритет обработки

Таблица Photo

Хранит информацию о фотографиях и состоянии их распознавания.

Поля:

  • PhotoId — идентификатор фотографии
  • AlbumId — идентификатор альбома
  • State — состояние обработки фотографии
  • CreatedOn, UpdatedOn, Version — системные поля
  • ReasonDescription — описание причины текущего состояния
  • Признаки распознавания (добавляются):
    • FaceRecognized — лица распознаны
    • NumberRecognized — номера распознаны

Признаки распознавания нужны для того, чтобы при смене стратегии распознавания выбирать из базы только фотографии, которые нужно распознать в новой стратегии. Например, если новая стратегия предполагает распознавание и лиц, и номеров, нужно выбрать все, у которых не распознаны лица или номера. Проблема в том, что могли уже отдать фотографию на распознавание номеров, но ожидаем колбек, и в этот момент изменили стратегию на ту, которая требует распознавания номеров. С одной стороны, номера еще не распознаны, поэтому нужно выбрать эту фотографию. С другой стороны, нет смысла ее снова обрабатывать, т.к. ожидаем колбека. С третьей стороны, могли авто распознавание (с колбеком) заменить на ручное распознавание (например, если колбеки уже не придут), тогда фото все же нужно взять. Поэтому оставляем пока с этой проблемой. Нет колбека - номера не распознаны - обрабатываем фото.

Таблица Tenant

Хранит информацию о тенантах.

Поля:

  • TenantId — идентификатор тенанта
  • RecognitionState — состояние распознавания
  • CreatedOn, UpdatedOn, Version — системные поля

Таблицы без изменений

Следующие таблицы переносятся без изменений:

  • AlbumCustomTag — кастомные теги для альбомов
  • Callback — колбеки от Athlete
  • Account — аккаунты VkVision
  • AccountSpace — спейсы VkVision
  • PhotoPerson — связь фото и персон

Интерфейс Athlete (Eldarius)

Запрос на распознавание

Тип распознавания:

recognition_type = FACE_NUMBER

Одним запросом получаем и лица, и номера.

Callback

public sealed class CallbackPayloadBinding
{
[Required]
[JsonPropertyName("persons")]
public IEnumerable<CallbackPersonBinding> Persons { get; set; } = null!;

[Required]
[JsonPropertyName("tags")]
public IEnumerable<CallbackPersonBinding> Tags { get; set; } = null!;
}

API сервиса

AdminApi

AlbumController

GET /api/v{version}/albums/{albumId}

Получить альбом по ID.

Аутентификация: требуется роль recognition.manage.

Параметры маршрута:

  • albumId: guid — идентификатор альбома

Ответы:

200 OK:

{
"name": "string",
"startNumbersRecognitionStrategy": "string",
"startNumberCapacity": 0,
"normalizationPolicy": "string",
"priority": 0,
"eventDate": "2024-01-01T00:00:00Z",
"createdOn": "2024-01-01T00:00:00Z",
"updatedOn": "2024-01-01T00:00:00Z",
"allowedStrategies": ["string"],
"allowedFaceProviders": [
{
"name": "string",
"providerId": "guid"
}
],
"recognition": {
"faceProviderId": "guid",
"faceProviderSpaceId": "guid"
}
}

404 Not Found — альбом не найден.

Обновления:

  • Из allowedFaceProviders будет удален провайдер Disabled. Фронт сам должен добавить этот вариант, и если он выбран, передать null в метод изменения настроек распознавания.
  • Поля recognitionStrategy и taggingStrategy сейчас сохранены для обратной совместимости, но будут удалены, вместо них - поле startNumbersRecognitionStrategy.
  • Поле allowedStrategies сейчас сохранено для обратной совместимости, но будет удалено, вместо него - поле allowedStartNumbersRecognitionStrategies.

PATCH /api/v{version}/albums/{albumId}/priority

Изменить приоритет альбома.

Аутентификация: требуется роль recognition.manage.

Параметры маршрута:

  • albumId: guid — идентификатор альбома

Тело запроса:

{
"priority": 0
}

Поле priority является обязательным ([Required]).

Ответы:

  • 204 No Content — приоритет успешно изменён
  • 404 Not Found — альбом не найден
  • 409 Conflict — конфликт версий (оптимистичная блокировка)
  • 422 Unprocessable Entity — невалидные данные

PATCH /api/v{version}/albums/{albumId}/recognition/settings

Изменить настройки распознавания альбома.

Аутентификация: требуется роль recognition.manage.

Параметры маршрута:

  • albumId: guid — идентификатор альбома

Тело запроса:

Текущий вид биндинга (для обратной совместимости — поля nullable):

{
"providerId": "guid",
"providerSpaceId": "guid",
"startNumbersRecognitionStrategy": "string | null",
"normalizationPolicy": "string | null",
"startNumberCapacity": "integer | null"
}

После исправления фронтенда поля startNumbersRecognitionStrategy, normalizationPolicy и startNumberCapacity станут обязательными:

{
"providerId": "guid",
"providerSpaceId": "guid",
"startNumbersRecognitionStrategy": "string",
"normalizationPolicy": "string",
"startNumberCapacity": 0
}

Поведение:

  • Если startNumbersRecognitionStrategy == null (режим обратной совместимости): изменяется только провайдер лица (ChangeAlbumFaceProviderCommand). Поля normalizationPolicy и startNumberCapacity игнорируются.
  • Если startNumbersRecognitionStrategy указан: изменяются все настройки распознавания (ChangeAlbumRecognitionSettingsCommand).
  • Если нужно отключить распознавание лиц, нужно передавать providerId=null.

Ответы:

  • 204 No Content — настройки успешно изменены
  • 404 Not Found — альбом или провайдер не найден
  • 409 Conflict — конфликт версий (оптимистичная блокировка)
  • 422 Unprocessable Entity — невалидные данные

SettingsController

Эндпоинты:

  • PATCH /api/v{version}/settings/{tagatorId}/changeTagatorSettings — изменить настройки тегатора
  • GET /api/v{version}/settings/{tagatorId}/tagatorSettings — получить настройки тегатора

TenantsController

Эндпоинты:

  • GET /api/v{version}/tenants/{tenantId} — получить тенант по ID
  • PUT /api/v{version}/tenants/{tenantId}/recognition — включить/выключить распознавание для тенанта

StatisticController

Эндпоинты:

  • GET /api/v{version}/statistics/byAlbums — статистика по альбомам
  • GET /api/v{version}/statistics/timeSheetsByInterval — статистика табелей по интервалам

TagatorController

Эндпоинты:

  • POST /api/v{version}/tagators — создать тегатора
  • PATCH /api/v{version}/tagators/{tagatorId} — изменить тегатора
  • POST /api/v{version}/tagators/{tagatorId}/password — изменить пароль тегатора
  • GET /api/v{version}/tagators/{tagatorId} — получить тегатора по ID
  • GET /api/v{version}/tagators/{tagatorId}/statistic — статистика тегатора
  • POST /api/v{version}/tagators/tagator-report — отчет по тегаторам
  • GET /api/v{version}/tagators — список тегаторов с пагинацией
  • POST /api/v{version}/tagators/invitation-tagging — пригласить тегаторов

TagatorTasksController

Эндпоинты:

  • POST /api/v{version}/tasks/callback — колбек завершения задачи тегирования

SelfiesController

Эндпоинты:

  • POST /api/v{version}/selfies — распознать селфи

AccountsController

Эндпоинты:

  • POST /api/v{version}/accounts — создать аккаунт VkVision
  • PATCH /api/v{version}/accounts/{accountId} — изменить аккаунт
  • GET /api/v{version}/accounts — список аккаунтов
  • GET /api/v{version}/accounts/{accountId} — получить аккаунт по ID
  • PUT /api/v{version}/accounts/{accountId}/active — изменить состояние аккаунта
  • GET /api/v{version}/accounts/{accountId}/spaces — получить спейсы аккаунта
  • GET /api/v{version}/accounts/{accountId}/spaces/{accountSpaceId} — получить спейс по ID
  • POST /api/v{version}/accounts/{accountId}/spaces — добавить спейс
  • PATCH /api/v{version}/accounts/{accountId}/spaces/{accountSpaceId} — изменить спейс
  • PUT /api/v{version}/accounts/{accountId}/spaces/{accountSpaceId}/active — изменить состояние спейса

ClientApi

SelfiesController

Эндпоинты:

  • POST /api/v{version}/selfies — распознать селфи
  • GET /api/v{version}/selfies/{selfieId} — получить детали селфи

AvatarTasksController

Эндпоинты:

  • POST /api/v{version}/avatar/tasks/callback — колбек задачи распознавания аватара

EldariusTasksController

Эндпоинты:

  • POST /api/v{version}/auto-tagging/tasks/callback — колбек задачи автотегирования

TagatorAccountController

Эндпоинты:

  • POST /api/v{version}/accounts/signin — вход тегатора
  • GET /api/v{version}/accounts — получить данные аккаунта

AlbumsController

Эндпоинты:

  • GET /api/v{version}/albums/{albumId}/customTags — получить кастомные теги
  • GET /api/v{version}/albums/{albumId}/taggingHint — получить подсказку для тегирования

TagatorWorksController

Эндпоинты:

  • POST /api/v{version}/works — создать работу тегатора
  • GET /api/v{version}/works/current — получить текущую работу
  • GET /api/v{version}/works/{tagatorWorkId} — получить работу по ID
  • GET /api/v{version}/works/{tagatorWorkId}/tasks — получить задачи работы
  • PUT /api/v{version}/works/{tagatorWorkId}/tasks/{taggingTaskId}/complete — завершить задачу
  • POST /api/v{version}/works/{tagatorWorkId}/tasks/{taggingTaskId}/tags — добавить теги
  • DELETE /api/v{version}/works/{tagatorWorkId}/tasks/{taggingTaskId}/tags — удалить теги

InternalApi

AlbumController

Эндпоинты:

  • GET /api/v{version}/albums/{albumId} — получить альбом по ID
  • GET /api/v{version}/albums/{albumId}/counter/photos — количество фото по статусу

TagatorsController

Эндпоинты:

  • GET /api/v{version}/tagators/{tagatorId} — получить тегатора по ID

StatisticsController

Эндпоинты:

  • GET /api/v{version}/statistics/tagators — статистика тегаторов

Команды и обработчики

Переписываемые джобы

AlbumPhotosProcessingJob

Текущая логика:

  • Перебирает все фотографии альбома
  • Создает задачи на обработку

Новая логика:

  • Выбирает только фото, требующие обработки согласно стратегии
  • Использует признаки состояния распознавания (FaceRecognized, NumberRecognized)
  • Учитывает наличие тегов и персон
  • Обрабатывает только необходимые фото

Команды обработки

Обработка PhotoPublished

Процесс:

  1. Создать локальную запись фотографии
  2. Определить стратегию альбома
  3. Обработать фото сразу (синхронно):
    • Для VkVision — распознать лица и сохранить результат
    • Для Athlete — отправить запрос на распознавание
    • Для ручного — создать задачу тегирования
  4. При ошибке — создать Hangfire-джобу для повторной обработки
  5. Завершить подписку

Обработка PhotoDeleted

Процесс:

  1. Отменить задачи тегирования через InternalApi
  2. Выполнить команду CancelTaggingTaskCommand

Интеграция с другими сервисами

PhotoService

Отправка результатов:

  • Персоны (лица) — после распознавания в VkVision или получения callback от Athlete
  • Теги (номера) — после распознавания в Athlete или завершения ручного тегирования

TagatorService

Создание задач:

  • Передача PhotoId, AlbumId, PhotographerId, ShootingDate
  • Назначение приоритета
  • Контроль состояния задач

Отмена задач:

  • При удалении фото
  • При изменении стратегии (если задача больше не нужна)

CompetitorService

Обращение:

  • Определить инстанс CompetitorService по настройкам проекта/тенанта
  • Выполнить запрос к соответствующему инстансу
  • Получить стартовый список для валидации

Миграция данных

Этапы миграции

  1. Подготовка:

    • Создать новую БД для сервиса распознавания
    • Развернуть схему БД
  2. Миграция данных:

    • Объединить данные из RecognitionService и TaggingService
    • Перенести альбомы, фотографии, задачи
    • Объединить дублирующиеся записи
    • Проверить целостность данных
  3. Синхронизация:

    • Настроить синхронизацию новых данных в процессе миграции
    • Обеспечить консистентность
  4. Переключение:

    • Развернуть новый сервис
    • Переключить маршрутизацию запросов
    • Остановить старые сервисы

Скрипты миграции

Требуется разработать SQL-скрипты для:

  • Создания структуры БД
  • Переноса данных из RecognitionService
  • Переноса данных из TaggingService
  • Объединения дублирующихся записей
  • Проверки целостности

Технические доработки

Удаление джоб отмены задач

После объединения сервисов:

  • Убрать джобы отмены задач при удалении фото
  • Использовать прямой вызов метода InternalApi
  • Выполнять команду CancelTaggingTaskCommand

Аналогично для RejectTagatorTaggingTasksJob.

Валидация и разрядность

  • Валидация результатов по стартовому списку сохраняется
  • Учет разрядности номеров в Athlete сохраняется

Команды, квери и джобы

Сохранить из текущих сервисов:

  • Команды создания, обновления, удаления сущностей
  • Квери получения данных
  • Джобы фоновой обработки

Внести изменения:

  • Интеграция с Athlete для получения persons и tags
  • Переработка AlbumPhotosProcessingJob
  • Оптимизация обработки фото (устранение промежуточных статусов)
  • Команды для работы с аккаунтами и спейсами VkVision

Развертывание

Конфигурация (неправильно)

Добавить конфигурационные файлы:

  • appsettings.json — основные настройки
  • appsettings.Development.json — настройки для dev
  • appsettings.Production.json — настройки для prod

CI/CD

Добавить:

  • .gitlab-ci.yml — пайплайн сборки и деплоя
  • Dockerfile — образ для контейнеризации

Helm Charts

Создать charts для развертывания в Kubernetes:

  • Deployment
  • Service
  • ConfigMap
  • Secrets
  • Ingress