Шаг 2.5 плана production-готовности:
- страница уведомлений (фильтр, догрузка, прочтение) + ссылки из dropdown/мобильного меню
- общие хелперы notification-utils (дедупликация dropdown)
- skip-link + id=content на main
- axe smoke-тесты (0 critical/serious), исправлены 2 нарушения в новой странице
- 3 новых теста (107/107), i18n отложен по решению пользователя
Шаги 0.5/0.2 плана production-готовности (досрочно ушли с a54ec77):
- Dockerfile: npm ci --omit=dev вместо копирования node_modules из builder,
пользователь app (USER app), HOME=/tmp, npm_config_cache=/tmp/.npm
- docker/Dockerfile.documents: USER app, HOME=/tmp
- server/vite.ts: vite и vite.config импортируются динамически внутри setupVite —
иначе prod-бандл падал с ERR_MODULE_NOT_FOUND (@vitejs/plugin-react)
- package.json: vitest/supertest/@types/* (16 пакетов) перенесены
в devDependencies — именно vitest в dependencies тянул vite/esbuild/tsx в прод-образ
Проверено локально: образ собирается, uid=1001(app), /app/data доступна на запись,
бандл стартует без devDeps (падает только на отсутствии JWT-секретов окружения)
Шаг A3 (из 1.6) плана production-готовности:
- package.json: скрипт "test": "vitest run"
- pr-check.yml: шаг Tests после type check
- server/utils/userActivity.ts: try/catch в trackUserActivity — синхронная
ошибка трекинга активности больше не срывает authenticateToken (ложный 403
на первом запросе пользователя за минуту)
- tests/auto-transitions.test.ts: 3 устаревших теста обновлены под намеренное
поведение (forward-only position, синк assignee, аудит вместо системного сообщения)
45/45 тестов зелёные, npm run check чисто.
- Добавлена миграция и поле forms.qr_generation_enabled.
- В редакторе формы (вкладка «Основное») добавлен переключатель «Показывать кнопку генерации QR в реестре форм».
- В реестре форм (/forms) рядом со статусом формы появляется кнопка QR, если toggle включён.
- Новый компонент BatchTaskQrDialog: генерирует QR для всех задач формы по всем qr.scan-шаблонам, позволяет скачать отдельный PNG или все сразу ZIP-архивом.
- Добавлена зависимость jszip.
- package.json: db:migrate теперь запускает scripts/migrate-docker.js
- docker-entrypoint.sh: использует npm run db:migrate вместо прямого вызова node scripts/migrate-docker.js
drizzle-kit migrate падает на сервере из-за ручных SQL-миграций без snapshot'ов,
поэтому официально переводим миграции на проверенный migrate-docker.js.
- Add client/src/themes/ with tokens, built-in skins (iistwin, twenty, omegaprom)
- Add ThemeProvider with data-skin/data-theme and runtime CSS for custom skins
- Add npm run skins:generate script for build-time CSS generation
- Add organization_skins table, migration and CRUD API
- Add activeSkinId to organizations and expose it in /api/auth/me
- Add skin switcher in /profile and admin skin editor in /settings/appearance
- Adapt index.css hardcoded colors to skin tokens
- Update AGENTS.md and Obsidian notes
- number-поля теперь рендерятся как text + inputMode=numeric,
чтобы браузер не округлял значения через input type=number
- пробелы при вставке в number-поля удаляются
- бэкенд нормализует значения number-полей в строку перед сохранением
- добавлен хелпер normalizeFieldValueForStorage
Closes: искажение расчётного счёта и других длинных числовых полей