v4.1.21: Реструктуризация проекта для Synology ARM
- Реструктуризация: src/ разбит на middleware/, utils/, repositories/ (удалены), routes/ (удалены) - Добавлен src/original-html.ts — полный HTML с reportModal - Добавлен src/index.tsx.backup — React-компонент с reportModal - Миграции переименованы (0001_initial_schema.sql) - Добавлена миграция 0018 (удалена позже) - Docker: multi-stage build, wrangler.toml - Frontend: public/static/app.js + style.css - seed.sql добавлен - Документация: CHANGELOG, CHANGES_v4.1.0-4.1.9, PROJECT_STRUCTURE
This commit is contained in:
381
DATE_FIELDS_LOGIC.md
Normal file
381
DATE_FIELDS_LOGIC.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# 📋 ЛОГИКА ДАТ И ЧЕКБОКСОВ - ПОЛНОЕ РУКОВОДСТВО
|
||||
|
||||
**Версия**: v4.1.17
|
||||
**Дата**: 2026-01-14
|
||||
**Обновление**: Исправлены права доступа (см. ACCESS_RIGHTS.md)
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ **ВАЖНО: ПРАВА ДОСТУПА**
|
||||
|
||||
**Детальная информация о правах доступа находится в файле:**
|
||||
📄 **[ACCESS_RIGHTS.md](./ACCESS_RIGHTS.md)**
|
||||
|
||||
**Краткая сводка:**
|
||||
- **Admin**: полный доступ (календари + toggle)
|
||||
- **User**: подтверждение MAT-1/MAT-2 + toggle всех полей
|
||||
- **Guest**: только просмотр
|
||||
|
||||
---
|
||||
|
||||
## 🔄 **TÖÖLEHTI (WORKSHEETS) - 3-ШАГОВЫЙ ЦИКЛ**
|
||||
|
||||
### **Как работает:**
|
||||
|
||||
#### **ШАГ 1: Пусто → Серый фон с датой**
|
||||
- **Состояние**: Пустая ячейка `-`
|
||||
- **Действие**: Клик по ячейке
|
||||
- **Результат**:
|
||||
- Появляется **текущая дата**
|
||||
- Фон **СЕРЫЙ** (не подтверждено)
|
||||
- `worksheets_date` = TODAY
|
||||
- `worksheets_confirmed` = 0
|
||||
|
||||
#### **ШАГ 2: Серый → Зеленый фон (подтверждение)**
|
||||
- **Состояние**: Дата с серым фоном
|
||||
- **Действие**: Клик по ячейке
|
||||
- **Результат**:
|
||||
- Дата **остается**
|
||||
- Фон становится **ЗЕЛЕНЫЙ** (подтверждено)
|
||||
- `worksheets_date` = **сохраняется**
|
||||
- `worksheets_confirmed` = 1
|
||||
|
||||
#### **ШАГ 3: Зеленый → Пусто (сброс)**
|
||||
- **Состояние**: Дата с зеленым фоном
|
||||
- **Действие**: Клик по ячейке
|
||||
- **Результат**:
|
||||
- Дата **удаляется**
|
||||
- Ячейка становится **пустой** `-`
|
||||
- `worksheets_date` = NULL
|
||||
- `worksheets_confirmed` = 0
|
||||
|
||||
### **Визуальная схема:**
|
||||
```
|
||||
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌─────────────┐
|
||||
│ ПУСТО │ Клик 1 │ СЕРЫЙ ФОН │ Клик 2 │ ЗЕЛЕНЫЙ ФОН │ Клик 3 │ ПУСТО │
|
||||
│ - │ ──────> │ 14.01.2026 │ ──────> │ 14.01.2026 │ ──────> │ - │
|
||||
│ │ │ (не подтверждено)│ │ (подтверждено) │ │ │
|
||||
└─────────────┘ └──────────────────┘ └──────────────────┘ └─────────────┘
|
||||
^ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────┘
|
||||
Цикл повторяется
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🟢 **MAT-1 (MATERIAL) - КАЛЕНДАРЬ + ПОДТВЕРЖДЕНИЕ**
|
||||
|
||||
### **Функционал:**
|
||||
- **Календарь**: Клик по ячейке → открывается календарь
|
||||
- **Выбор даты**: Выбрать дату → сохраняется `material_date`
|
||||
- **Кнопка подтверждения** ✓: Клик → зеленая рамка
|
||||
- `material_confirmed` = 1
|
||||
- Ячейка с зеленой рамкой
|
||||
|
||||
### **Кто может изменять:**
|
||||
- ✅ Admin
|
||||
- ✅ Public User (все)
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.material_date` (TEXT)
|
||||
- `status_checkboxes.material_confirmed` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 🔒 **MAT-2 (MATERIAL2) - ЗАВИСИТ ОТ MAT-1**
|
||||
|
||||
### **Блокировка:**
|
||||
- **Заблокировано**: Если MAT-1 пустая
|
||||
- **Показывается**: 🔒 с подсказкой "MAT-1 peab olema täidetud"
|
||||
- **Разблокировано**: Когда MAT-1 заполнена
|
||||
|
||||
### **Функционал (когда разблокирована):**
|
||||
- **Календарь**: Клик → открывается календарь
|
||||
- **Выбор даты**: Выбрать дату → сохраняется `material2_date`
|
||||
- **Кнопка подтверждения** ✓: Клик → зеленая рамка
|
||||
- `material2_confirmed` = 1
|
||||
|
||||
### **Кто может изменять:**
|
||||
- ✅ Admin
|
||||
- ✅ Public User (если MAT-1 заполнена)
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.material2_date` (TEXT)
|
||||
- `status_checkboxes.material2_confirmed` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 📦 **PAKETT (PACKAGE) - КАЛЕНДАРЬ**
|
||||
|
||||
### **Функционал:**
|
||||
- **Календарь**: Клик → открывается календарь
|
||||
- **Выбор даты**: Выбрать дату → сохраняется `package_date`
|
||||
- **Нет подтверждения**: Только дата (без кнопки ✓)
|
||||
|
||||
### **Кто может изменять:**
|
||||
- ✅ Admin
|
||||
- ✅ Public User (все)
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.package_date` (TEXT)
|
||||
|
||||
---
|
||||
|
||||
## 🔴 **LÕIKUS (CUTTING) - ТОЛЬКО ADMIN**
|
||||
|
||||
### **Функционал:**
|
||||
- **Toggle**: Клик → дата появляется/исчезает
|
||||
- **Автоматическая дата**: Устанавливается на **сегодня**
|
||||
- **Ошибка-флаг** 🚫: `cutting_error`
|
||||
- Если установлена → красная метка
|
||||
- Блокирует **VALMIS** и **VÄLJAS**
|
||||
|
||||
### **Кто может изменять:**
|
||||
- 🔴 **ТОЛЬКО Admin**
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.cutting_date` (TEXT)
|
||||
- `status_checkboxes.cutting_error` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 🔴 **KLAAS (GLAZING) - ТОЛЬКО ADMIN**
|
||||
|
||||
### **Функционал:**
|
||||
- **Toggle**: Клик → дата появляется/исчезает
|
||||
- **Автоматическая дата**: Устанавливается на **сегодня**
|
||||
- **Ошибка-флаг** 🚫: `glazing_error`
|
||||
- Если установлена → красная метка
|
||||
- Блокирует **VALMIS** и **VÄLJAS**
|
||||
|
||||
### **Кто может изменять:**
|
||||
- 🔴 **ТОЛЬКО Admin**
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.glazing_date` (TEXT)
|
||||
- `status_checkboxes.glazing_error` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 🔒 **VALMIS (READY) - Admin/User Toggle + БЛОКИРОВКА ТОЛЬКО ПО ERROR ФЛАГАМ**
|
||||
|
||||
### **ВАЖНО: ТЕКСТ ПРОБЛЕМЫ НЕ БЛОКИРУЕТ!**
|
||||
Текст в поле "Probleemid" (серая метка ⚠️) **НЕ** блокирует VALMIS!
|
||||
|
||||
### **Блокировка:**
|
||||
Поле **ЗАБЛОКИРОВАНО ТОЛЬКО**, если установлен **ЛЮБОЙ error флаг** (красная галочка ✗):
|
||||
- `worksheets_error = 1`
|
||||
- `cutting_error = 1`
|
||||
- `glazing_error = 1`
|
||||
- `ready_error = 1`
|
||||
- `issued_error = 1`
|
||||
|
||||
**НЕ блокируется**, если:
|
||||
- Есть только текст в `production_records.problems` (серая метка ⚠️)
|
||||
- Все error флаги = 0
|
||||
|
||||
### **Визуальное отображение:**
|
||||
- **Заблокировано**: 🔒 + сообщение "Vigade märked on seatud (punased kolmnurgad)"
|
||||
- **Разблокировано**: Toggle как обычно
|
||||
|
||||
### **Функционал (когда разблокирована):**
|
||||
- **Toggle**: Клик → дата появляется/исчезает
|
||||
- **Автоматическая дата**: Устанавливается на **сегодня**
|
||||
|
||||
### **Кто может изменять:**
|
||||
- ✅ **Admin + User** (изменено в v4.1.18)
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.ready_date` (TEXT)
|
||||
- `status_checkboxes.ready_error` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 🔒 **VÄLJAS (ISSUED) - Admin/User Toggle + БЛОКИРОВКА ТОЛЬКО ПО ERROR ФЛАГАМ**
|
||||
|
||||
### **ВАЖНО: ТЕКСТ ПРОБЛЕМЫ НЕ БЛОКИРУЕТ!**
|
||||
Текст в поле "Probleemid" (серая метка ⚠️) **НЕ** блокирует VÄLJAS!
|
||||
|
||||
### **Блокировка:**
|
||||
**ТА ЖЕ ЛОГИКА** что и **VALMIS**:
|
||||
- Блокируется **ТОЛЬКО** если установлен **ЛЮБОЙ error флаг** (красная галочка ✗)
|
||||
- **НЕ** блокируется если есть только текст в `production_records.problems`
|
||||
|
||||
### **Функционал (когда разблокирована):**
|
||||
- **Toggle**: Клик → дата появляется/исчезает
|
||||
- **Автоматическая дата**: Устанавливается на **сегодня**
|
||||
|
||||
### **Кто может изменять:**
|
||||
- ✅ **Admin + User** (изменено в v4.1.18)
|
||||
|
||||
### **Кто может изменять:**
|
||||
- 🔴 **ТОЛЬКО Admin**
|
||||
|
||||
### **База данных:**
|
||||
- `status_checkboxes.issued_date` (TEXT)
|
||||
- `status_checkboxes.issued_error` (INTEGER, 0 или 1)
|
||||
|
||||
---
|
||||
|
||||
## 📊 **СВОДНАЯ ТАБЛИЦА**
|
||||
|
||||
| Поле | Тип | Доступ | Логика | Подтверждение | Блокировка |
|
||||
|------|-----|--------|--------|---------------|-----------|
|
||||
| **MAT-1** | Календарь | Все | Календарь | ✓ Да | Нет |
|
||||
| **MAT-2** | Календарь | Все | Календарь | ✓ Да | Если MAT-1 пуста |
|
||||
| **PAKETT** | Календарь | Все | Календарь | Нет | Нет |
|
||||
| **Töölehti** | 3-цикл | Admin | Серый→Зеленый→Пусто | Да | Нет |
|
||||
| **LÕIKUS** | Toggle | Admin | Появляется/Исчезает | Нет | Нет |
|
||||
| **KLAAS** | Toggle | Admin | Появляется/Исчезает | Нет | Нет |
|
||||
| **VALMIS** | Toggle | Admin/User | Появляется/Исчезает | Нет | ТОЛЬКО если error флаги (НЕ текст проблемы) |
|
||||
| **VÄLJAS** | Toggle | Admin/User | Появляется/Исчезает | Нет | ТОЛЬКО если error флаги (НЕ текст проблемы) |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 **ПРАВА ДОСТУПА**
|
||||
|
||||
### **Admin** (admin, aknaproff):
|
||||
- ✅ Все поля (MAT-1, MAT-2, PAKETT, Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS)
|
||||
- ✅ Добавление записей
|
||||
- ✅ Редактирование записей
|
||||
- ✅ Удаление записей
|
||||
- ✅ Изменение проблем и ошибок
|
||||
|
||||
### **Public User** (kasutaja):
|
||||
- ✅ MAT-1 (календарь + подтверждение)
|
||||
- ✅ MAT-2 (календарь + подтверждение, если MAT-1 заполнена)
|
||||
- ✅ PAKETT (календарь)
|
||||
- ❌ Töölehti, LÕIKUS, KLAAS, VALMIS, VÄLJAS (только просмотр)
|
||||
- ❌ Добавление/редактирование/удаление записей
|
||||
|
||||
---
|
||||
|
||||
## 🎨 **ВИЗУАЛЬНЫЕ ИНДИКАТОРЫ**
|
||||
|
||||
### **Цвета:**
|
||||
- 🟢 **Зеленая рамка**: MAT-1/MAT-2 подтверждены
|
||||
- 🟢 **Зеленый фон**: Töölehti подтверждено (confirmed=1)
|
||||
- ⬜ **Серый фон**: Töölehti не подтверждено (confirmed=0)
|
||||
- 🔴 **Красная метка**: Ошибка-флаг установлен
|
||||
- 🔒 **Замок**: Поле заблокировано
|
||||
|
||||
### **Подсказки:**
|
||||
- **MAT-2 заблокирована**: "MAT-1 peab olema täidetud"
|
||||
- **VALMIS/VÄLJAS заблокированы**: Текст проблемы из `production_records.problems`
|
||||
- **Töölehti Шаг 1**: "Klõps 1: Lisa kuupäev"
|
||||
- **Töölehti Шаг 2**: "Klõps 2: Kinnita"
|
||||
- **Töölehti Шаг 3**: "Klõps 3: Tühjenda"
|
||||
|
||||
---
|
||||
|
||||
## 📝 **AUDIT LOG**
|
||||
|
||||
Каждое изменение даты записывается в таблицу `audit_log`:
|
||||
```sql
|
||||
INSERT INTO audit_log (user_id, record_id, field, old_value, new_value, action)
|
||||
VALUES (?, ?, ?, ?, ?, 'toggle_status')
|
||||
```
|
||||
|
||||
**Поля:**
|
||||
- `user_id`: ID пользователя (1=admin, 2=aknaproff, 4=kasutaja)
|
||||
- `record_id`: ID записи
|
||||
- `field`: Название поля (worksheets, cutting, glazing, ready, issued)
|
||||
- `old_value`: Старое значение даты
|
||||
- `new_value`: Новое значение даты
|
||||
- `action`: Тип действия ('toggle_status', 'worksheets_cycle')
|
||||
|
||||
---
|
||||
|
||||
## ✅ **ПРОВЕРКА**
|
||||
|
||||
### **Test Töölehti 3-цикл:**
|
||||
```bash
|
||||
# Шаг 1: Пусто → Серый
|
||||
PATCH /api/records/2/worksheets-cycle
|
||||
→ {"date": "2026-01-14", "confirmed": 0}
|
||||
|
||||
# Шаг 2: Серый → Зеленый
|
||||
PATCH /api/records/2/worksheets-cycle
|
||||
→ {"date": "2026-01-14", "confirmed": 1}
|
||||
|
||||
# Шаг 3: Зеленый → Пусто
|
||||
PATCH /api/records/2/worksheets-cycle
|
||||
→ {"date": null, "confirmed": 0}
|
||||
```
|
||||
|
||||
### **Test блокировка MAT-2:**
|
||||
```bash
|
||||
# MAT-1 пустая → MAT-2 заблокирована
|
||||
SELECT material_date FROM status_checkboxes WHERE record_id = 5
|
||||
→ NULL
|
||||
# UI показывает: 🔒 "MAT-1 peab olema täidetud"
|
||||
```
|
||||
|
||||
### **Test блокировка VALMIS:**
|
||||
```bash
|
||||
# Есть проблемы → VALMIS заблокирована
|
||||
SELECT problems FROM production_records WHERE id = 10
|
||||
→ "Aken vajab parandust"
|
||||
# UI показывает: 🔒 + текст проблемы
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Версия**: v4.1.16
|
||||
**Статус**: ✅ Работает корректно
|
||||
**Дата**: 2026-01-14
|
||||
|
||||
---
|
||||
|
||||
## 🔒 **ВАЖНО: ПРАВИЛО БЛОКИРОВКИ VALMIS/VÄLJAS**
|
||||
|
||||
### **Версия**: v4.1.19
|
||||
### **Дата изменения**: 2026-01-14
|
||||
|
||||
**КРИТИЧЕСКИ ВАЖНО**: Блокировка VALMIS/VÄLJAS работает **ТОЛЬКО** по error флагам!
|
||||
|
||||
### **Блокируется**, если установлен **ЛЮБОЙ** из error флагов (красная галочка ✗):
|
||||
- `worksheets_error = 1`
|
||||
- `cutting_error = 1`
|
||||
- `glazing_error = 1`
|
||||
- `ready_error = 1`
|
||||
- `issued_error = 1`
|
||||
|
||||
### **НЕ БЛОКИРУЕТСЯ**, если:
|
||||
- Есть **ТОЛЬКО** текст в `production_records.problems` (серая метка ⚠️)
|
||||
- Все error флаги = 0
|
||||
|
||||
### **Визуальные индикаторы:**
|
||||
- **VALMIS/VÄLJAS заблокированы**: 🔒 + сообщение "Vigade märked on seatud (punased kolmnurgad)"
|
||||
- **Серая метка с ⚠️**: Указывает на текст проблемы в поле "Probleemid", **НЕ блокирует** VALMIS/VÄLJAS
|
||||
|
||||
### **Код проверки блокировки** (backend):
|
||||
```typescript
|
||||
if (field === 'ready' || field === 'issued') {
|
||||
const statusCheckbox = await c.env.DB.prepare(
|
||||
'SELECT worksheets_error, cutting_error, glazing_error, ready_error, issued_error FROM status_checkboxes WHERE record_id = ?'
|
||||
).bind(recordId).first()
|
||||
|
||||
const hasErrorFlags = statusCheckbox && (
|
||||
statusCheckbox.worksheets_error ||
|
||||
statusCheckbox.cutting_error ||
|
||||
statusCheckbox.glazing_error ||
|
||||
statusCheckbox.ready_error ||
|
||||
statusCheckbox.issued_error
|
||||
)
|
||||
|
||||
if (hasErrorFlags) {
|
||||
return c.json({
|
||||
error: 'blocked',
|
||||
message: 'Vigade märked on seatud (punased kolmnurgad)'
|
||||
}, 403)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Тестирование** (результаты от 2026-01-14):
|
||||
✅ **Test 1**: Только текст problems → НЕ блокируется → `{"success":true}`
|
||||
✅ **Test 2**: Установлен error flag → БЛОКИРУЕТСЯ → `{"error":"blocked","message":"..."}`
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user