# ShiftLens — AI shift handover prototype

Новый прототип для NeuroBridge.SI / AI Enterprise Solutions, начат 9 октября 2026.
Производственный сценарий: текст или голос оператора → структурированные наблюдения → исходные цитаты → оборудование без сведений → проверка оператором → сохранённая передача смены.

## Запуск на Ubuntu

Требуется только Python 3.10+. npm, Composer, MySQL и внешние Python-пакеты не нужны.

```bash
cd shiftlens
python3 server.py
```

Откройте http://localhost:8080. Работают три учебных примера с заранее подготовленными результатами. Они помечены в интерфейсе и НЕ являются AI-анализом. Любой изменённый текст требует AI-режима.

## Настоящий AI и голос

Ключ задаётся только на сервере. Не присылайте ключ в чат и не добавляйте его в репозиторий.
Остановите сервер Ctrl+C. В терминале Bash:

```bash
# Ввод без отображения на экране и без записи значения в историю команд.
read -rsp 'OpenAI API key: ' OPENAI_API_KEY
export OPENAI_API_KEY
printf '\n'
export OPENAI_MODEL=gpt-4o-mini
export OPENAI_TRANSCRIBE_MODEL=whisper-1
python3 server.py
```

Выберите «Мой отчёт · AI». Можно вводить текст или записать голос (до 90 секунд / 8 МБ). Запись использует MediaRecorder, расшифровка — серверный OpenAI Audio API. Затем проверьте распознанные коды оборудования и нажмите «Разобрать отчёт». Расшифровка НЕ анализирует и НЕ сохраняет передачу смены автоматически.

Модели задаются переменными окружения; нужен API-аккаунт с доступом к выбранным моделям и оплатой. Запросы используют Chat Completions + strict JSON schema. Если API не отвечает или модель отказала, приложение показывает ошибку и не подменяет результат учебным примером.

## Что реализовано

- Интерфейс AZ/RU/EN (AZ по умолчанию), мобильная раскладка, пять учебных единиц оборудования.
- Голос → проверяемая расшифровка → структурированный черновик.
- Каждое наблюдение привязано к дословной цитате с кодом оборудования. Несуществующие цитаты и неизвестные коды блокируются сервером.
- Статусы: «без замечаний по отчёту», «требует внимания», «не подтверждено».
- Объекты без упоминания показаны отдельно; упоминание НЕ доказывает физическую проверку.
- Подтверждение требует имени оператора и явной отметки проверки.
- Клиент передаёт только ID черновика; сохранить подменённое содержимое нельзя.
- Подтверждённые отчёты хранятся в SQLite, доступны для скачивания как JSON после сохранения. Черновики в памяти, срок жизни 1 час.
- Внешних фронтенд-библиотек, шаблонов и компонентов старого SafeShift нет.

## Границы прототипа

Это локальное хакатонное демо, сервер слушает только 127.0.0.1. Учебные данные вымышлены.
Нет QR/NFC, подтверждения местоположения, фотоанализа, реальных датчиков, команд оборудованию, авторизации нескольких пользователей и полноценного журнала безопасности. Для размещения на публичном сервере нужны отдельная настройка HTTPS, аутентификация, лимиты запросов и управление секретами; не открывайте этот сервер напрямую в интернет. На обычном PHP shared hosting этот Python-сервер не запускается без поддержки Python-приложений.

Дословная цитата помогает найти источник, но не доказывает правильность AI-статуса. «Не проверял», отрицания, неоднозначные фразы и prompt injection нужно отдельно проверять на живой модели. Не используйте прототип для решений по промышленной безопасности.

## Проверки

```bash
python3 -m unittest discover -s tests -v
```

Автоматические тесты проверяют программные ограничения и три учебных сценария, а не точность живой AI-модели. Реальный API и микрофон необходимо проверить после подключения ключа. См. QUALITY.md.

## Демо за 90 секунд

1. Учебный пример «Отклонение»: показать четыре сообщения, вибрацию P-101, непроверенный C-201 и отсутствующие сведения по T-401.
2. Показать цитаты и объяснить, что отсутствующие сведения не считаются нормой.
3. Ввести имя, отметить проверку и подтвердить. Скачать JSON.
4. После подключения API перейти в «Мой отчёт · AI», надиктовать новое сообщение, проверить текст и повторить разбор.
5. Указать происхождение результата: учебный пример или фактический OpenAI-запрос. В живом режиме выводятся токены и время анализа.

## Disclosure

Разработано с помощью ChatGPT/Codex. Код новый, написан во время текущего хакатона; старый SafeShift не использован. Python standard library, Vanilla JavaScript, SQLite, browser MediaRecorder. AI providers: OpenAI; configurable analysis model (default gpt-4o-mini), transcription model (default whisper-1). Девять локализованных вымышленных учебных отчётов и их эталонные ответы созданы для демонстрации; они не являются результатами живого вызова модели. Официальный репозиторий задач организаторов в этой сессии не установлен.

## Языки и история разработки

Азербайджанский включён по умолчанию. В правом верхнем углу доступны AZ, RU и EN. Каждый язык имеет три своих учебных отчёта и результаты. При живом AI выбранный язык задаёт язык пояснений; исходные цитаты остаются без перевода. Один голосовой сценарий подтверждён присланным пользователем экспортом; точность азербайджанской речи и кодов на полном наборе записей ещё не измерена.

В архив включена папка `.git`: это настоящая история снимков и изменений с момента её инициализации. Первый коммит — снимок ранее созданной версии, без задней датировки. См. DEVELOPMENT_HISTORY.md и evidence/.

## Обновление v3: защита localhost и диагностика

Добавлены точные проверки Host/Origin, ограничения AI (10 вызовов/мин, максимум 2 одновременно), лимит JSON 80 КиБ, лимит аудио 8 МиБ и тайм-аут чтения клиента. Запросы OpenAI ограничивают длину генерируемого ответа; ошибки DNS/TLS/тайм-аута отображаются отдельно. Сервер остаётся локальным и не имеет авторизации пользователей. Для публичного запуска нужна другая HTTP/session-инфраструктура; см. SECURITY_REVIEW.md.

## Обновление v4 — пояснения и ошибки AI

Если AI не добавил пояснение, карточка честно сообщает об этом на выбранном языке и показывает исходную цитату для проверки. Статус остаётся тем, который вернула модель. Недопустимые статусы, неизвестные коды, выдуманные цитаты и слишком длинные пояснения отклоняются с отдельным сообщением. Добавлены требования к непустому пояснению в схеме и запросе. 46 автоматических проверок пройдены; живой браузерный сценарий обновления ещё нужно подтвердить.

## Обновление v5 — коды оборудования после голосовой расшифровки

Известные коды P101, P 101, p-101 и варианты тире распознаются как P-101 (аналогично остальным четырём кодам). Карточки используют канонический ID; исходные текст и цитата сохраняются без изменений. В интерфейсе и JSON видно, какие варианты распознаны. P1010, XP101, неизвестные номера и выдуманные/изменённые цитаты отклоняются. Числа, записанные словами, и ошибочно распознанные слова автоматически не исправляются: оператор должен проверить расшифровку перед анализом. 53 программных проверки пройдены; повторная живая проверка голоса ещё нужна.

## Обновление v6 — цитаты из исходного текста

AI возвращает только код оборудования, статус и пояснение. Цитата берётся сервером из исходного текста: от маркера оборудования до следующего маркера. Для повторных упоминаний берётся непрерывный диапазон, охватывающий все его блоки; он может включать другое оборудование. Исходный текст не исправляется и не переводится. JSON содержит evidence_source с методом и смещениями в Unicode code points. Содержимое цитаты не генерируется моделью. Если AI пропустил явно упомянутый код, отчёт отклоняется. Указанные диапазоны — способ найти исходный контекст, а не доказательство правильного статуса или выполненного обхода. 61 программная проверка пройдена. Пользователь прислал успешный v6-экспорт для отрицания и сведений со слов коллеги; полная матрица живых тестов ещё не завершена. См. LIVE_V6_ACCEPTANCE_CHECK.json и BUSINESS_CASE_AZ.md.
