12
This commit is contained in:
@@ -1,166 +0,0 @@
|
||||
# chestny-znak-web-app — План реализации тестового web-приложения для API Честного знака
|
||||
|
||||
**Статус:** Активен
|
||||
|
||||
## Описание задачи
|
||||
|
||||
Проанализировать API «Честный знак» (ГИС МТ, True API) и создать план реализации тестового web-приложения, которое позволяет:
|
||||
1. Авторизоваться в системе (подписать тестовый набор данных УКЭП)
|
||||
2. Получить информацию о QR-кодах (КМ) из УПД — актуальны или нет
|
||||
|
||||
## Результаты анализа API
|
||||
|
||||
### Документация True API
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Официальная документация | https://docs.crpt.ru/gismt/True_API/ |
|
||||
| Тестовый контур (sandbox) | `https://markirovka.sandbox.crptech.ru/api/v3/true-api` |
|
||||
| Промышленный контур | `https://markirovka.crpt.ru/api/v3/true-api` |
|
||||
| Версия API | v3/v4 |
|
||||
| Формат | REST, JSON |
|
||||
| Аутентификация | УКЭП (ГОСТ, CAdES-BES) → Bearer token |
|
||||
|
||||
### Процесс аутентификации (Единая аутентификация)
|
||||
|
||||
```
|
||||
Шаг 1: GET /auth/key → { uuid, data }
|
||||
(получаем UUID и случайную строку для подписи)
|
||||
|
||||
Шаг 2: Подписать data УКЭП (CAdES-BES, присоединённая подпись, base64)
|
||||
(требуется КриптоПро или совместимое СКЗИ)
|
||||
|
||||
Шаг 3: POST /auth/simpleSignIn → { token, uuidToken?, expireDate? }
|
||||
Body: { uuid: "<uuid>", data: "<base64 signature>" }
|
||||
```
|
||||
|
||||
- Срок действия токена: **не более 10 часов**
|
||||
- Форматы токена: JWT (по умолчанию) или UUID (параметр `unitedToken: true`)
|
||||
- Поддержка JWT — до марта 2026 года, UUID — основной формат
|
||||
|
||||
### Ключевые методы для задачи
|
||||
|
||||
| Метод | Endpoint | Описание |
|
||||
|-------|----------|----------|
|
||||
| Получение информации о КМ | `POST /api/v3/true-api/cises/info` | Статус, производитель, собственник, GTIN |
|
||||
| Проверка кодов (розница) | `POST /api/v4/true-api/codes/check` | Проверка перед продажей |
|
||||
| Публичная проверка | `GET https://mobile.api.crpt.ru/mobile/check?code=<код>` | Без авторизации (недокументированный эндпоинт моб. приложения) |
|
||||
| Поиск КМ | `POST /api/v4/true-api/cises/search` | Поиск по фильтрам |
|
||||
|
||||
### Пример публичного API (без авторизации)
|
||||
|
||||
Запрос:
|
||||
```
|
||||
GET https://mobile.api.crpt.ru/mobile/check?code=0104640507713421215TxdVFoOB.zFF
|
||||
```
|
||||
|
||||
Ответ (JSON):
|
||||
```json
|
||||
{
|
||||
"code": "0104640507713421215TxdVFoOB.zFF",
|
||||
"found": true,
|
||||
"valid": true,
|
||||
"status": "INTRODUCED"
|
||||
}
|
||||
```
|
||||
|
||||
**Ограничения публичного API:**
|
||||
- Не требует аутентификации — можно использовать для быстрой проверки единичных кодов
|
||||
- Возвращает минимум данных: только статус и флаг валидности
|
||||
- Не подходит для пакетной проверки (по одному коду за запрос)
|
||||
- Не документирован официально (эндпоинт мобильного приложения)
|
||||
|
||||
**Для полноценной проверки КМ из УПД рекомендуется использовать авторизованный метод** `POST /api/v3/true-api/cises/info`, который возвращает полную информацию: GTIN, наименование товара, производителя, владельца, дату ввода в оборот и т.д.
|
||||
|
||||
### Структура ответа /cises/info
|
||||
|
||||
```json
|
||||
{
|
||||
"cisInfo": [{
|
||||
"requestedCis": "0104600702028445...",
|
||||
"cis": "0104600702028445...",
|
||||
"gtin": "04600702028445",
|
||||
"status": "INTRODUCED",
|
||||
"productName": "Молоко 3.2%",
|
||||
"productGroup": "Молочная продукция",
|
||||
"producerName": "АО \"Данон Россия\"",
|
||||
"ownerName": "ООО Магнит",
|
||||
"ownerBin": "2309085638",
|
||||
"producedDate": "2025-01-15T10:00:00.000Z",
|
||||
"packageType": "UNIT"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
**Статусы КМ:** `EMITTED` (эмитирован), `APPLIED` (нанесён), `INTRODUCED` (в обороте), `RETIRED` (выбыл), `WRITTEN_OFF` (списан), `DISAGGREGATION` (расформирован), `CANCELLED` (аннулирован)
|
||||
|
||||
### Работа с УПД
|
||||
|
||||
- Коды маркировки в XML УПД (формат Приказа №970 ФНС) находятся в элементе `Документ/ТаблСчФакт/СведТов/ДопСведТов/НомСредИдентТов`
|
||||
- При проверке QR-кодов из УПД необходимо:
|
||||
1. Загрузить XML УПД (формат 970 приказа)
|
||||
2. Распарсить XML по XPath: `//Документ/ТаблСчФакт/СведТов/ДопСведТов/НомСредИдентТов`
|
||||
3. Извлечь все коды маркировки
|
||||
4. Отправить запрос в `/cises/info` (с авторизацией)
|
||||
5. Отобразить статус каждого кода
|
||||
|
||||
---
|
||||
|
||||
## Шаги
|
||||
|
||||
- [ ] 1. **Инициализация проекта** — создать Fastify/Express backend + React frontend. Оба сервиса запускаются через `docker-compose`
|
||||
- [ ] 2. **Backend: модуль аутентификации**
|
||||
- 2.1. Реализовать `GET /auth/key` — получение UUID + data от True API
|
||||
- 2.2. Реализовать подпись data через КриптоПро с помощью `@vgoma/crypto-pro` (Node.js binding для КриптоПро CSP)
|
||||
- 2.3. Реализовать `POST /auth/simpleSignIn` — получение токена
|
||||
- 2.4. Кеширование и auto-refresh токена (раз в 10 часов)
|
||||
- [ ] 3. **Backend: модуль проверки КМ**
|
||||
- 3.1. Реализовать `POST /api/check-codes` — принимает массив кодов маркировки
|
||||
- 3.2. Вызов `POST /api/v3/true-api/cises/info` для каждого кода (батчами до 1000)
|
||||
- 3.3. Возврат статуса: актуален / неактуален / не найден / ошибка
|
||||
- [ ] 4. **Backend: модуль обработки УПД**
|
||||
- 4.1. Приём XML-файла УПД через `POST /api/upload-upd`
|
||||
- 4.2. Парсинг XML, извлечение кодов маркировки из `НомСредИдентТов`
|
||||
- 4.3. Передача кодов в модуль проверки КМ (шаг 3)
|
||||
- [ ] 5. **Frontend: страница авторизации**
|
||||
- 5.1. Форма ввода/загрузки сертификата УКЭП
|
||||
- 5.2. Отображение статуса авторизации и срока действия токена
|
||||
- [ ] 6. **Frontend: страница проверки QR-кодов**
|
||||
- 6.1. **Проверка одного кода** — поле ввода + две кнопки:
|
||||
- «Проверить без авторизации» — через публичный API (`mobile.api.crpt.ru/mobile/check`), минимум данных
|
||||
- «Проверить с авторизацией» — через `POST /cises/info`, полная информация: GTIN, наименование, производитель, владелец, статус
|
||||
- 6.2. **Загрузка XML УПД (формат 970 приказа)** — drag & drop / file picker, парсинг на backend, пакетная проверка через `/cises/info`
|
||||
- 6.3. Таблица результатов: код, GTIN, наименование, статус, производитель, владелец
|
||||
- 6.4. Цветовая индикация: зелёный (актуален / в обороте), красный (выбыл / списан), жёлтый (предупреждение)
|
||||
- [ ] 7. **Тестирование на sandbox**
|
||||
- 7.1. Получение тестового УКЭП через testca2012.cryptopro.ru
|
||||
- 7.2. Регистрация в sandbox (markirovka.sandbox.crptech.ru)
|
||||
- 7.3. Интеграционные тесты: авторизация → проверка кодов
|
||||
- [ ] 8. **Docker-сборка**
|
||||
- 8.1. `Dockerfile.backend` — backend-образ с Node.js + установленным КриптоПро CSP (`crypto-pro`)
|
||||
- 8.2. `Dockerfile.frontend` — nginx-образ со статикой React-приложения
|
||||
- 8.3. `docker-compose.yml` — сервисы `backend`, `frontend`, общая сеть
|
||||
- 8.4. README с инструкцией по запуску (`docker-compose up --build`)
|
||||
|
||||
- [x] 9. **Переключение контура (sandbox/prod) из UI**
|
||||
- 9.1. Backend: два набора URL (`envUrls`) в `config.ts`, per-env кеш токенов
|
||||
- 9.2. Backend: все сервисы и роуты принимают `?env=sandbox|prod`
|
||||
- 9.3. Frontend: `<select>` в хедере, `getEnv()`/`setEnv()` в модуле API
|
||||
- 9.4. QA-доработки:
|
||||
- `onUnauthorized` передаёт env — логаут правильного контура при 401
|
||||
- `window.confirm` при переключении на промышленный контур
|
||||
- `setPage('auth')` при смене env
|
||||
- `getAuthStatus` при переключении — восстановление `authenticated` если токен жив
|
||||
- `uploadUpd` через общий `request()` (устранено дублирование)
|
||||
|
||||
## Затрагиваемые сервисы
|
||||
|
||||
- `backend/` — Fastify/Express backend с модулями:
|
||||
- `auth-service` — получение и менеджмент токена True API
|
||||
- `crypto-service` — подпись данных через `@vgoma/crypto-pro` (КриптоПро CSP)
|
||||
- `cises-service` — проверка статусов кодов маркировки через `/cises/info`
|
||||
- `upd-parser` — парсинг XML УПД и извлечение кодов
|
||||
- `frontend/` — React (Next.js) SPA:
|
||||
- Страница авторизации
|
||||
- Страница проверки кодов
|
||||
- Компонент загрузки УПД
|
||||
Reference in New Issue
Block a user