diff --git a/ACCESS_RIGHTS.md b/ACCESS_RIGHTS.md new file mode 100644 index 0000000..dd994ff --- /dev/null +++ b/ACCESS_RIGHTS.md @@ -0,0 +1,217 @@ +# 🔐 ПРАВА ДОСТУПА - МАТРИЦЫ РАЗРЕШЕНИЙ + +**Версия**: v4.1.17 +**Дата**: 2026-01-14 +**Обновление**: Уточнены права доступа User и Guest + +--- + +## 🔐 МАТРИЦА ПРАВ ДОСТУПА - РЕДАКТИРОВАНИЕ + +| Поле | Admin | User | Guest | +|------|-------|------|-------| +| **MAT-1** календарь | ✅ | ❌ | ❌ | +| **MAT-1** подтверждение | ✅ | ✅ | ❌ | +| **MAT-2** календарь | ✅ | ❌ | ❌ | +| **MAT-2** подтверждение | ✅ | ✅ | ❌ | +| **PAKETT** календарь | ✅ | ❌ | ❌ | +| **Töölehti** toggle | ✅ | ✅ | ❌ | +| **LÕIKUS** toggle | ✅ | ✅ | ❌ | +| **KLAAS** toggle | ✅ | ✅ | ❌ | +| **VALMIS** toggle | ✅* | ✅* | ❌ | +| **VÄLJAS** toggle | ✅* | ✅* | ❌ | + +*Блокируется при наличии проблем/ошибок + +--- + +## 👁️ МАТРИЦА ПРАВ ДОСТУПА - ПРОСМОТР + +| Поле | Admin | User | Guest | +|------|-------|------|-------| +| **MAT-1** дата | ✅ | ✅ | ✅ | +| **MAT-1** кнопка ✓ | ✅ | ✅ | ❌ | +| **MAT-2** дата | ✅ | ✅ | ✅ | +| **MAT-2** кнопка ✓ | ✅ | ✅ | ❌ | +| **PAKETT** дата | ✅ | ✅ | ✅ | +| **Töölehti** дата+статус | ✅ | ✅ | ✅ | +| **LÕIKUS** дата | ✅ | ✅ | ✅ | +| **KLAAS** дата | ✅ | ✅ | ✅ | +| **VALMIS** дата | ✅ | ✅ | ✅ | +| **VÄLJAS** дата | ✅ | ✅ | ✅ | + +--- + +## 👤 РОЛИ ПОЛЬЗОВАТЕЛЕЙ + +### **Admin** (admin, aknaproff) + +#### Редактирование: +- ✅ **MAT-1**: выбор даты через календарь +- ✅ **MAT-1**: подтверждение (кнопка ✓) +- ✅ **MAT-2**: выбор даты через календарь +- ✅ **MAT-2**: подтверждение (кнопка ✓) +- ✅ **PAKETT**: выбор даты через календарь +- ✅ **Töölehti**: полный контроль 3-шагового цикла +- ✅ **LÕIKUS**: toggle даты +- ✅ **KLAAS**: toggle даты +- ✅ **VALMIS**: toggle даты (если нет блокировки) +- ✅ **VÄLJAS**: toggle даты (если нет блокировки) +- ✅ Добавление записей +- ✅ Редактирование записей +- ✅ Удаление записей +- ✅ Изменение проблем и ошибок + +#### Просмотр: +- ✅ Все поля видны полностью + +--- + +### **User** (kasutaja) + +#### Редактирование: +- ❌ **MAT-1**: НЕТ доступа к календарю +- ✅ **MAT-1**: ЕСТЬ доступ к подтверждению (кнопка ✓) +- ❌ **MAT-2**: НЕТ доступа к календарю +- ✅ **MAT-2**: ЕСТЬ доступ к подтверждению (кнопка ✓) +- ❌ **PAKETT**: нет доступа к календарю +- ✅ **Töölehti**: полный контроль 3-шагового цикла +- ✅ **LÕIKUS**: toggle даты +- ✅ **KLAAS**: toggle даты +- ✅ **VALMIS**: toggle даты (если нет блокировки) +- ✅ **VÄLJAS**: toggle даты (если нет блокировки) +- ❌ Добавление/редактирование/удаление записей + +#### Просмотр: +- ✅ **MAT-1, MAT-2**: видит дату + кнопку подтверждения +- ✅ **PAKETT**: видит дату +- ✅ **Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS**: видит дату + +--- + +### **Guest** (неавторизованный пользователь) + +#### Редактирование: +- ❌ **Все поля**: нет доступа к редактированию + +#### Просмотр: +- ✅ **MAT-1, MAT-2**: видит только дату (БЕЗ кнопки подтверждения) +- ✅ **PAKETT**: видит дату +- ✅ **Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS**: видит дату + +--- + +## 📊 ДЕТАЛЬНОЕ ОПИСАНИЕ + +### **MAT-1 (Material)** +- **Admin**: открывает календарь + подтверждает +- **User**: только подтверждает (кнопка ✓) +- **Guest**: только просмотр даты + +### **MAT-2 (Material2)** +- **Admin**: открывает календарь + подтверждает +- **User**: только подтверждает (кнопка ✓) +- **Guest**: только просмотр даты +- **Блокировка**: если MAT-1 пустая + +### **PAKETT (Package)** +- **Admin**: открывает календарь +- **User**: только просмотр +- **Guest**: только просмотр + +### **Töölehti (Worksheets)** +- **Admin**: полный контроль 3-цикла +- **User**: полный контроль 3-цикла +- **Guest**: только просмотр + +### **LÕIKUS (Cutting)** +- **Admin**: toggle (добавить/удалить дату) +- **User**: toggle (добавить/удалить дату) +- **Guest**: только просмотр + +### **KLAAS (Glazing)** +- **Admin**: toggle (добавить/удалить дату) +- **User**: toggle (добавить/удалить дату) +- **Guest**: только просмотр + +### **VALMIS (Ready)** +- **Admin**: toggle (если нет проблем/ошибок) +- **User**: toggle (если нет проблем/ошибок) +- **Guest**: только просмотр +- **Блокировка**: при наличии проблем или ошибок + +### **VÄLJAS (Issued)** +- **Admin**: toggle (если нет проблем/ошибок) +- **User**: toggle (если нет проблем/ошибок) +- **Guest**: только просмотр +- **Блокировка**: при наличии проблем или ошибок + +--- + +## 🔑 ТЕХНИЧЕСКИЕ ДЕТАЛИ + +### **Backend проверка прав:** +```typescript +// optionalAuthMiddleware - разрешает Guest просмотр +// authMiddleware - требует авторизацию + +// Календари (MAT-1, MAT-2, PAKETT) +if (userRole !== 'admin') { + return c.json({ error: 'Only admin can change dates' }, 403) +} + +// Подтверждение (MAT-1, MAT-2) +// Разрешено всем авторизованным (Admin + User) + +// Toggle (Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS) +// Разрешено всем авторизованным (Admin + User) +``` + +### **Frontend проверка прав:** +```javascript +// canEditRecords() - проверяет наличие токена и роль +// Для Admin + User = true +// Для Guest = false + +// MAT-1/MAT-2 календарь +if (currentUser.role !== 'admin') { + // Скрыть календарь +} + +// MAT-1/MAT-2 подтверждение +if (!token) { + // Скрыть кнопку ✓ +} + +// Toggle поля +if (!canEditRecords()) { + // Отключить клик +} +``` + +--- + +## ✅ СВОДКА + +### **Что может Admin:** +- 📅 Выбирать даты через календарь (MAT-1, MAT-2, PAKETT) +- ✓ Подтверждать материалы +- 🔄 Управлять всеми toggle-полями +- ➕ Добавлять/редактировать/удалять записи + +### **Что может User:** +- ❌ НЕ может выбирать даты через календарь +- ✓ МОЖЕТ подтверждать материалы (MAT-1, MAT-2) +- 🔄 МОЖЕТ управлять toggle-полями (Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS) +- ❌ НЕ может добавлять/редактировать/удалять записи + +### **Что может Guest:** +- 👁️ Только просмотр всех дат +- ❌ НЕ видит кнопки подтверждения +- ❌ НЕ может редактировать ничего + +--- + +**Статус**: ✅ Права доступа корректны +**Версия**: v4.1.17 +**Дата**: 2026-01-14 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2e6eb63 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,232 @@ +# AKNAPROFF Tootmine - CHANGELOG + +## v4.1.10 - 2025-12-31 (HOTFIX - КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ) + +### 🔥 Критические исправления + +#### 1. Исправлена потеря данных при рестарте Docker +- **Проблема:** Миграции пересоздавали БД при каждом запуске +- **Симптомы:** + - Существующая БД с 38 записями терялась + - При обновлении страницы старые данные появлялись на секунду +- **Решение:** + - Добавлен флаг `SKIP_MIGRATIONS=true` в `docker-entrypoint.sh` + - Добавлена переменная `SKIP_MIGRATIONS: "true"` в `docker-compose.yml` + - Миграции теперь пропускаются по умолчанию + - Используется готовая БД из `data/` директории +- **Файлы:** `docker-entrypoint.sh`, `docker-compose.yml` + +#### 2. Исправлена ошибка 500 при добавлении записи +- **Проблема:** `POST /api/records` возвращал 500 Internal Server Error +- **Симптомы:** + ``` + POST http://komo.aknaproff.ee:8180/api/records + [HTTP/1.1 500 Internal Server Error] + Save record error: "Failed to create record" + ``` +- **Причина:** Таблица `production_records` требует поля `created_by` и `updated_by`, но они не передавались +- **Решение:** + - Добавлены поля `created_by` и `updated_by` в INSERT запрос + - Добавлено поле `updated_by` в UPDATE запрос + - Значения берутся из `userId` (из JWT токена) +- **Файлы:** `src/index.tsx`, `dist/_worker.js` + +#### 3. Исправлена неработающая кнопка "Lisa uus rida" +- **Проблема:** Admin не мог добавить новую запись +- **Причина:** Ошибка 500 в backend (см. пункт 2) +- **Решение:** Исправлен backend код +- **Статус:** ✅ Теперь работает + +### 📝 Изменённые файлы + +#### Backend +- **src/index.tsx** + - `POST /api/records`: добавлены поля `created_by, updated_by` в INSERT + - `PUT /api/records/:id`: добавлено поле `updated_by` в UPDATE + +- **dist/_worker.js** + - Пересобран с исправлениями + +#### Docker +- **docker-entrypoint.sh** + - Добавлен флаг `SKIP_MIGRATIONS` (по умолчанию `true`) + - Добавлена логика проверки `SKIP_MIGRATIONS` + - При `SKIP_MIGRATIONS=true` миграции пропускаются + +- **docker-compose.yml** + - Добавлена переменная `SKIP_MIGRATIONS: "true"` + +#### Frontend +- **public/original.html** + - Cache version обновлена: `app.js?v=4.1.10` + +### ⚠️ Breaking Changes +Нет breaking changes. Полная обратная совместимость с v4.1.9. + +### 🔄 Миграция с v4.1.9 +1. Остановить контейнер: `docker-compose down` +2. **КРИТИЧНО:** Сделать бэкап: `cp -r data data.backup.$(date +%Y%m%d_%H%M%S)` +3. Заменить файлы (НЕ трогать `data/`) +4. Проверить `SKIP_MIGRATIONS: "true"` в `docker-compose.yml` +5. Запустить: `docker-compose up -d --build` +6. Проверить данные: 38 записей должны остаться + +### ✅ Тесты +- [x] Данные сохраняются между рестартами +- [x] Миграции пропускаются (логи: "Skipping migrations") +- [x] POST /api/records работает (200 OK) +- [x] Кнопка "Lisa uus rida" работает +- [x] created_by/updated_by записываются в БД +- [x] Admin может добавлять записи +- [x] User НЕ может добавлять записи +- [x] User НЕ может редактировать заметки +- [x] User может редактировать проблемы + +### 📦 Архивы +- `aknaproff_production_v4.1.10_arm.tar.gz` (278 KB) +- `aknaproff_production_v4.1.10_arm.zip` (318 KB) + +--- + +## v4.1.9 - 2025-12-30 + +### 🔒 Исправлены права доступа + +#### 1. User теперь может только просматривать заметки (read-only) +- **Проблема:** User мог редактировать заметки +- **Решение:** + - Frontend: `openNotesModal()` использует `canEditRecords()` (только admin) + - Frontend: кнопка "Salvesta" скрыта для user + - Backend: `PATCH /api/records/:id/notes` → Admin only (403 для user) +- **Статус:** ✅ Исправлено + +#### 2. User может редактировать проблемы +- **Backend:** `PATCH /api/records/:id/problems` → Admin + User +- **Frontend:** UI показывает возможность редактирования +- **Статус:** ✅ Работает + +#### 3. Кнопка "Lisa uus rida" скрыта для User и Guest +- **Frontend:** Кнопка скрыта через `role-admin` CSS класс +- **Backend:** Проверка роли перед созданием записи +- **Статус:** ✅ Работает + +### 📊 Матрица прав доступа + +| Функция | Admin | User | Guest | +|----------------------|-------|------|-------| +| Просмотр записей | ✅ | ✅ | ✅ | +| Добавить запись | ✅ | ❌ | ❌ | +| Редактировать запись | ✅ | ❌ | ❌ | +| Удалить запись | ✅ | ❌ | ❌ | +| Просмотр заметок | ✅ | ✅ | ✅ | +| Редактировать заметки| ✅ | ❌ | ❌ | +| Просмотр проблем | ✅ | ✅ | ✅ | +| Редактировать проблемы| ✅ | ✅ | ❌ | + +### 📝 Изменённые файлы +- `public/static/app.js`: изменены `openNotesModal()`, `saveNotes()` +- `src/index.tsx`: добавлены проверки роли в API +- `public/original.html`: cache v4.1.9 + +--- + +## v4.1.8 - 2025-12-30 + +### 🐛 Исправления + +#### 1. Исправлены права пользователей +- **Проблема:** User не мог редактировать Problems +- **Решение:** Изменён `openProblemsModal()` на использование `canEditProblems()` + +#### 2. Скрыта кнопка "Lisa uus rida" для non-admin +- **Frontend:** Кнопка скрыта для User и Guest ролей +- **CSS:** Использован класс `.role-admin` + +#### 3. Добавлены колонки problems +- **База данных:** + - `problems` TEXT DEFAULT NULL + - `problems_date` DATE DEFAULT NULL +- **Миграции:** Применены в локальной БД + +#### 4. Исправлены названия полей audit_log +- **Было:** `field_name`, `action_type` +- **Стало:** `field`, `action` +- **Файлы:** `src/index.tsx` + +### 📦 Изменения БД +```sql +ALTER TABLE production_records ADD COLUMN problems TEXT DEFAULT NULL; +ALTER TABLE production_records ADD COLUMN problems_date DATE DEFAULT NULL; +``` + +--- + +## v4.1.7 - 2025-12-30 + +### 🔐 Исправлена аутентификация + +#### 1. Исправлена система входа (bcrypt → SHA-256) +- **Проблема:** Login failed - несовместимость хэшей +- **Было:** Бэкап использовал bcrypt ($2a$) +- **Стало:** Все пароли SHA-256 +- **Решение:** Обновлены все password_hash в БД + +#### 2. Удалён дубликат пользователя +- **Удалён:** user `tootmine` (дубликат kasutaja) +- **Причина:** Один человек, два аккаунта +- **Статус:** ✅ Удалён + +#### 3. Добавлена колонка deleted_at +- **Таблица:** `users` +- **Тип:** `DATETIME DEFAULT NULL` +- **Причина:** Код использовал `WHERE deleted_at IS NULL`, но колонки не было +- **Статус:** ✅ Добавлена + +### 📊 База данных +- **Записей:** 38 production records +- **Пользователей:** 3 active + - `admin` / `demo123` (admin) + - `aknaproff` / `demo123` (admin) + - `kasutaja` / `tootmine` (user) + +### 🔒 Учётные данные +Все пароли теперь SHA-256: +``` +admin: d3ad9315b7be5dd53b31a273b3b3aba5defe700808305aa16a3062b76658a791 +aknaproff: d3ad9315b7be5dd53b31a273b3b3aba5defe700808305aa16a3062b76658a791 +kasutaja: a1026b7bd143f7190248bc79901e9a357a408e208f2d8e4d38fccf184754f35f +``` + +--- + +## v4.1.6 и ранее + +См. файлы: +- `CHANGES_v4.1.6.md` +- `CHANGES_v4.1.5.md` +- `CHANGES_v4.1.4.md` +- `CHANGES_v4.1.3.md` +- `CHANGES_v4.1.2.md` +- `CHANGES_v4.1.0.md` + +--- + +## Легенда + +- 🔥 Критическое исправление +- 🐛 Исправление бага +- ✨ Новая функция +- 🔒 Безопасность +- 📝 Документация +- 🔧 Конфигурация +- 📊 База данных +- 🎨 UI/UX +- ⚡ Производительность +- 🔄 Рефакторинг + +--- + +**Текущая версия:** v4.1.10 +**Дата:** 2025-12-31 +**Статус:** Production Ready ✅ +**Архитектура:** ARM64/AMD64 (Synology Compatible) diff --git a/CHANGES_v4.1.0.md b/CHANGES_v4.1.0.md new file mode 100644 index 0000000..87604c8 --- /dev/null +++ b/CHANGES_v4.1.0.md @@ -0,0 +1,199 @@ +# AKNAPROFF Tootmine - Изменения v4.1.0 + +**Дата:** 28.11.2025 +**Версия:** v4.1.0 + +--- + +## 🎯 Реализованные изменения + +### 1. ✅ Логика блокировки изменена +**Было:** Проблемы блокировали поля при наличии текста ИЛИ галочек ошибок +**Стало:** Блокировка только по галочкам ошибок, текст - только пояснение + +**Технические детали:** +- Убрана проверка `(record.problems && record.problems.trim())` из условия hasProblems +- Блокировка происходит только при установленных флагах ошибок + +### 2. ✅ Система авторизации и ролей +**Реализовано 3 уровня доступа:** + +| Роль | Доступ | Описание | +|------|--------|----------| +| **guest** | Только просмотр | Гость без входа - ничего не может изменять | +| **user** | Просмотр + Проблемы | Простой пользователь - может изменять только Problems | +| **admin** | Полный доступ | Администратор - может изменять всё | + +**Функциональность:** +- При открытии без логина показывается форма входа +- Guest (гость) - только read-only просмотр +- User - может редактировать проблемы (текст + галочки ошибок) +- Admin - полный доступ ко всем функциям + +**Защищённые функции:** +- toggleDate() - только admin +- toggleMaterialConfirmed() - только admin +- toggleMaterial2Confirmed() - только admin +- toggleWorksheetsStep() - только admin +- togglePricePaid() - только admin +- saveNotes() - только admin +- saveProblems() - user и admin + +### 3. ✅ Кнопка сортировки по ID +**Добавлена кнопка "ID" перед фильтрами:** +- Клик 1: Сортировка по возрастанию (↑) +- Клик 2: Сортировка по убыванию (↓) +- Клик 3: Отключение сортировки +- Иконка показывает текущее состояние + +--- + +## 📂 Измененные файлы + +### Для копирования на сервер: + +```bash +# Frontend файлы (обязательно) +public/static/app.js +public/original.html + +# Backend файлы (обязательно) +src/index.tsx # Если были изменения в API +src/original-html.ts # Embedded HTML + +# Build файлы (создаются автоматически) +dist/_worker.js # Скомпилированный backend +``` + +--- + +## 🚀 Инструкция по обновлению на сервере + +### Вариант 1: Полное обновление (РЕКОМЕНДУЕТСЯ) + +```bash +# 1. Остановить контейнер +docker-compose down + +# 2. Скопировать файлы из локальной машины на сервер +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ + +# 3. Пересобрать на сервере +cd /path/to/webapp +npm run build + +# 4. Запустить контейнер +docker-compose up -d --build +``` + +### Вариант 2: Только frontend (БЕЗ ПЕРЕСБОРКИ) + +Если НЕ ИЗМЕНЯЛСЯ backend (src/index.tsx), можно обновить только frontend: + +```bash +# 1. Скопировать файлы +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ + +# 2. Пересобрать +docker-compose exec aknaproff-backend npm run build + +# 3. Перезапустить (НЕ пересобирать образ) +docker-compose restart +``` + +### Вариант 3: Копирование готового dist/ + +```bash +# 1. Собрать локально (уже сделано) +npm run build + +# 2. Скопировать dist на сервер +scp dist/_worker.js user@server:/path/to/webapp/dist/ + +# 3. Перезапустить +docker-compose restart +``` + +--- + +## ⚠️ ВАЖНО: База данных + +**БД НЕ ИЗМЕНЯЛАСЬ!** Миграции не требуются. + +Все изменения только в логике приложения: +- Логика hasProblems (frontend) +- Система прав (frontend) +- Кнопка сортировки (frontend) + +**Данные в БД сохранятся полностью.** + +--- + +## ✅ Проверка после обновления + +### 1. Проверить вход +```bash +# Открыть в браузере +http://your-server:8180 + +# Должна показаться форма входа +``` + +### 2. Тестировать роли + +**Guest (без входа):** +- ❌ Не может ничего изменять +- ✅ Может только просматривать + +**User (простой пользователь):** +- ✅ Может изменять Problems (текст + галочки) +- ❌ Не может изменять даты, notes, статусы + +**Admin:** +- ✅ Может изменять всё + +### 3. Проверить сортировку +- Нажать кнопку "ID" перед фильтрами +- Проверить сортировку: ↑ → ↓ → отключено + +### 4. Проверить логику блокировки +- Поставить галочку ошибки без текста +- Поле VALMIS/VÄLJAS должно заблокироваться (красное) +- Убрать галочку, добавить только текст +- Поле VALMIS/VÄLJAS НЕ должно блокироваться + +--- + +## 📊 Сводка изменений + +| Компонент | Изменено | Тип | +|-----------|----------|-----| +| Логика hasProblems | ✅ | Frontend | +| Система авторизации | ✅ | Frontend | +| Проверки прав | ✅ | Frontend | +| Кнопка сортировки | ✅ | Frontend | +| База данных | ❌ | Не изменялась | +| Backend API | ❌ | Не изменялся | + +--- + +## 🔧 Откат изменений (если что-то пошло не так) + +```bash +# 1. Вернуться к предыдущей версии +git checkout v4.0.13 + +# 2. Пересобрать +npm run build + +# 3. Перезапустить +docker-compose up -d --build +``` + +--- + +**Готово к deployment!** 🚀 diff --git a/CHANGES_v4.1.2.md b/CHANGES_v4.1.2.md new file mode 100644 index 0000000..667143c --- /dev/null +++ b/CHANGES_v4.1.2.md @@ -0,0 +1,116 @@ +# 🔄 CHANGES v4.1.2 - UI Layout Update + +**Дата**: 2025-11-28 +**Версия**: v4.1.2 +**Тип**: UI Layout Improvement + +--- + +## 📝 Что изменено + +**Перемещение кнопки сортировки**: +- Кнопка **"Sorteerimine"** (сортировка по ID) перенесена из секции **"Filters"** в секцию **"Kiir otsing"** (Быстрый поиск) +- Теперь кнопка находится **ПЕРЕД** полем **"Klient"** + +--- + +## 🎨 Визуальная структура + +### ДО (v4.1.1): +``` +┌─ Filters ─────────────────────────┐ +│ [Sorteerimine: ID ↕] │ +│ [Kuu] [Aasta] [Lisa uus rida] │ +└───────────────────────────────────┘ + +┌─ Kiir otsing ─────────────────────┐ +│ [Klient] [Tüüp] [Pakkum. Nr] │ +│ [Töö Nr] [Aasta filter] │ +└───────────────────────────────────┘ +``` + +### ПОСЛЕ (v4.1.2): +``` +┌─ Filters ─────────────────────────┐ +│ [Kuu] [Aasta] [Lisa uus rida] │ +└───────────────────────────────────┘ + +┌─ Kiir otsing ─────────────────────┐ +│ [Sorteerimine: ID ↕] [Klient] │ +│ [Tüüp] [Pakkum. Nr] [Töö Nr] │ +│ [Aasta filter] │ +└───────────────────────────────────┘ +``` + +--- + +## 💡 Логика изменения + +**Почему так лучше**: +1. **Логическая группировка**: Сортировка и поиск - это функции фильтрации данных, поэтому логично их держать вместе +2. **Меньше секций**: Секция Filters теперь содержит только основные фильтры (месяц/год) и кнопку добавления +3. **Удобнее использовать**: Сортировка и поиск теперь в одном месте + +--- + +## 📦 Изменённые файлы + +1. **public/original.html** + - Удалена кнопка Sorteerimine из Filters (строки 123-131) + - Добавлена кнопка Sorteerimine в Kiir otsing перед Klient + - Обновлена версия: `app.js?v=4.1.1` → `app.js?v=4.1.2` + +2. **src/original-html.ts** + - Регенерирован embedded HTML с новой структурой + +3. **dist/_worker.js** + - Пересобран с обновлённым HTML + +--- + +## ✅ Тестирование + +**Проверено**: +- ✅ Кнопка Sorteerimine отображается в секции Kiir otsing +- ✅ Кнопка находится ПЕРЕД полем Klient +- ✅ Функционал сортировки работает (↑ ↓ ↕) +- ✅ Все поля поиска работают +- ✅ Layout адаптивный (flex-wrap) +- ✅ Консоль браузера чистая + +--- + +## 🔗 URLs + +- **Production**: https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **Git Commit**: b541aff + +--- + +## 📊 Статус + +**Версия**: v4.1.2 +**Статус**: ✅ Production Ready +**HTTP Status**: 200 OK +**JavaScript Errors**: 0 + +--- + +## 📝 Для deployment на production + +```bash +# Вариант 1: Быстрый (рекомендуется) +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart + +# Вариант 2: Полный +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +cd /path/to/webapp && npm run build && docker-compose restart +``` + +**После deployment**: Нажмите **Ctrl+Shift+R** в браузере для сброса кэша. + +--- + +**🎯 Готово!** Кнопка Sorteerimine перенесена в секцию Kiir otsing перед полем Klient. diff --git a/CHANGES_v4.1.3.md b/CHANGES_v4.1.3.md new file mode 100644 index 0000000..a5ab18c --- /dev/null +++ b/CHANGES_v4.1.3.md @@ -0,0 +1,228 @@ +# 🔧 CHANGES v4.1.3 - UI Polish & New User + +**Дата**: 2025-11-28 +**Версия**: v4.1.3 +**Тип**: UI Improvement + User Management + +--- + +## 📝 Что изменено + +### 1. Убрано слово "Sorteerimine" +- **ДО**: Кнопка имела label "Sorteerimine" над ней +- **ПОСЛЕ**: Только кнопка "ID" с иконкой сортировки (↕) +- **Причина**: Более компактный и чистый UI + +### 2. Добавлен новый пользователь "kasutaja" +- **Username**: kasutaja +- **Password**: tootmine +- **Full Name**: Kasutaja +- **Role**: user (обычный пользователь) + +### 3. Уточнена система ролей + +**Три пользователя с двумя уровнями доступа**: + +| Username | Password | Full Name | Role | Уровень доступа | +|----------|----------|-----------|------|-----------------| +| kasutaja | tootmine | Kasutaja | user | Обычный пользователь | +| aknaproff | demo123 | AKNAPROFF | admin | Администратор | +| admin | demo123 | Administrator | admin | Администратор | + +**Права доступа**: + +#### User (kasutaja) +- ✅ Просмотр всех записей +- ✅ Изменение проблем (текст + галочки) +- ✅ Просмотр Notes (read-only) +- ❌ Изменение дат +- ❌ Изменение MAT-1/MAT-2 +- ❌ Добавление/редактирование/удаление записей + +#### Admin (aknaproff, admin) +- ✅ Все права User +- ✅ Изменение дат (toggle) +- ✅ Изменение MAT-1/MAT-2 (toggle) +- ✅ Изменение LÕIKUS/KLAAS/VALMIS/VÄLJAS (3-step cycle) +- ✅ Добавление записей +- ✅ Редактирование записей +- ✅ Удаление записей + +**Примечание**: aknaproff и admin имеют одинаковый уровень доступа (оба admin). + +--- + +## 🎨 Визуальные изменения + +### ДО (v4.1.2): +``` +┌─ Kiir otsing ─────────────────────────────┐ +│ Sorteerimine │ +│ [ID ↕] │ +│ │ +│ Klient │ +│ [Otsi kliendi järgi...] │ +└───────────────────────────────────────────┘ +``` + +### ПОСЛЕ (v4.1.3): +``` +┌─ Kiir otsing ─────────────────────────────┐ +│ [ID ↕] [Klient: Otsi kliendi järgi...] │ +└───────────────────────────────────────────┘ +``` + +**Преимущества**: +- Более компактный UI +- Меньше визуального шума +- Интуитивно понятно, что кнопка ID для сортировки + +--- + +## 📦 Изменённые файлы + +### 1. public/original.html +- Убран label с текстом "Sorteerimine" +- Кнопка ID теперь без label (только иконка + текст) +- Обновлена версия: `app.js?v=4.1.2` → `app.js?v=4.1.3` + +### 2. seed.sql +- Добавлен пользователь "kasutaja" с паролем "tootmine" +- Обновлены комментарии с пояснением ролей +- Добавлен SHA-256 hash для пароля "tootmine" + +### 3. src/original-html.ts +- Регенерирован embedded HTML + +### 4. dist/_worker.js +- Пересобран с обновлениями + +--- + +## 🧪 Тестирование + +### Проверка UI +✅ Кнопка ID отображается без label "Sorteerimine" +✅ Кнопка компактная и выровнена с другими полями +✅ Функционал сортировки работает (↑ ↓ ↕) + +### Проверка нового пользователя +✅ Вход: kasutaja / tootmine +✅ Роль: user +✅ Доступ только к просмотру и изменению проблем +✅ Остальные функции заблокированы (alert) + +### Проверка существующих пользователей +✅ aknaproff / demo123 - admin права +✅ admin / demo123 - admin права +✅ Оба имеют полный доступ + +--- + +## 🔐 Учётные данные + +### Production Users + +**Обычный пользователь**: +- Username: `kasutaja` +- Password: `tootmine` +- Доступ: просмотр + изменение проблем + +**Администраторы** (одинаковые права): +- Username: `aknaproff` | Password: `demo123` +- Username: `admin` | Password: `demo123` +- Доступ: полный + +**Гость** (без входа): +- Кнопка: "Vaata ainult" +- Доступ: только просмотр (read-only) + +--- + +## 🔗 URLs + +- **Production**: https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **Git Commit**: Будет добавлен после коммита + +--- + +## 📊 Статус + +**Версия**: v4.1.3 +**Статус**: ✅ Production Ready +**HTTP Status**: 200 OK +**JavaScript Errors**: 0 +**Database**: Обновлена (добавлен пользователь kasutaja) + +--- + +## 🚀 Deployment Instructions + +### ⚠️ ВАЖНО: Требуется обновление базы данных! + +**На production сервере**: + +```bash +# 1. Скопировать seed.sql с новым пользователем +scp seed.sql user@server:/path/to/webapp/ + +# 2. На сервере применить seed.sql +docker-compose exec aknaproff-backend sh -c " + cd /app && + npx wrangler d1 execute webapp-production --local --file=./seed.sql +" + +# 3. Проверить, что пользователь добавлен +docker-compose exec aknaproff-backend sh -c " + npx wrangler d1 execute webapp-production --local \ + --command='SELECT username, full_name, role FROM users' +" + +# Должно вывести: +# - kasutaja | Kasutaja | user +# - aknaproff | AKNAPROFF | admin +# - admin | Administrator | admin + +# 4. Скопировать обновлённые файлы +scp dist/_worker.js user@server:/path/to/webapp/dist/ +# или +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +# и потом: npm run build + +# 5. Перезапустить +docker-compose restart +``` + +### Проверка после deployment + +```bash +# 1. Проверить HTTP +curl -I http://localhost:8180 + +# 2. Войти в браузере под kasutaja/tootmine +# 3. Проверить, что доступно только изменение проблем +# 4. Войти под aknaproff/demo123 или admin/demo123 +# 5. Проверить полный доступ +``` + +--- + +## 💾 Password Hashes + +Для справки (SHA-256): +- **demo123**: `d3ad9315b7be5dd53b31a273b3b3aba5defe700808305aa16a3062b76658a791` +- **tootmine**: `a1026b7bd143f7190248bc79901e9a357a408e208f2d8e4d38fccf184754f35f` + +--- + +## 📝 Заметки + +1. **База данных изменена**: Добавлен новый пользователь, требуется применение seed.sql на production +2. **Роли**: aknaproff и admin - оба admin, kasutaja - user +3. **UI**: Более компактный, убран label "Sorteerimine" +4. **Cache-busting**: v4.1.3, нужен Ctrl+Shift+R после deployment + +--- + +**🎯 Готово!** UI упрощён, добавлен пользователь kasutaja (tootmine), система ролей уточнена. diff --git a/CHANGES_v4.1.4.md b/CHANGES_v4.1.4.md new file mode 100644 index 0000000..f0bbad6 --- /dev/null +++ b/CHANGES_v4.1.4.md @@ -0,0 +1,152 @@ +# 📝 CHANGES v4.1.4 - Login Form Simplification + +**Дата**: 2025-11-28 +**Версия**: v4.1.4 +**Тип**: UI Text Improvement + +--- + +## 📝 Что изменено + +### Упрощение текста формы логина + +**ДО (v4.1.3)**: +``` +┌─────────────────────────────────┐ +│ 🔒 │ +│ Administrator Login │ +│ Sisesta admin kasutajaandmed │ +│ │ +│ [Kasutajanimi] │ +│ [Parool] │ +│ [Logi sisse] │ +└─────────────────────────────────┘ +``` + +**ПОСЛЕ (v4.1.4)**: +``` +┌─────────────────────────────────┐ +│ 🔒 │ +│ Login │ +│ Sisesta kasutajaandmed │ +│ │ +│ [Kasutajanimi] │ +│ [Parool] │ +│ [Logi sisse] │ +└─────────────────────────────────┘ +``` + +### Изменения: +1. **Заголовок**: "Administrator Login" → **"Login"** +2. **Подзаголовок**: "Sisesta admin kasutajaandmed" → **"Sisesta kasutajaandmed"** + +### Причина: +- Форма теперь используется **всеми типами пользователей** (kasutaja, aknaproff, admin) +- Не только администраторами, поэтому слово "Administrator" и "admin" вводят в заблуждение +- Более универсальный и понятный текст + +--- + +## 📦 Изменённые файлы + +### 1. public/original.html +- Строка 47: `Administrator Login` → `Login` +- Строка 48: `Sisesta admin kasutajaandmed` → `Sisesta kasutajaandmed` +- Обновлена версия: `app.js?v=4.1.3` → `app.js?v=4.1.4` + +### 2. src/original-html.ts +- Регенерирован embedded HTML с новыми текстами + +### 3. dist/_worker.js +- Пересобран с обновлениями + +--- + +## ✅ Тестирование + +**Проверено**: +- ✅ Заголовок формы: "Login" (не "Administrator Login") +- ✅ Подзаголовок: "Sisesta kasutajaandmed" (не "admin kasutajaandmed") +- ✅ Все функции входа работают +- ✅ Вход для kasutaja/tootmine работает +- ✅ Вход для aknaproff/demo123 работает +- ✅ Вход для admin/demo123 работает +- ✅ Кнопка "Vaata ainult" (guest) работает + +--- + +## 🚀 Deployment + +### Быстрое обновление (только UI) + +```bash +# Скопировать только dist +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart + +# ИЛИ скопировать исходники +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +# На сервере: npm run build && docker-compose restart +``` + +### Проверка + +```bash +# HTTP +curl -I http://localhost:8180 + +# Браузер (Ctrl+Shift+R) +# Проверить текст: "Login" и "Sisesta kasutajaandmed" +``` + +--- + +## ⚠️ Важно + +- **База данных**: НЕ изменена +- **Миграции**: НЕ требуются +- **Изменения**: только UI текст +- **Cache-busting**: v4.1.4 + +--- + +## 🔗 URLs + +- **Production**: https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **Git Commit**: f9c5e0a + +--- + +## 📊 Статус + +**Версия**: v4.1.4 +**Статус**: ✅ Production Ready +**HTTP Status**: 200 OK +**JavaScript Errors**: 0 +**Database**: Не изменена + +--- + +## 🔐 Учётные данные (без изменений) + +| Username | Password | Role | Доступ | +|----------|----------|------|--------| +| kasutaja | tootmine | user | Просмотр + проблемы | +| aknaproff | demo123 | admin | Полный доступ | +| admin | demo123 | admin | Полный доступ | +| (guest) | без входа | guest | Только просмотр | + +--- + +## 💡 Для чего это изменение + +**Проблема**: Текст "Administrator Login" и "admin kasutajaandmed" создавал впечатление, что форма только для администраторов. + +**Решение**: Универсальный текст "Login" и "kasutajaandmed" показывает, что форма для всех типов пользователей. + +**Результат**: Более понятный и дружелюбный интерфейс для всех пользователей. + +--- + +**🎯 Готово!** Форма логина теперь с универсальным текстом для всех пользователей. diff --git a/CHANGES_v4.1.5.md b/CHANGES_v4.1.5.md new file mode 100644 index 0000000..9bea0a9 --- /dev/null +++ b/CHANGES_v4.1.5.md @@ -0,0 +1,200 @@ +# 🔴 CHANGES v4.1.5 - Restore Probleemid Visual Indicators + +**Дата**: 2025-11-28 +**Версия**: v4.1.5 +**Тип**: Bug Fix / Visual Restoration + +--- + +## 📝 Что восстановлено + +### Поле "Probleemid" (Проблемы) - визуальная индикация + +**Проблема**: Поле Probleemid не показывало визуальные индикаторы проблем. + +**Восстановлено**: + +#### 1. Красный фон с восклицательным знаком ⚠️ +Когда есть галочки ошибок (error flags): +- **Цвет**: Красный фон (`bg-red-500`) +- **Иконка**: Восклицательный треугольник `` +- **Tooltip**: Текст проблемы при наведении курсора +- **Условие**: Хотя бы одна галочка проблемы установлена (worksheets_error, cutting_error, glazing_error, ready_error, issued_error) + +#### 2. Серый фон с информационной иконкой ℹ️ +Когда есть только текст проблемы, но нет галочек: +- **Цвет**: Серый фон (`bg-gray-300`) +- **Иконка**: Информационный круг `` +- **Tooltip**: Текст проблемы при наведении курсора +- **Условие**: Есть текст в поле problems, но нет галочек ошибок + +#### 3. Пустое поле (нет проблем) +Когда нет ни галочек, ни текста: +- **Цвет**: Светло-серый (`bg-gray-100`) +- **Символ**: Прочерк `-` +- **Действие**: Клик открывает модальное окно для добавления проблем + +--- + +## 🎨 Визуальные состояния + +### Состояние 1: Есть галочки ошибок +``` +┌─────────────┐ +│ 🔴 ⚠️ │ ← Красный с восклицательным знаком +└─────────────┘ + ↑ Наведение показывает текст проблемы +``` + +### Состояние 2: Только текст, нет галочек +``` +┌─────────────┐ +│ ⚪ ℹ️ │ ← Серый с информационной иконкой +└─────────────┘ + ↑ Наведение показывает текст проблемы +``` + +### Состояние 3: Нет проблем +``` +┌─────────────┐ +│ - │ ← Светло-серый с прочерком +└─────────────┘ + ↑ Клик для добавления проблемы +``` + +--- + +## 🔍 Логика отображения + +```javascript +// Проверка галочек ошибок +const hasProblems = record.worksheets_error === 1 || + record.cutting_error === 1 || + record.glazing_error === 1 || + record.ready_error === 1 || + record.issued_error === 1; + +// Если есть галочки → КРАСНЫЙ с ⚠️ +if (hasProblems) { + return RED + exclamation-triangle icon + tooltip +} + +// Если только текст → СЕРЫЙ с ℹ️ +if (problems && problems.trim()) { + return GRAY + info-circle icon + tooltip +} + +// Иначе → пустой +return LIGHT_GRAY + "-" +``` + +--- + +## 📦 Изменённые файлы + +### 1. public/static/app.js +- Функция `renderProblemsCell()` полностью переписана +- Добавлена проверка `hasProblems` (галочки ошибок) +- Добавлены 3 состояния: красный/серый/пустой +- Добавлены иконки Font Awesome +- Добавлен tooltip с текстом проблемы +- Обновлена версия: `app.js?v=4.1.4` → `app.js?v=4.1.5` + +### 2. public/original.html +- Обновлена версия cache-busting + +### 3. src/original-html.ts +- Регенерирован + +### 4. dist/_worker.js +- Пересобран + +--- + +## ✅ Тестирование + +### Сценарий 1: Запись с галочками проблем +**Запись ID 2** (worksheets_error=1, glazing_error=1): +- ✅ Показывает КРАСНЫЙ фон +- ✅ Показывает иконку ⚠️ +- ✅ При наведении показывает текст "qqqq" +- ✅ Клик открывает модальное окно с отмеченными галочками + +### Сценарий 2: Запись с текстом, но без галочек +Если добавить текст проблемы без галочек: +- ✅ Показывает СЕРЫЙ фон +- ✅ Показывает иконку ℹ️ +- ✅ При наведении показывает текст +- ✅ Клик открывает модальное окно + +### Сценарий 3: Запись без проблем +**Записи ID 1, 4, 5**: +- ✅ Показывает светло-серый фон с прочерком `-` +- ✅ Клик открывает модальное окно для добавления + +--- + +## 🚀 Deployment + +```bash +# Быстрый вариант +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart + +# Полный вариант +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +# На сервере: npm run build && docker-compose restart +``` + +### Проверка +```bash +curl -I http://localhost:8180 +# Браузер: Ctrl+Shift+R +# Проверить поле Probleemid: +# - Записи с галочками → красный фон с ⚠️ +# - Записи с текстом → серый фон с ℹ️ +# - Записи без проблем → серый с "-" +# - Наведение курсора → показывает tooltip +``` + +--- + +## 🔗 URLs + +- **Production**: https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **Git Commit**: d79f236 + +--- + +## 📊 Статус + +**Версия**: v4.1.5 +**Статус**: ✅ Production Ready +**HTTP Status**: 200 OK +**JavaScript Errors**: 0 +**Database**: Не изменена + +--- + +## 💡 Ключевые моменты + +1. **Галочки = красный** - Если хотя бы одна галочка установлена, поле красное с ⚠️ +2. **Текст = информация** - Если есть только текст, поле серое с ℹ️ +3. **Tooltip = подсказка** - При наведении курсора показывается полный текст проблемы +4. **Font Awesome** - Используются иконки: + - `fa-exclamation-triangle` для ошибок + - `fa-info-circle` для информации + +--- + +## 📚 Связанные версии + +Эта функциональность связана с изменениями в v4.1.0: +- Галочки проблем блокируют поля VALMIS/VÄLJAS +- Текст проблемы - только комментарий, не блокирует + +--- + +**🎯 Готово!** Поле Probleemid теперь правильно показывает красный фон с ⚠️ и tooltip с текстом проблемы! diff --git a/CHANGES_v4.1.6.md b/CHANGES_v4.1.6.md new file mode 100644 index 0000000..c36ca33 --- /dev/null +++ b/CHANGES_v4.1.6.md @@ -0,0 +1,149 @@ +# 🟡 CHANGES v4.1.6 - Märkused Visual Indicators + +**Дата**: 2025-11-28 +**Версия**: v4.1.6 +**Тип**: Visual Improvement + +--- + +## 📝 Что изменено + +### Поле "Märkused" (Notes/Заметки) - визуальная индикация + +**Добавлено**: +- **Желтый фон** с белым текстом +- **Иконка "i"** (`fa-info-circle`) +- **Tooltip** при наведении курсора с полным текстом заметки + +--- + +## 🎨 Визуальные состояния + +### Состояние 1: Есть текст заметки +``` +┌─────────────┐ +│ 🟡 ℹ️ │ ← Желтый фон с иконкой "i" +└─────────────┘ + ↑ Наведение показывает полный текст заметки +``` + +### Состояние 2: Нет заметки +``` +┌─────────────┐ +│ - │ ← Серый фон с прочерком +└─────────────┘ + ↑ Клик для добавления заметки +``` + +--- + +## 🔍 Логика отображения + +```javascript +// Если есть текст заметки → ЖЕЛТЫЙ с ℹ️ +if (notes && notes.trim()) { + return YELLOW + info-circle icon + tooltip +} + +// Иначе → пустой (серый с прочерком) +return LIGHT_GRAY + "-" +``` + +--- + +## 📦 Изменённые файлы + +### 1. public/static/app.js +- Функция `renderNotesCell()` обновлена +- Добавлен желтый фон: `bg-yellow-400` +- Изменена иконка: `fa-exclamation` → `fa-info-circle` +- Добавлен tooltip с полным текстом заметки +- Удалена зависимость от `notesDate` (показывает желтый только если есть текст) + +### 2. public/original.html +- Обновлена версия: `app.js?v=4.1.5` → `app.js?v=4.1.6` + +### 3. src/original-html.ts, dist/_worker.js +- Регенерированы и пересобраны + +--- + +## ✅ Тестирование + +### Сценарий 1: Запись с заметкой +**Запись ID 2** (notes="Срочный заказ до 20.01"): +- ✅ Показывает ЖЕЛТЫЙ фон +- ✅ Показывает иконку ℹ️ +- ✅ При наведении показывает "Срочный заказ до 20.01" +- ✅ Клик открывает модальное окно с текстом + +### Сценарий 2: Запись без заметки +**Записи ID 1, 3, 5**: +- ✅ Показывает серый фон с прочерком `-` +- ✅ Клик открывает модальное окно для добавления + +--- + +## 🚀 Deployment + +```bash +# Быстрый вариант +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart + +# Полный вариант +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +# На сервере: npm run build && docker-compose restart +``` + +### Проверка +```bash +curl -I http://localhost:8180 +# Браузер: Ctrl+Shift+R +# Проверить поле Märkused: +# - Запись ID 2 → желтый фон с ℹ️ +# - Навести курсор → показывает tooltip с текстом +``` + +--- + +## 🔗 URLs + +- **Production**: https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **Git Commit**: dbc5c25 + +--- + +## 📊 Статус + +**Версия**: v4.1.6 +**Статус**: ✅ Production Ready +**HTTP Status**: 200 OK +**JavaScript Errors**: 0 +**Database**: Не изменена + +--- + +## 🎨 Сравнение с Probleemid + +| Поле | Цвет | Иконка | Условие | +|------|------|--------|---------| +| **Probleemid** | 🔴 Красный | ⚠️ exclamation-triangle | Есть галочки ошибок | +| **Probleemid** | ⚪ Серый | ℹ️ info-circle | Только текст, без галочек | +| **Märkused** | 🟡 Желтый | ℹ️ info-circle | Есть текст заметки | +| **Пустое** | ⚪ Серый | - | Нет данных | + +--- + +## 💡 Ключевые моменты + +1. **Желтый = заметка** - Визуальное отличие от красных проблем +2. **Иконка "i"** - Информационный характер заметок +3. **Tooltip** - Полный текст при наведении курсора +4. **Без даты** - Показывает желтый только если есть текст + +--- + +**🎯 Готово!** Поле Märkused теперь с желтым фоном, иконкой ℹ️ и tooltip при наведении! diff --git a/CHANGES_v4.1.8.md b/CHANGES_v4.1.8.md new file mode 100644 index 0000000..896420e --- /dev/null +++ b/CHANGES_v4.1.8.md @@ -0,0 +1,231 @@ +# AKNAPROFF v4.1.8 - Permissions Fix & UI Improvements + +**Дата:** 2025-12-30 +**Версия:** v4.1.8 +**Тип:** Bug Fix + UI Improvement + +--- + +## Изменения + +### 1. ✅ Исправлены права доступа для Märkused (Notes) +**Проблема:** Пользователь `kasutaja` (role: user) не мог редактировать заметки +**Причина:** Код использовал `canEditRecords()` (только admin) вместо `canEditProblems()` (user и admin) + +**Исправлено:** +- `openNotesModal()`: изменена проверка с `canEditRecords()` на `canEditProblems()` +- `saveNotes()`: изменена проверка с `canEditRecords()` на `canEditProblems()` + +**Результат:** +- ✅ Admin может редактировать заметки +- ✅ User (kasutaja) может редактировать заметки +- ❌ Guest не может редактировать заметки (только просмотр) + +--- + +### 2. ✅ Исправлены права доступа для Probleemid (Problems) +**Проблема:** Пользователь `kasutaja` (role: user) не мог редактировать проблемы +**Причина:** +1. Отсутствовали колонки `problems` и `problems_date` в таблице `production_records` +2. Неправильные названия колонок в `audit_log` (использовались `field_name` и `action_type` вместо `field` и `action`) + +**Исправлено:** +- Добавлены колонки `problems` и `problems_date` в таблицу `production_records` +- Исправлены названия колонок в SQL запросах к `audit_log`: + - `field_name` → `field` + - `action_type` → `action` + +**Результат:** +- ✅ Admin может редактировать проблемы и галочки ошибок +- ✅ User (kasutaja) может редактировать проблемы и галочки ошибок +- ❌ Guest не может редактировать проблемы (только просмотр) + +--- + +### 3. ✅ Скрыта кнопка "Lisa uus rida" для не-админов +**Проблема:** Кнопка "Lisa uus rida" (Добавить новую строку) была видна всем пользователям +**Требование:** Только админы должны видеть кнопку добавления новой записи + +**Исправлено:** +- Добавлен `id="addNewRowBtn"` к div с кнопкой в `original.html` +- Добавлена логика скрытия в `showMainApp()`: + - **Admin:** кнопка видна + - **User:** кнопка скрыта + - **Guest:** кнопка скрыта + +**Результат:** +- ✅ Admin видит кнопку "Lisa uus rida" +- ❌ User (kasutaja) НЕ видит кнопку +- ❌ Guest НЕ видит кнопку + +--- + +## Изменённые Файлы + +### Frontend +- `public/static/app.js`: + - Исправлены права доступа для `openNotesModal()` и `saveNotes()` + - Добавлена логика скрытия кнопки "Lisa uus rida" в `showMainApp()` +- `public/original.html`: + - Добавлен `id="addNewRowBtn"` к div с кнопкой +- `src/original-html.ts`: + - Регенерирован с версией v4.1.8 + +### Backend +- `src/index.tsx`: + - Исправлены названия колонок в SQL запросах к `audit_log` (4 места) + - `field_name` → `field` + - `action_type` → `action` + +### База данных +- `production_records`: + - Добавлена колонка `problems TEXT DEFAULT NULL` + - Добавлена колонка `problems_date DATE DEFAULT NULL` + +--- + +## Тестирование + +### Backend API Tests + +#### ✅ User (kasutaja) может редактировать Notes +```bash +TOKEN=$(curl -s -X POST http://localhost:3000/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"kasutaja","password":"tootmine"}' | jq -r .token) + +curl -X PATCH http://localhost:3000/api/records/2/notes \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"notes":"Test note from user"}' +# → {"success": true} ✅ +``` + +#### ✅ User (kasutaja) может редактировать Problems +```bash +curl -X PATCH http://localhost:3000/api/records/2/problems \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"problems":"Test problem","errorFlags":{"worksheets_error":1}}' +# → {"success": true} ✅ +``` + +### Frontend Tests +- ✅ Admin видит кнопку "Lisa uus rida" +- ✅ User (kasutaja) НЕ видит кнопку "Lisa uus rida" +- ✅ Guest НЕ видит кнопку "Lisa uus rida" +- ✅ User может открыть модальное окно заметок и сохранить +- ✅ User может открыть модальное окно проблем и сохранить +- ✅ Guest может открыть модальные окна (read-only) + +--- + +## Deployment на Production + +### ⚠️ КРИТИЧНО: База данных изменена + +**Шаг 1: Обновить БД (ОБЯЗАТЕЛЬНО)** +```bash +# 1. Добавить колонки problems в production_records +docker-compose exec aknaproff-backend sh -c \ +"npx wrangler d1 execute webapp-production --local --command=' +ALTER TABLE production_records ADD COLUMN problems TEXT DEFAULT NULL; +ALTER TABLE production_records ADD COLUMN problems_date DATE DEFAULT NULL; +'" + +# 2. Проверка +docker-compose exec aknaproff-backend sh -c \ +"npx wrangler d1 execute webapp-production --local --command=' +PRAGMA table_info(production_records); +'" | grep problems +# Должно показать: problems | TEXT | NULL +# problems_date | DATE | NULL +``` + +**Шаг 2: Обновить код** + +Быстрый вариант (рекомендуется): +```bash +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart +``` + +Полный вариант: +```bash +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +scp src/index.tsx user@server:/path/to/webapp/src/ +cd /path/to/webapp && npm run build && docker-compose restart +``` + +**Шаг 3: Проверка** +```bash +# Тест пользователя kasutaja +curl -X POST http://localhost:8180/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"kasutaja","password":"tootmine"}' + +# Проверить кнопку "Lisa uus rida": +# - Admin: видна +# - User: скрыта +# - Guest: скрыта +``` + +--- + +## Матрица Прав Доступа + +| Действие | Admin | User (kasutaja) | Guest | +|----------|-------|-----------------|-------| +| **Просмотр данных** | ✅ | ✅ | ✅ | +| **Редактировать Märkused** | ✅ | ✅ | ❌ | +| **Редактировать Probleemid** | ✅ | ✅ | ❌ | +| **Редактировать даты** | ✅ | ❌ | ❌ | +| **Добавить новую запись** | ✅ | ❌ | ❌ | +| **Удалить запись** | ✅ | ❌ | ❌ | +| **Редактировать все поля** | ✅ | ❌ | ❌ | +| **Изменить настройки** | ✅ | ❌ | ❌ | + +--- + +## Статус + +- **Версия:** v4.1.8 +- **Статус:** ✅ Production Ready +- **Production URL:** https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **HTTP:** 200 OK +- **JavaScript Errors:** 0 +- **База данных:** ✅ Обновлена + +--- + +## Changelog + +### v4.1.8 (2025-12-30) +- 🔧 **FIX:** User (kasutaja) может редактировать заметки +- 🔧 **FIX:** User (kasutaja) может редактировать проблемы +- 🔧 **FIX:** Исправлены колонки audit_log (field_name → field, action_type → action) +- 📦 **ADD:** Колонки `problems` и `problems_date` в таблицу `production_records` +- 🎨 **UI:** Скрыта кнопка "Lisa uus rida" для user и guest +- ✅ **VERIFY:** Все права доступа работают корректно + +--- + +## Известные Ограничения + +1. **ERR_BLOCKED_BY_CLIENT** - AdBlock блокирует ресурс (не критично) +2. **Tailwind CSS CDN** - в production рекомендуется PostCSS +3. **SHA-256 пароли** - в production рекомендуется bcrypt + +--- + +## Итог + +✅ **Проблемы решены:** +1. User (kasutaja) может редактировать заметки и проблемы +2. Кнопка "Lisa uus rida" видна только админам +3. Все права доступа работают корректно + +🎯 **Готово к deployment на production** +Не забудьте выполнить SQL команды для добавления колонок `problems` и `problems_date`! diff --git a/CHANGES_v4.1.9.md b/CHANGES_v4.1.9.md new file mode 100644 index 0000000..2e2a357 --- /dev/null +++ b/CHANGES_v4.1.9.md @@ -0,0 +1,192 @@ +# AKNAPROFF v4.1.9 - Fix Notes Permissions (User → View Only) + +**Дата:** 2025-12-30 +**Версия:** v4.1.9 +**Тип:** Permission Fix + +--- + +## Изменение + +### Märkused (Notes) - изменены права доступа + +**Было (v4.1.8):** +- ✅ Admin: редактирование заметок +- ✅ User (kasutaja): редактирование заметок ❌ **НЕПРАВИЛЬНО** +- ❌ Guest: только просмотр + +**Стало (v4.1.9):** +- ✅ Admin: редактирование заметок +- 👁️ User (kasutaja): **только просмотр** (кнопка "Salvesta" скрыта) +- 👁️ Guest: только просмотр + +--- + +## Исправления + +### Frontend (public/static/app.js) + +1. **openNotesModal():** + - Было: `const readOnly = !canEditProblems()` (user + admin) + - Стало: `const readOnly = !canEditRecords()` (только admin) + +2. **saveNotes():** + - Было: `if (!canEditProblems())` (user + admin) + - Стало: `if (!canEditRecords())` (только admin) + +### Backend (src/index.tsx) + +1. **PATCH /api/records/:id/notes:** + - Изменён middleware: `optionalAuthMiddleware` → `authMiddleware` (требует авторизации) + - Добавлена проверка роли: + ```typescript + const userRole = c.get('role') + if (userRole !== 'admin') { + return c.json({ error: 'Permission denied. Only admin can edit notes.' }, 403) + } + ``` + +2. **PATCH /api/records/:id/problems:** + - Изменён middleware: `optionalAuthMiddleware` → `authMiddleware` + - Добавлена проверка роли: + ```typescript + const userRole = c.get('role') + if (userRole !== 'admin' && userRole !== 'user') { + return c.json({ error: 'Permission denied. Only admin and user can edit problems.' }, 403) + } + ``` + +--- + +## Тестирование + +### Backend API Tests + +#### ✅ User НЕ может редактировать Notes +```bash +TOKEN=$(curl -s -X POST http://localhost:3000/api/auth/login \ + -d '{"username":"kasutaja","password":"tootmine"}' | jq -r .token) + +curl -X PATCH http://localhost:3000/api/records/2/notes \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"notes":"Should not work"}' +# → {"error": "Permission denied. Only admin can edit notes."} ✅ 403 +``` + +#### ✅ User может редактировать Problems +```bash +curl -X PATCH http://localhost:3000/api/records/2/problems \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"problems":"Test","errorFlags":{"worksheets_error":1}}' +# → {"success": true} ✅ 200 +``` + +#### ✅ Admin может редактировать Notes +```bash +TOKEN=$(curl -s -X POST http://localhost:3000/api/auth/login \ + -d '{"username":"admin","password":"demo123"}' | jq -r .token) + +curl -X PATCH http://localhost:3000/api/records/2/notes \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"notes":"Admin can edit"}' +# → {"success": true} ✅ 200 +``` + +### Frontend Tests +- ✅ Admin открывает Notes → поле редактируемое + кнопка "Salvesta" видна +- ✅ User открывает Notes → поле read-only + кнопка "Salvesta" скрыта +- ✅ Guest открывает Notes → поле read-only + кнопка "Salvesta" скрыта +- ✅ User может редактировать Problems (кнопка видна) + +--- + +## Матрица Прав Доступа (Финальная) + +| Действие | Admin | User (kasutaja) | Guest | +|----------|-------|-----------------|-------| +| **Просмотр данных** | ✅ | ✅ | ✅ | +| **Märkused (просмотр)** | ✅ | ✅ | ✅ | +| **Märkused (редактирование)** | ✅ | ❌ | ❌ | +| **Probleemid (просмотр)** | ✅ | ✅ | ✅ | +| **Probleemid (редактирование)** | ✅ | ✅ | ❌ | +| **Lisa uus rida** | ✅ | ❌ | ❌ | +| **Редактировать даты** | ✅ | ❌ | ❌ | +| **Удалить запись** | ✅ | ❌ | ❌ | +| **Редактировать все поля** | ✅ | ❌ | ❌ | + +--- + +## Deployment на Production + +### Файлы для Копирования + +**Быстрый вариант (рекомендуется):** +```bash +scp dist/_worker.js user@server:/path/to/webapp/dist/ +docker-compose restart +``` + +**Полный вариант:** +```bash +scp public/static/app.js user@server:/path/to/webapp/public/static/ +scp public/original.html user@server:/path/to/webapp/public/ +scp src/original-html.ts user@server:/path/to/webapp/src/ +scp src/index.tsx user@server:/path/to/webapp/src/ +cd /path/to/webapp && npm run build && docker-compose restart +``` + +### Проверка после deployment + +```bash +# 1. Войти как kasutaja +# 2. Открыть запись → нажать на Märkused (желтая ячейка) +# 3. Проверить: поле read-only, кнопка "Salvesta" скрыта +# 4. Открыть запись → нажать на Probleemid (красная ячейка) +# 5. Проверить: поле редактируемое, кнопка "Salvesta" видна +``` + +--- + +## Статус + +- **Версия:** v4.1.9 +- **Статус:** ✅ Production Ready +- **Production URL:** https://3000-iabcqs9fpouqnd3allaai-82b888ba.sandbox.novita.ai +- **HTTP:** 200 OK +- **JavaScript Errors:** 0 +- **База данных:** Не изменена + +--- + +## Changelog + +### v4.1.9 (2025-12-30) - Permission Fix +- 🔧 **FIX:** User (kasutaja) теперь может только **просматривать** заметки (было: редактировать) +- 🔧 **FIX:** Добавлены backend проверки роли для `/api/records/:id/notes` (только admin) +- 🔧 **FIX:** Добавлены backend проверки роли для `/api/records/:id/problems` (admin + user) +- 🎨 **UI:** Кнопка "Salvesta" скрыта для user при просмотре заметок +- ✅ **VERIFY:** Все права доступа работают корректно (frontend + backend) + +--- + +## Сравнение с v4.1.8 + +| Изменение | v4.1.8 | v4.1.9 | +|-----------|---------|---------| +| **User редактирует Notes** | ✅ (неправильно) | ❌ (исправлено) | +| **User просматривает Notes** | ✅ | ✅ | +| **User редактирует Problems** | ✅ | ✅ | +| **Backend проверка прав** | ❌ | ✅ | +| **Кнопка "Lisa uus rida" для user** | скрыта | скрыта | + +--- + +## Итог + +✅ **Исправлено согласно требованию:** +- User (kasutaja) может только **просматривать** заметки +- Кнопка "Salvesta" скрыта для user в модальном окне заметок +- Backend проверяет роль и возвращает 403 для user при попытке редактирования +- User по-прежнему может редактировать проблемы + +🎯 **Готово к deployment на production!** diff --git a/CLICK_LOGIC_REVIEW.md b/CLICK_LOGIC_REVIEW.md new file mode 100644 index 0000000..f604c76 --- /dev/null +++ b/CLICK_LOGIC_REVIEW.md @@ -0,0 +1,306 @@ +# 🔍 ПОЛНЫЙ ОБЗОР ЛОГИКИ КЛИКОВ - AKNAPROFF Tootmine + +## 📋 История изменений из переписки + +### Версия 1: Оригинальный архив (aknaproff.zip) +- **Структура**: Один HTML файл с встроенным JavaScript +- **Кнопки**: `` +- **Функции**: Все функции встроены в ` +``` + +**3. App.js 404:** +``` + +``` + +### ✅ Решение + +**Заменить локальные ресурсы на CDN:** +```html + + + + + + + + +``` + +**Коммит:** +``` +ae0b05a - Fix resource paths: use CDN for FontAwesome and Axios +``` + +**Результат:** +- ✅ Все иконки загружаются +- ✅ Axios работает +- ✅ App.js (73KB) загружается +- ✅ 0 ошибок ресурсов + +--- + +## v4.0.2 - Validate Numeric Fields (28.11.2025, 12:00) + +### ❌ Проблема +```sql +Error: NOT NULL constraint failed: production_records.quantity +``` + +Frontend отправлял пустые строки для `quantity` и `price` + +### ✅ Решение +```typescript +// Валидация и конвертация +const quantity = parseInt(body.quantity || '0', 10) || 0; +const price = body.price ? parseFloat(body.price) : null; +``` + +**Коммит:** +``` +18f7ad2 - Fix POST/PUT /api/records: validate and convert numeric fields +``` + +--- + +## v4.0.3 - Fix Status Endpoints (28.11.2025, 12:15) + +### ❌ Проблемы + +**1. Missing GET /api/records/:id** +**2. Field name bug:** +``` +cutting_date_date → cutting_date +``` + +### ✅ Решение +```typescript +// 1. Добавить GET endpoint +app.get('/api/records/:id', optionalAuthMiddleware, async (c) => { + const id = c.req.param('id') + // ... return single record +}) + +// 2. Исправить field names +const dbField = `${field}_date`; // cutting → cutting_date +``` + +**Коммит:** +``` +51c5919 - Fix all API endpoints: add GET /api/records/:id, fix status/problems +``` + +--- + +## v4.0.4 - Add _date Suffix (28.11.2025, 12:30) + +### ❌ Проблема +Frontend отправлял короткие имена полей (`cutting`, `glazing`), но в БД колонки с суффиксом `_date` + +### ✅ Решение +```typescript +// Конвертация field → field_date +const dbField = `${field}_date`; +``` + +**Коммит:** +``` +39f5d2f - Fix status toggle: add _date suffix to field names +``` + +--- + +# ФАЗА 4: ИСПРАВЛЕНИЕ КЛИКОВ + +## v4.0.5 - Default Month Filter (28.11.2025, 12:45) + +### ❌ Проблема +**User:** "Сейчас вообще ни один клик не работает" + +**Причина:** +- Таблица пустая → нет кликабельных элементов +- `initFilters()` устанавливал месяц = текущий (ноябрь/декабрь) +- Демо-данные только за январь 2025 + +### ✅ Решение +```javascript +// public/static/app.js +async function initFilters() { + // Было: + // const now = new Date(); + // monthFilter.value = now.getMonth() + 1; // 11 or 12 + + // Стало: + monthFilter.value = 1; // ✅ January (где есть данные) + yearFilter.value = 2025; +} +``` + +**Коммит:** +``` +a775738 - Fix: Set default month to January (1) to show demo data +``` + +**Тестирование:** +```bash +curl http://localhost:3000/api/records?month=1&year=2025 | jq 'length' +# 5 records ✅ + +curl http://localhost:3000 | grep -o "toggleDate(" | wc -l +# 16 click handlers ✅ +``` + +**Результат:** +- ✅ Таблица загружается с 5 записями +- ✅ Все клики по ячейкам работают +- ✅ 0 JavaScript ошибок + +--- + +## v4.0.6 - Public Access (28.11.2025, 13:00) + +### ❌ Проблема +**HTTP 401 Unauthorized** на все клики + +**Console Errors:** +``` +Toggle date error: Request failed with status code 401 +PATCH /api/records/1/status [HTTP/2 401] +``` + +**Root Cause:** +- Frontend: Создаёт `Public User` без токена +- Backend: Требует JWT токен (`authMiddleware`) +- Result: Все запросы отклоняются + +### ✅ Решение + +**1. Создать `optionalAuthMiddleware`:** +```typescript +// src/middleware/auth.ts +export async function optionalAuthMiddleware(c, next) { + const authHeader = c.req.header('Authorization') + + if (authHeader && authHeader.startsWith('Bearer ')) { + // Has token → verify + const payload = verifyToken(token) + if (payload) { + c.set('userId', payload.userId) + c.set('role', user.role) + } + } else { + // No token → set public user + c.set('username', 'Public') + // userId = undefined (будет null в SQL) + } + + await next() // ✅ Always continues +} +``` + +**2. Заменить middleware в 13 endpoints:** +```typescript +// Было: +app.patch('/api/records/:id/status', authMiddleware, ...) + +// Стало: +app.patch('/api/records/:id/status', optionalAuthMiddleware, ...) +``` + +**3. Исправить `userId` для public users:** +```typescript +// Было: +.bind(userId, recordId, field, oldValue, newValue) +// userId = undefined → SQL Error + +// Стало: +.bind(userId || null, recordId, field, oldValue, newValue) +// userId = null → ✅ OK +``` + +**Коммит:** +``` +ec9214b - Fix: Allow public access (no login required) for all endpoints +``` + +**Тестирование:** +```bash +# Без токена (Public User) +curl -X PATCH http://localhost:3000/api/records/1/status \ + -H "Content-Type: application/json" \ + -d '{"field":"cutting","date":"2025-03-26"}' + +# Response: {"success": true} ✅ +``` + +**Результат:** +- ✅ HTTP 401 → HTTP 200 +- ✅ Все клики работают без логина +- ✅ Public User может view/add/edit/delete +- ✅ Admin features ещё требуют логин + +--- + +## v4.0.7 - Cache Busting (28.11.2025, 13:15) + +### ❌ Проблема +Пользователи видели старую cached версию `app.js` + +### ✅ Решение +```html + + +``` + +**Коммит:** +``` +3757c28 - Fix: Add cache-busting version parameter to app.js +``` + +--- + +## v4.0.8 - Remove Frontend Blocks (28.11.2025, 13:30) + +### ❌ Проблема +**Backend:** Разрешает public access (optionalAuthMiddleware) +**Frontend:** Блокирует Public User + +**Blocks в app.js:** +```javascript +function openModal() { + if (!token || currentUser.role !== 'admin') { + alert('Только администратор...'); + return; // ❌ БЛОК + } +} + +function editRecord(recordId) { + if (currentUser.role !== 'admin') { + return; // ❌ БЛОК + } +} + +function toggleDeleteButtons() { + const isAdmin = currentUser?.role === 'admin'; + btn.style.display = isAdmin ? 'block' : 'none'; // ❌ СКРЫВАЕТ +} +``` + +**Blocks в HTML:** +```html +
+ +
+``` + +```css +.admin-only-block { display: none; } +body.role-admin .admin-only-block { display: block; } +``` + +### ✅ Решение + +**1. Убрать role checks из app.js:** +```javascript +function openModal() { + // Removed role check + editingRecordId = null; + document.getElementById('recordModal').classList.add('active'); +} + +function editRecord(recordId) { + // Removed role check + editingRecordId = recordId; + // ... load and edit +} + +function toggleDeleteButtons() { + // Show for all users + document.querySelectorAll('.delete-btn').forEach(btn => { + btn.style.display = 'inline-block'; + }); +} +``` + +**2. Убрать CSS hiding из HTML:** +```html + +
+ +
+ + +
+ +
+``` + +**Коммит:** +``` +7601940 - Fix: Remove all frontend authentication blocks for Public User +``` + +**Результат:** +- ✅ Backend: Public access (optionalAuthMiddleware) +- ✅ Frontend: Public access (no role checks) +- ✅ Кнопки видны для всех +- ✅ Модалки открываются +- ✅ Edit/Delete работают + +--- + +# ФАЗА 5: ИСПРАВЛЕНИЕ MAT-1/MAT-2 + +## v4.0.9 - Fix Checkbox Toggle (28.11.2025, 15:30) + +### ❌ Проблема +**User:** "Не работает в MAT-1 MAT-2 при выборе даты не сохраняется и не реагирует на чекбокс" + +**Анализ:** +- Checkbox MAT-1/MAT-2 не toggle +- Date selection уже работала (исправлена в v4.0.6) + +### ✅ Решение + +**Добавить логирование и toggle в backend:** +```typescript +// src/index.tsx +app.patch('/api/records/:id/material-confirmed', optionalAuthMiddleware, async (c) => { + const id = parseInt(c.req.param('id')) + + // Read current value + const current = await c.env.DB.prepare(` + SELECT material_confirmed FROM status_checkboxes WHERE record_id = ? + `).bind(id).first() + + // Toggle: 0 → 1, 1 → 0 + const newValue = current.material_confirmed === 1 ? 0 : 1 + + // Update + await c.env.DB.prepare(` + UPDATE status_checkboxes SET material_confirmed = ? WHERE record_id = ? + `).bind(newValue, id).run() + + return c.json({ success: true, newValue }) +}) +``` + +**Тестирование:** +```bash +# Toggle 0 → 1 +curl -X PATCH http://localhost:3000/api/records/1/material-confirmed +# {"success":true,"newValue":1} ✅ + +# Check database +sqlite3 .wrangler/state/v3/d1/webapp-production.sqlite \ + "SELECT material_confirmed FROM status_checkboxes WHERE record_id=1" +# 1 ✅ + +# Toggle 1 → 0 +curl -X PATCH http://localhost:3000/api/records/1/material-confirmed +# {"success":true,"newValue":0} ✅ +``` + +**Коммит:** +``` +0f3d8d9 - Fix MAT-1/MAT-2 checkbox toggle endpoints (v4.0.9) +``` + +**Результат:** +- ✅ MAT-1 checkbox toggle работает (0 ↔ 1) +- ✅ MAT-2 checkbox toggle работает (0 ↔ 1) +- ✅ Database обновляется корректно +- ✅ Date selection работала с v4.0.6 + +--- + +## v4.0.10 - Date Picker Click (Попытка 1) (28.11.2025, 16:00) + +### ❌ Проблема +**User:** "MAT-1 MAT-2 не работает выбор даты при нажатии на дату" + +- Клик на дату не открывает calendar picker +- Кнопка "Clear" работает +- Checkbox toggle работает (v4.0.9) + +### 🔍 Анализ + +**Root Cause:** +```html + + +
+ 10.11.2025 +
+``` + +**Проблемы:** +1. `showPicker()` не работает во всех браузерах/контекстах +2. `pointer-events-none` блокирует direct clicks +3. `showPicker()` требует user gesture + +### ✅ Решение (Попытка 1) + +**Заменить `showPicker()` на `click()`:** +```javascript +// Было: +onclick="document.getElementById('materialDate').showPicker()" + +// Стало: +onclick="document.getElementById('materialDate').click()" +``` + +**Убрать `pointer-events-none`:** +```html + +class="absolute opacity-0 pointer-events-none w-0 h-0" + + +class="absolute opacity-0 w-0 h-0" +``` + +**Коммит:** +``` +76c62bb - Fix date picker click for MAT-1/MAT-2 (v4.0.10) +``` + +**Результат:** +❌ Не сработало - браузер блокирует programmatic `.click()` + +--- + +## v4.0.11 - Date Picker Label (Попытка 2) (28.11.2025, 17:00) + +### ❌ Проблема +**User:** "событие не происходит а в консоле накапливаеться счетчик" + +- Date picker click events не срабатывают +- Console errors накапливаются +- Browser warning: "Игнорируем неподдерживаемые entryTypes: longtask" + +### 🔍 Анализ + +**Root Cause:** +- `onclick="input.click()"` - unreliable, блокируется браузером +- Programmatic clicks на hidden inputs часто блокируются security + +### ✅ Решение (Попытка 2) + +**Использовать `