feat: migrate to VitePress from monorepo docs, add test-contour section

This commit is contained in:
sova-bootstrap
2026-05-28 12:29:31 +03:00
parent e90dfe1bd4
commit e3e438df68
76 changed files with 11998 additions and 60 deletions
+75
View File
@@ -0,0 +1,75 @@
---
title: Отметка киоска clvisitsovacheckpass (Backend)
---
# Сценарий 3.3: Проверка / отметка киоска (`clvisitsovacheckpass`)
## Бизнес-цель
В филиале может стоять **киоск** самообслуживания. Когда пациент авторизован в приложении, backend фиксирует факт «проверки прохода» для пары **пациент (`pcode`/`uid`) + филиал**, чтобы киоск знал, можно ли продолжить сценарий (метод возвращает булев признак `isResult()` у сущности `MarkKiosk`).
## Точки входа
| Тип | Метод + URL | Класс |
| --- | --- | --- |
| HTTP | `GET /infoclinica/clvisitsovacheckpass/{filial}` | `InfoclinicaController::clvisitsovacheckpass` |
Доступ: `#[IsGranted('ROLE_USER')]` — нужен JWT. `filial` — целочисленный идентификатор из URL.
## Что такое `pcode` здесь
Внутри метода берётся **текущий пользователь** через `JWTDecoderService::getUser()`, далее `$user->getUid()` трактуется как **`pcode` пациента** для записи в `MarkKiosk`. То есть это **тот же числовой uid**, что хранится в `users.uid` после сценариев [auth-uid-pcode.md](./auth-uid-pcode.md).
## Пошаговый алгоритм
1. Проверка JWT; если пользователь не найден — `401` с телом `{"error":"Пользователь не найден"}`.
2. `$pcode = $user->getUid()`.
3. Репозиторий `MarkKiosk` ищет запись по паре `['pcode' => $pcode, 'filial' => $filial]`.
4. Если записи нет — создаётся `new MarkKiosk()` с `pcode`, `filial`, `createdAt`/`modifyAt` (текущее время), `persist` + `flush`.
5. Повторная выборка той же сущности (как в коде после создания).
6. Ответ API: JSON c булевым полем из `MarkKiosk::isResult()` — для **новой** строки поле `result` в сущности по умолчанию **`null`** (в setter при создании в контроллере `result` не выставляется).
## Mermaid
```mermaid
sequenceDiagram
participant K as Киоск / клиент
participant IC as InfoclinicaController
participant JWT as JWTDecoderService
participant EM as EntityManager
participant MK as MarkKiosk
K->>IC: GET .../clvisitsovacheckpass/{filial} + JWT
IC->>JWT: getUser()
alt нет пользователя
IC-->>K: 401
else ok
IC->>EM: find MarkKiosk pcode+filial
alt нет строки
IC->>EM: persist новый MarkKiosk
end
EM-->>IC: MarkKiosk
IC-->>K: {result: isResult()}
end
```
## Внешние зависимости
| Система | Роль |
| --- | --- |
| PostgreSQL | таблица `mark_kiosk` (имя по маппингу Doctrine) |
| Инфоклиника | **не вызывается** в этом методе; имя маршрута исторически связано с MIS |
## Обработка ошибок и edge cases
- **Нет JWT / неверный токен** — ответ средства Symfony Security (не разобран в контроллере).
- **Повторный вызов** — запись уже есть; логика `isResult()` определяет, что отдать киоску при повторе (см. `Entity/MarkKiosk.php`).
- **У пользователя нет `uid`** — маловероятно по модели, но при `0` возможны коллизии — вопрос целостности данных.
## Ссылки на классы
- `apps/backend/src/Controller/InfoclinicaController.php`
- `apps/backend/src/Entity/MarkKiosk.php`
- `apps/backend/src/Service/DecoderJWT/JWTDecoderService.php`
Карта домена: [backend-ddd.md](../backend-ddd.md).