fix(number-fields): избегаем потери точности длинных чисел

- number-поля теперь рендерятся как text + inputMode=numeric,
  чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage

Closes: искажение расчётного счёта и других длинных числовых полей
This commit is contained in:
2026-07-07 21:03:40 +03:00
commit 1f5ecb6da4
1089 changed files with 237546 additions and 0 deletions

280
DOCKER.md Normal file
View File

@@ -0,0 +1,280 @@
# Запуск через Docker
Приложение поддерживает несколько режимов развёртывания через Docker Compose.
Каждый режим активируется профилями `--profile`.
---
## Режимы базы данных
| Режим | База данных | Команда |
|---|---|---|
| Внешняя (Neon, любой Postgres) | Ваш хост | `docker compose up --build` |
| Встроенная PostgreSQL | Docker-контейнер | `docker compose --profile with-postgres up --build` |
## Режимы хранилища файлов
| Режим | Хранилище | Команда |
|---|---|---|
| Локальный диск (по умолчанию) | Папка `uploads/` | *(без флагов)* |
| MinIO S3 + WebDAV | MinIO-контейнер | `--profile with-minio` |
Профили можно комбинировать. Самый полный вариант («устройство в коробке»):
```bash
docker compose --profile with-postgres --profile with-minio up --build
```
---
## Режим 1: Внешняя база, локальный диск
Файлы хранятся в папке `uploads/` (сбрасываются при пересборке).
```env
DATABASE_URL=postgresql://user:password@host/dbname?sslmode=require
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
```
```bash
docker compose up --build
```
---
## Режим 2: Встроенная PostgreSQL, локальный диск
```env
# PostgreSQL
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=your-strong-db-password
DATABASE_URL=postgresql://appuser:your-strong-db-password@db:5432/appdb
# App
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
```
```bash
docker compose --profile with-postgres up --build
```
---
## Режим 3: MinIO S3 + WebDAV (рекомендуется для устройств)
Файлы хранятся в MinIO — не теряются при перезапуске. WebDAV позволяет
просматривать и добавлять файлы через Windows Explorer, Finder, Cyberduck.
### Переменные окружения
```env
# PostgreSQL (если используете встроенную)
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=your-strong-db-password
DATABASE_URL=postgresql://appuser:your-strong-db-password@db:5432/appdb
# MinIO S3 — приложение видит MinIO как "minio" внутри Docker-сети
MINIO_ENDPOINT=http://minio:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=your-strong-minio-password
MINIO_BUCKET=files
# WebDAV — доступ через браузер/файловый менеджер на порту 8080
WEBDAV_USER=admin
WEBDAV_PASSWORD=your-webdav-password
# App
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
```
### Запуск (всё сразу: PostgreSQL + App + MinIO + WebDAV)
```bash
docker compose --profile with-postgres --profile with-minio up --build
```
### Доступные интерфейсы
| Сервис | Адрес | Описание |
|---|---|---|
| iistwin приложение | `http://device-ip:5000` | Основной интерфейс |
| MinIO Console | `http://device-ip:9001` | Веб-интерфейс MinIO (логин: MINIO_ACCESS_KEY) |
| WebDAV | `http://device-ip:8080` | Файловый менеджер (логин: WEBDAV_USER) |
### Подключение WebDAV
**Windows Explorer:** Нажмите «Подключить сетевой диск» → введите `\\device-ip@8080\DavWWWRoot`
**macOS Finder:** Нажмите ⌘K → введите `http://device-ip:8080`
**Cyberduck / WinSCP:** Протокол WebDAV, хост `device-ip`, порт `8080`
---
## Локальные LLM через Ollama
Профиль `with-ollama` запускает [Ollama](https://ollama.com/) — локальный LLM-сервер — как отдельный контейнер. Модели **не скачиваются автоматически**: вы выбираете и загружаете их через интерфейс iistwin в разделе **Настройки → LLM Провайдеры**.
### Запуск с Ollama
```bash
# Только приложение + Ollama (внешняя БД)
docker compose --profile with-ollama up --build
# Всё сразу: PostgreSQL + App + Ollama
docker compose --profile with-postgres --profile with-ollama up --build
# Максимальная конфигурация: PostgreSQL + MinIO + WebDAV + Ollama
docker compose --profile with-postgres --profile with-minio --profile with-ollama up --build
```
При активном профиле `with-ollama` переменная `OLLAMA_BASE_URL=http://ollama:11434` передаётся в контейнер приложения автоматически через `docker-compose.yml`. Переопределить адрес можно через `.env`.
### Управление моделями через UI
После запуска откройте **Настройки → LLM Провайдеры**, добавьте провайдер типа `Ollama` с URL `http://ollama:11434` (или `http://localhost:11434` для локального запуска вне Docker) и воспользуйтесь разделом **«Модели Ollama»**:
- **Скачать модель** — введите имя (например `qwen2.5:7b`) и нажмите «Скачать». Сервер запустит `ollama pull`, скачивание занимает несколько минут.
- **Удалить модель** — нажмите кнопку удаления рядом с установленной моделью.
- **Список установленных моделей** — отображается с размером на диске.
### Рекомендуемые модели
| Тип | Модели |
|---|---|
| Эмбеддинги (RAG) | `bge-m3`, `mxbai-embed-large`, `qwen3-embedding:8b` |
| Чат / AI-боты | `qwen2.5:3b`, `qwen2.5:7b` |
### NVIDIA GPU
Для использования GPU раскомментируйте секцию `deploy` в сервисе `ollama` в файле `docker-compose.yml` и убедитесь, что на хосте установлен [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html).
### Порты
| Сервис | Порт | Описание |
|---|---|---|
| Ollama API | `11434` | REST API для управления моделями и инференса |
### Volumes
| Volume | Данные |
|---|---|
| `ollama_data` | Скачанные модели Ollama |
Для сброса данных (удаление всех скачанных моделей):
```bash
docker compose --profile with-ollama down -v
```
---
## Генерация VAPID-ключей для веб-пушей
VAPID-ключи используются для web push уведомлений. Без постоянных ключей при каждом перезапуске сервера все push-подписки браузеров становятся невалидными.
**Генерация ключей (выполнить один раз):**
```bash
npx web-push generate-vapid-keys
```
Команда выведет пару ключей:
```
Public Key:
BAxxx...
Private Key:
xxx...
```
Скопируйте значения в переменные окружения `VAPID_PUBLIC_KEY` и `VAPID_PRIVATE_KEY`. Если ключи не заданы, сервер выведет предупреждение в лог и сгенерирует временные ключи (только для текущей сессии).
---
## Sequence при старте
Независимо от режима, контейнер приложения всегда:
1. Проверяет доступность базы данных (`scripts/check-db.js`)
2. Применяет SQL-миграции из папки `migrations/` (`npm run db:migrate`)
3. Создаёт MinIO bucket если настроен S3 (автоматически)
4. Запускает сервер приложения (`npm run start`)
---
## Изменение схемы базы данных
При добавлении новых таблиц или колонок в `shared/schema.ts` необходимо
создать SQL-файл миграции, который будет применён на всех серверах автоматически.
### Шаги
1. **Внесите изменения** в `shared/schema.ts`.
2. **Сгенерируйте миграцию** (создаёт SQL-файл в папке `migrations/`):
```bash
npm run db:generate
```
Команда создаст файл вида `migrations/0004_<name>.sql`.
3. **Закоммитьте оба файла** — изменённый `shared/schema.ts` и новый SQL-файл миграции:
```bash
git add shared/schema.ts migrations/
git commit -m "feat: add <description>"
```
4. **При деплое новой версии** (`docker compose pull && docker compose up -d`)
`db:migrate` автоматически применит новую миграцию, не затрагивая уже существующие данные.
> **Важно:** SQL-файлы миграций нельзя редактировать после коммита — только добавлять новые.
> Применённые миграции отслеживаются в таблице `__drizzle_migrations` в самой БД.
### Проверка миграций после деплоя
Чтобы убедиться, что все миграции применились корректно, выполните в PostgreSQL:
```sql
SELECT * FROM "__drizzle_migrations" ORDER BY created_at;
```
Ожидаемый результат: строки `0000_baseline`, `0001_sync_missing_columns`, …, `0007_sync_missing_columns_v2` (плюс все последующие).
Если строки отсутствуют или возникла ошибка — смотрите логи контейнера: `docker compose logs app`.
---
## Хранение данных (volumes)
| Volume | Данные |
|---|---|
| `postgres_data` | База данных PostgreSQL |
| `minio_data` | Файлы (загруженные через iistwin) |
| `ollama_data` | Скачанные LLM-модели |
Для полного сброса данных:
```bash
docker compose --profile with-postgres --profile with-minio --profile with-ollama down -v
```
---
## Быстрый справочник
| Цель | Команда |
|---|---|
| Только приложение (внешняя БД + диск) | `docker compose up --build` |
| + встроенная PostgreSQL | `docker compose --profile with-postgres up --build` |
| + MinIO + WebDAV (без PostgreSQL) | `docker compose --profile with-minio up --build` |
| + локальные LLM (Ollama) | `docker compose --profile with-ollama up --build` |
| Всё сразу | `docker compose --profile with-postgres --profile with-minio --profile with-ollama up --build` |