- Реструктуризация: 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
307 lines
9.1 KiB
Markdown
307 lines
9.1 KiB
Markdown
# 🔍 ПОЛНЫЙ ОБЗОР ЛОГИКИ КЛИКОВ - 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` у кнопок.
|