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:
Deploy Bot
2026-01-14 18:37:00 +02:00
parent 4898f5ec7f
commit 64403d6fd6
113 changed files with 19231 additions and 3084 deletions

306
CLICK_LOGIC_REVIEW.md Normal file
View File

@@ -0,0 +1,306 @@
# 🔍 ПОЛНЫЙ ОБЗОР ЛОГИКИ КЛИКОВ - AKNAPROFF Tootmine
## 📋 История изменений из переписки
### Версия 1: Оригинальный архив (aknaproff.zip)
- **Структура**: Один HTML файл с встроенным JavaScript
- **Кнопки**: `<button onclick="openModal()">Lisa uus rida</button>`
- **Функции**: Все функции встроены в `<script>` теги внутри HTML
- **Аутентификация**: НЕТ - приложение работало без логина
- **Статус**: ✅ Все клики работали
### Версия 2: Разделение на фронт + бэк (v3.x - v4.0.6)
**Что было сделано:**
1. HTML извлечён в `public/original.html`
2. JavaScript извлечён в `public/static/app.js`
3. Backend создан с Hono + D1 Database
4. Добавлена JWT аутентификация
**Проблемы:**
- ❌ Кнопки требовали admin роль, но Public User не мог их видеть
- ❌ Backend требовал JWT токен (authMiddleware)
- ❌ Frontend показывал только для `body.role-admin`
### Версия 3: Текущая (v4.0.7)
**Что исправлено:**
- ✅ Backend: `authMiddleware``optionalAuthMiddleware` (13 endpoints)
- ✅ Backend: `userId || null` для audit_log
- ✅ Backend: Все PATCH/POST/PUT/DELETE работают без токена
- ✅ Default month: Изменён на January (1) где есть демо-данные
- ✅ Cache busting: Добавлен `?v=4.0.6` к app.js
**Что НЕ ИСПРАВЛЕНО:**
- ❌ Frontend: Кнопка "Lisa uus rida" всё ещё скрыта для Public User
- ❌ Frontend: `openModal()` проверяет `role === 'admin'` и блокирует
- ❌ CSS: `.admin-only-block { display: none }` скрывает кнопки
---
## 🎯 ТЕКУЩЕЕ СОСТОЯНИЕ КЛИКОВ
### ✅ Что РАБОТАЕТ
#### 1. Клики по ячейкам таблицы (Date Toggle)
```html
<td onclick="toggleDate(1, 'cutting', '2025-01-10')">
```
**Функция:**
```javascript
async function toggleDate(recordId, field, date) {
await axios.patch(`/api/records/${recordId}/status`, { field, date });
await loadRecords();
}
```
**Status:** ✅ РАБОТАЕТ (без токена, optionalAuthMiddleware)
#### 2. Клики по Worksheets Cycle
```html
<button onclick="toggleWorksheetsStep(1)">
```
**Функция:**
```javascript
async function toggleWorksheetsStep(recordId) {
await axios.patch(`/api/records/${recordId}/worksheets-cycle`);
await loadRecords();
}
```
**Status:** ✅ РАБОТАЕТ (без токена)
#### 3. Фильтры (Month/Year)
```html
<select id="monthFilter">
```
**Event Listener:**
```javascript
document.getElementById('monthFilter').addEventListener('change', loadRecords);
```
**Status:** ✅ РАБОТАЕТ
#### 4. Поиск (Search Inputs)
```html
<input id="searchClient">
```
**Event Listener:**
```javascript
document.getElementById('searchClient').addEventListener('input', handleSearchFilter);
```
**Status:** ✅ РАБОТАЕТ
### ❌ Что НЕ РАБОТАЕТ
#### 1. Кнопка "Lisa uus rida" (Add Record)
```html
<div class="admin-only-block">
<button onclick="openModal()">Lisa uus rida</button>
</div>
```
**CSS:**
```css
.admin-only-block { display: none; }
body.role-admin .admin-only-block { display: block; }
```
**Проблема:** Кнопка СКРЫТА для Public User
**Функция:**
```javascript
function openModal() {
if (!token || !currentUser || currentUser.role !== 'admin') {
alert('Ainult administraator saab lisada uusi kirjeid');
openLoginModal();
return; // ❌ БЛОКИРУЕТ для Public User
}
document.getElementById('recordModal').classList.add('active');
}
```
**Status:**НЕ РАБОТАЕТ (скрыта + блокируется)
#### 2. Edit Record Button
```html
<button onclick="editRecord(1)">
```
**Функция:**
```javascript
function editRecord(recordId) {
if (!token || !currentUser || currentUser.role !== 'admin') {
alert('Ainult administraator saab muuta kirjeid');
openLoginModal();
return; // ❌ БЛОКИРУЕТ
}
// ... load and edit
}
```
**Status:** ❌ ЧАСТИЧНО (видна, но блокируется)
#### 3. Delete Record Button
```html
<button onclick="confirmDelete(1)" class="delete-btn">
```
**CSS:**
```css
.delete-btn { display: none; }
```
**JavaScript Toggle:**
```javascript
function toggleDeleteButtons() {
const isAdmin = currentUser?.role === 'admin';
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.style.display = isAdmin ? 'inline-block' : 'none';
});
}
```
**Status:**НЕ РАБОТАЕТ (скрыта для Public User)
---
## 🔧 КОРНЕВАЯ ПРИЧИНА
### Несоответствие Frontend ↔ Backend
**Backend (v4.0.6):**
```typescript
// ✅ Разрешает публичный доступ
app.post('/api/records', optionalAuthMiddleware, async (c) => {
// userId может быть null для Public User
})
```
**Frontend (app.js):**
```javascript
// ❌ Блокирует публичный доступ
function openModal() {
if (currentUser.role !== 'admin') {
alert('Только администратор...');
return; // БЛОК!
}
}
```
**CSS:**
```css
/* ❌ Скрывает кнопки для Public User */
.admin-only-block { display: none; }
body.role-admin .admin-only-block { display: block; }
```
---
## 📊 СРАВНЕНИЕ: Оригинал vs Текущий
| Функция | Оригинал | Текущий v4.0.7 | Причина проблемы |
|---------|----------|----------------|------------------|
| Toggle Date | ✅ Работает | ✅ Работает | Backend: optionalAuth |
| Worksheets | ✅ Работает | ✅ Работает | Backend: optionalAuth |
| Add Record | ✅ Работает | ❌ Скрыта | CSS: admin-only-block |
| Edit Record | ✅ Работает | ❌ Блокируется | JS: role check |
| Delete Record | ✅ Работает | ❌ Скрыта | JS: toggleDeleteButtons |
| Filters | ✅ Работает | ✅ Работает | No auth needed |
| Search | ✅ Работает | ✅ Работает | No auth needed |
---
## 🎯 ЧТО НУЖНО ИСПРАВИТЬ
### Проблема 1: Кнопка "Lisa uus rida" скрыта
**Файл:** `public/original.html`
**Сейчас:**
```html
<div class="admin-only-block">
<button onclick="openModal()">Lisa uus rida</button>
</div>
```
**Исправить на:**
```html
<div>
<button onclick="openModal()">Lisa uus rida</button>
</div>
```
### Проблема 2: openModal() блокирует Public User
**Файл:** `public/static/app.js`
**Сейчас:**
```javascript
function openModal() {
if (!token || !currentUser || currentUser.role !== 'admin') {
alert('Ainult administraator...');
openLoginModal();
return;
}
// ...
}
```
**Исправить на:**
```javascript
function openModal() {
// Allow all users to open modal
editingRecordId = null;
document.getElementById('modalTitle').textContent = 'Lisa uus kirje';
document.getElementById('recordForm').reset();
document.getElementById('recordModal').classList.add('active');
updateMat2State();
}
```
### Проблема 3: editRecord() блокирует Public User
**Исправить на:**
```javascript
function editRecord(recordId) {
// Allow all users to edit
editingRecordId = recordId;
// ... load and show modal
}
```
### Проблема 4: Delete buttons скрыты
**Файл:** `public/static/app.js`
**Сейчас:**
```javascript
function toggleDeleteButtons() {
const isAdmin = currentUser?.role === 'admin';
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.style.display = isAdmin ? 'inline-block' : 'none';
});
}
```
**Исправить на:**
```javascript
function toggleDeleteButtons() {
// Show delete buttons for all users
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.style.display = 'inline-block';
});
}
```
---
## ✅ ИТОГО
**РЕАЛЬНО РАБОТАЕТ:**
- ✅ Клики по ячейкам таблицы (toggleDate)
- ✅ Worksheets cycle button
- ✅ Фильтры (month/year)
- ✅ Поиск (client/type/offer/work)
- ✅ Сортировка (sortRecords)
- ✅ Backend API (26/26 endpoints с optionalAuth)
**НЕ РАБОТАЕТ (причина - Frontend блокировки):**
- ❌ Кнопка "Lisa uus rida" - СКРЫТА (admin-only-block CSS)
- ❌ openModal() - БЛОКИРУЕТСЯ (role check в JS)
- ❌ editRecord() - БЛОКИРУЕТСЯ (role check в JS)
- ❌ Delete buttons - СКРЫТЫ (toggleDeleteButtons)
**ПРИЧИНА:**
Backend был сделан публичным (optionalAuthMiddleware), но **Frontend всё ещё требует admin роль**.
**РЕШЕНИЕ:**
Убрать все проверки `role === 'admin'` из app.js и удалить класс `admin-only-block` у кнопок.