Files
tech-service-portal/README.md
T
darkorion 0f239d5015 feat: документация из Nextcloud, график у сотрудника, автоочистка фото, мониторинг, итог мастера, фильтр по местам; доп. сервисы в docker-compose
- docker-compose.yml: профили docs (Nextcloud), office (ONLYOFFICE Document Server), ai (Ollama + скачивание модели)
- автонастройка: адреса Nextcloud, ONLYOFFICE, портала и модели подставляются из .env или по именам сервисов
  во внутренней сети Docker; значения из интерфейса важнее
- локальная модель в своей сети (имя сервиса, частный IP) подключается без ключа API
- .env.example, docs/DEPLOY.md (раздел 7а), README
2026-10-13 13:27:20 +03:00

24 KiB
Raw Blame History

Портал технической службы (чек-листы, наряды, инструмент)

FastAPI + SQLAlchemy, веб-интерфейс на чистом JS, JWT-API для будущего Android-приложения. Документация API (Swagger): /docs.

Модель

  • Должность (technician / engineer) имеет график (по дням недели или цикл N/M, дневная/ночная смена). Пользователь привязывается к должности администратором.
  • Чек-лист — список задач; тип ответа: статус (в работе/выполнено), список, число (с границами), текст.
  • Шаблон наряда — единожды настроенный наряд + периодичность (каждый день / дни недели / раз в месяц / каждые N дней). Планировщик внутри приложения создаёт из него наряды.
  • Наряд — копия чек-листа с оборудованием, местом, исполнителем и проверяющим. Исполнитель: конкретный человек или должность (тогда наряд видят те, кто сейчас на смене; кто первый начал — тот исполнитель). Статусы: new → in_progress → review → completed (проверяющий может вернуть на доработку), cancelled.
  • Права: техник — только свои наряды; инженер — всё про наряды/чек-листы/оборудование + проверка; админ — ещё пользователи, должности, графики.

Документация

  • Руководство пользователя (PDF) — для техников, инженеров, модераторов и администраторов: скриншоты с пометками, работа без связи, проверка, графики, отчёты, FAQ. Пересборка: tools/guide.
  • docs/DEPLOY.md — установка на свой сервер (Docker Compose); docs/API.md — описание API для разработчика клиентов; android/README.md — сборка приложения.

Роли

  • Администратор — всё, включая «Настройки сервера» (каталог фото, лимит размера, контакт push).
  • Модератор — панель «Администрирование»: пользователи, должности, графики, чек-листы, оборудование, наряды; не меняет администраторов, не выдаёт права, не видит настройки сервера, сам наряды не выполняет.
  • Инженер / техник — по типу должности (см. выше).

Android-приложение

Нативное приложение (Kotlin + Compose) в каталоге android/: список и выполнение нарядов, фото с камеры, комментарии, проверка для инженеров, полноценная работа без связи (накопленное уходит на сервер само), уведомления. Распространяется APK-файлом: готовая версия лежит в release/ и раздаётся по https://<домен>/app.apk (ссылка на экране входа); новый файл можно положить в DATA_DIR/apk/ — он важнее.

Мобильная версия в браузере (PWA)

Запасной вариант, если приложение недоступно (например, iPhone): https://<домен>/m. Устанавливается на экран «Домой» (Android: «Установить приложение»; iPhone: «Поделиться → На экран Домой»), работает полностью без связи: наряды и чек-листы хранятся в браузере (IndexedDB), ответы, фото, комментарии и сдача копятся в очереди и уходят сами (фото с Idempotency-Key, ответы пачкой через /orders/{id}/sync). Все экраны: список с фильтрами и поиском, чек-лист с крупными кнопками, фото с камеры, комментарии, проверка для инженеров, уведомления (Web Push), выход.

  • С телефона на основном адресе предлагается перейти на /m (выбор «Остаться» запоминается); на ПК остаётся полная версия.
  • Файлы: app/static/m/ (m.js, m.css, manifest, иконки); service worker — app/static/sw.js (кэш оболочки + push).
  • Ограничения iOS: нет фоновой синхронизации (отправка идёт, пока приложение открыто), push работает только у установленной PWA (iOS 16.4+) и только по HTTPS. Данные браузера iOS может очистить, если не открывать сайт долго.

Демонстрационный режим (личный)

«Администрирование → Демонстрационный режим». Демо включается только для того, кто его включил: его запросы идут в отдельную SQLite-базу с тестовыми данными (сотрудники, оборудование и краны, чек-листы, наряды и задачи за 14 дней, карты, склады, инциденты), остальные пользователи продолжают работать с рабочей базой. Администратор может включить или выключить демо любому сотруднику. Тестовые учётные записи (пароль demo1234) работают параллельно с рабочими. Приложение для Android и мобильная версия при смене режима очищают локальные данные. Подробнее — docs/API.md, раздел «Демонстрационный режим».

Графики и отчёты

  • Графики: по дням недели, простой цикл N через M или конструктор цикла из шагов (смена/выходной, любая длительность, дневные, ночные и суточные смены, метки «отсыпной» и т. п.) с календарём-предпросмотром на 6 недель.
  • Отчёты → «Выполненные наряды»: машина, чек-лист, кто выполнил, должность, когда. Период (дата+время) обязателен; фильтры по машине, должности, исполнителю; экспорт в PDF и CSV. Шрифт DejaVu лежит в app/fonts (кириллица в PDF).

Регламентное обслуживание и «Текущее состояние»

  • Узлы машины. Карточка машины («Оборудование» → «Узлы и наработка») хранит наработку (моточасы) и список обслуживаемых узлов: масло, фильтры, ремни и т. п. Для каждого узла выбирается, как он обслуживается: по наработке (каждые N м/ч), по календарю (раз в N дней / недель / месяцев) или что наступит раньше; задаётся порог предупреждения «Скоро» (% от интервала). При добавлении указывается, когда и при какой наработке узел обслуживался в последний раз.
  • Чек-лист «Регламентное обслуживание». Тип чек-листа в редакторе. В наряд подставляются: показание наработки машины, ваши обычные задачи и по пункту «обслужено?» на каждый узел выбранной машины (можно только «Требуется/Скоро»). Оборудование обязательно. Когда наряд завершён (после проверки, если она есть), отмеченные узлы сбрасываются, а наработка машины обновляется. Работает и в автозапуске (шаблоны нарядов). Android-приложение показывает пункты узлов с остатком и содержит экран «Состояние узлов» (наработка, сброс); мобильная версия — как обычные задачи.
  • Сброс узла вручную — если замена или обслуживание выполнены отдельно либо при внештатной ситуации (дата, наработка, комментарий; всё в истории узла). Показание счётчика не может уменьшаться, кроме «коррекции» (замена/обнуление счётчика).
  • Отчёт «Текущее состояние» (Отчёты): узлы всех машин с состоянием Требуется / Скоро / В норме, остатком по наработке и календарю, сроком и прогнозом даты (по средней наработке в сутки за 30 дней). Фильтры по машине, месту и состоянию; экспорт PDF и CSV.
  • API: /equipment/{id}/service-units, /service-units/{id}[/reset|/events], /equipment/{id}/meter, /reports/equipment-state (см. docs/API.md).

Портал: задания, инциденты, карта, инструмент, сотрудники

  • Боковое меню вместо шапок: на компьютере всегда видно, на телефоне (сайт, /m, Android 1.1.0) — по кнопке ☰.
  • Суточные задания (/tasks): назначен / в работе / приостановлен / выполнен / отменён; для трёх последних комментарий обязателен; фото, привязка к машине или узлу. Другим ставят инженер, модератор, админ; техник — себе.
  • Инциденты (/incidents): авария на машине — описание, затронутые узлы, была ли замена (замена сбрасывает ресурс узла). Открытый инцидент — состояние машины «Авария». Сводка состояний: /equipment-health.
  • Иконки оборудования: встроенный набор app/static/icons (генерируется tools/make_icons.py) или своё фото.
  • Карта завода (/map): картинку и расстановку иконок ведёт админ; «!» — авария, жёлтое свечение — скоро/пора ТО. Карта складов — зоны складов на том же плане (ведёт администратор склада), клик — содержимое склада.
  • Инструмент и склады (/inventory/*, /warehouses): каталог, остатки, выдача лично сотруднику, возврат, перемещение, списание, журнал. Роль «Администратор склада» (is_storekeeper). Сотрудник видит только выданное ему (/me/inventory).
  • Заявки на инструмент (/tool-requests): что купить, зачем, ссылка на товар; статусы и ответ ответственного.
  • Карточка сотрудника (/users/{id}/card): ФИО, фото, должность, ближайшие смены, «что умею», текущие задания и наряды, инструмент.
  • Передача задания (POST /tasks/{id}/transfer): исполнитель, поставивший задание или инженер; причина обязательна, видна в истории.
  • Инциденты извне. Публичная форма /report без входа: место → только машины этого места (и вложенных) → описание и контакты (обязательно); лимит отправок по адресу, ловушка для ботов, выключается в «Настройках сервера». API для внешних систем: POST /external/incidents с заголовком X-API-Key (машина по id или инвентарному номеру, external_id защищает от дублей), справочник GET /external/equipment; ключи выпускает и отзывает админ в «Настройках сервера» (в БД — только хэш).
  • История машины (GET /equipment/{id}/history, вкладка в карточке машины): инциденты, обслуживание и замены узлов, наработка, наряды, задания; фильтры по типу, периоду и тексту.
  • Отделы (/departments): вложенность, руководитель; отдел в карточке пользователя, фильтр в «Сотрудниках».
  • Мастер первичной настройки (Администрирование → 🧭): графики, должности, отделы, места, оборудование, сотрудники (пакетный ввод строками, логины и временные пароли — таблицей для печати), карта, склады и остатки, чек-листы, внешние обращения, копии.
  • Резервные копии (Администрирование → «Резервные копии», /backups): база в переносимом формате + конфигурация (+ фото по желанию), автокопии по расписанию, скачивание, загрузка, восстановление.
  • AI-помощник (включается в «Настройках сервера»: провайдер, адрес, модель, ключ): кнопка в правом нижнем углу на всех экранах; отвечает только о работе в портале, учитывает права пользователя и читает данные только от его имени.
  • Отчёт «Выполнение работ» (/reports/execution): % выполнения суточных осмотров, чек-листов, ТО и заданий по машинам, отклонения; PDF/CSV.

Комментарии, фото, уведомления

  • Комментарии к наряду видят все, кто видит наряд; участникам (исполнитель, проверяющий, назначенный) уходит уведомление.
  • Фото: у пункта чек-листа режим «без фото / по желанию / обязательно». Браузер уменьшает снимок до 1600 px. Файлы лежат в каталоге из настроек (по умолчанию data/photos, в Docker — ./photos на хосте), в БД — только путь. API: POST /api/orders/{id}/items/{item_id}/photos (тело — сам файл, Content-Type: image/jpeg|png|webp), GET /api/photos/{id} (с токеном).
  • Уведомления — Web Push: кнопка «🔔» в шапке. Нужен HTTPS (через Nginx Proxy Manager подойдёт). Приходят при назначении наряда (человеку или тем, кто в этот момент на смене в должности), на проверку, при возврате и при комментариях.

API

Версионированный REST: /api/v1, Swagger на /docs. Короткий access-токен + refresh с ротацией, пакетная офлайн-синхронизация (POST /orders/{id}/sync), курсор updated_since, идемпотентная загрузка фото, FCM для Android. Полное описание для разработчика приложения: docs/API.md. Переменные: ACCESS_TTL_MIN (60), REFRESH_TTL_DAYS (90), LOGIN_MAX_FAILS (5), LOGIN_WINDOW_SEC (300).

Локальный запуск

python -m venv .venv && .venv\Scripts\pip install -r requirements.txt
.venv\Scripts\python -m uvicorn app.main:app --reload

Вход: admin / admin (создаётся при первом старте, смените). Тесты: pytest tests.

Требования к серверу

Оценка по устройству портала (одно приложение на Python + PostgreSQL в Docker), нагрузочных замеров не было.

Минимум (до 20–30 сотрудников) Рекомендуется (до 100–150 сотрудников, с запасом)
Процессор 1 ядро (x86-64 или ARM64) 2 ядра
Память 2 ГБ (с 1 ГБ работает, но первая сборка образа может не пройти без файла подкачки) 4 ГБ
Диск 10 ГБ: система, Docker, образ ~1 ГБ, база, резервные копии 40 ГБ
ОС Linux (Debian 12/13, Ubuntu 22.04/24.04), Docker 24+ с Compose v2 —
  • Фото — главный расход места. Приложение их сжимает, ориентир 0,3–0,5 МБ на снимок: при 50 фото в день — 6–9 ГБ в год, и ещё столько же, если резервные копии делаются с фото.
  • Нужны домен и HTTPS (обратный прокси): без них не работают уведомления, мобильная версия на iPhone и релизное приложение для Android.
  • Интернет серверу нужен только для уведомлений Android (Firebase) и AI-помощника, если он включён; остальное работает в локальной сети.
  • Тяжелее всего для процессора PDF-отчёты и анализ надёжности — секунды на запрос, не постоянная нагрузка.

Пошаговая установка — docs/DEPLOY.md.

Дополнительные сервисы

Рядом с порталом docker-compose.yml может поднять Nextcloud (документация оборудования), ONLYOFFICE (просмотр Word/Excel/PowerPoint в портале) и Ollama (локальная модель для AI-помощника) — профилями docs, office, ai (COMPOSE_PROFILES=docs,office,ai в .env). Портал сам находит их во внутренней сети Docker и заполняет адреса в настройках. Подробно — docs/DEPLOY.md, раздел 7а.

Установка без Coolify (Docker Compose)

Пошаговая инструкция для любого Linux-сервера с Docker: docs/DEPLOY.md (шаблон настроек — .env.example). Коротко: cp .env.example .env → заполнить → docker compose up -d --build → обратный прокси с HTTPS на APP_PORT.

Деплой (Coolify + Nginx Proxy Manager)

Приложение разворачивается из docker-compose.yml (сервис приложения + PostgreSQL, тома pgdata, photos, appdata).

  1. В Coolify: Project → New → Application из Git-репозитория, Build Pack = Docker Compose, файл docker-compose.yml.
  2. Переменные окружения (Coolify → Environment Variables): DB_PASSWORD, SECRET_KEY (случайная строка), ADMIN_PASSWORD (пароль администратора admin, применяется при первом старте), FORWARDED_ALLOW_IPS (IP вашего NPM, например 192.168.1.10), при желании APP_TZ (по умолчанию Europe/Moscow) и APP_PORT (порт хоста, по умолчанию 8080). В боевом режиме (APP_ENV=production, уже прописан в compose) приложение не запустится, если SECRET_KEY короче 32 символов или пуст, а ADMIN_PASSWORD слабее 10 символов (проверяется при первом создании администратора). Пароли пользователей — от 10 символов.
  3. Домен в Coolify не задаётся: прокси — NPM. Proxy Host → Forward http://<IP сервера Coolify>:8080, SSL (Let's Encrypt), Force SSL. В Advanced добавьте client_max_body_size 20m; (иначе фото больше 1 МБ вернут 413). Порт приложения обязательно закройте файрволом для всех, кроме адреса NPM, а в FORWARDED_ALLOW_IPS укажите этот адрес: только от него принимаются заголовки X-Forwarded-For. Проверка: «Администрирование → Настройки сервера» показывает адрес клиента, каким его видит сервер.
  4. Запуск строго в одном процессе (так и настроено): планировщик нарядов и демо-режим живут внутри процесса.
  5. APK: готовый подписанный файл лежит в репозитории (release/) и входит в образ, поэтому ссылка «Скачать приложение для Android» на экране входа и адрес /app.apk работают сразу после деплоя. Новую версию можно выложить без передеплоя: положить файл в том appdata по пути apk/ (он важнее файла из образа): docker cp checklists.apk <контейнер приложения>:/srv/data/apk/.
  6. Резервные копии: pg_dump базы по расписанию + тома photos и appdata.