- Изменено поле document → document_id для соответствия backend
- Изменено поле parent → parent_id для соответствия backend
- Исправлена ошибка 400 при создании комментариев к документам
PROBLEM:
- Upload form was minimal, not using full backend capabilities
- Missing: recipients, departments, acknowledgement requirement
- No folder indication when uploading to specific folder
SOLUTION - BACKEND:
- Added 'acknowledgement_required' field to DocumentWriteSerializer
- Now accepts: sent_to_all, department_ids, recipient_ids, acknowledgement_required
SOLUTION - FRONTEND:
Extended DocumentUploadForm with enterprise-grade features:
NEW FIELDS:
1. Sent to All Toggle
- Checkbox to send document to all employees
- When checked, hides recipients/departments selection
2. Recipients Section (when sent_to_all = false)
- Multi-select for departments (with Building2 icon)
- Multi-select for specific employees (with Users icon)
- Live loading from API
- Validation: requires at least one department OR recipient
- Helper text for Ctrl/Cmd multi-select
3. Acknowledgement Required
- Checkbox to require recipients to acknowledge reading
- Clear explanation of what it means
UX IMPROVEMENTS:
- Folder indicator: shows when uploading to specific folder
- Visual sections with dividers and headers
- Icons for each field type
- Warning when no recipients selected (amber alert)
- Better validation messages
- Reset all new fields on successful upload
API CLIENT:
- Updated createDocument signature to include acknowledgement_required
- Properly serializes checkbox values as strings
DATA LOADING:
- useEffect loads departments and employees on mount
- Loading states during fetch
- Handles empty lists gracefully
VALIDATION:
- Requires file and title (unchanged)
- NEW: When sent_to_all=false, requires departments OR recipients
- Shows user-friendly error messages
BENEFITS:
- Full feature parity with backend capabilities
- Professional document management workflow
- Granular control over document distribution
- Acknowledgement tracking from upload stage
- Better UX with progressive disclosure
Backend changes:
- Add acknowledgement_required field to Document model (migration 0009)
- Add FolderViewSet with CRUD endpoints for folder management
- Add folder_id filtering support in DocumentViewSet.get_queryset()
- Register folders endpoint in API router
Frontend changes:
- Add DocumentAcknowledgementsReport component for viewing acknowledgement status
- Add folder_id parameter to getDocuments API method
- Add currentFolderId prop to DocumentUploadForm
- Update document creation to save to selected folder
- Add folder filtering in documents list view
- Fix PDF worker loading (use local worker instead of CDN)
- Lock pdfjs-dist version to 5.4.296 to prevent conflicts
- Add postinstall script to copy PDF worker to public/
Features:
- Hierarchical folder structure with parent-child relationships
- Filter documents by selected folder
- Upload documents to specific folders
- View acknowledgement statistics with search and export
- Local PDF worker for reliable document preview
- Updated DocumentUploadForm to use processDocument utility
- Added real-time progress tracking with visual feedback
- Display extracted text in editable textarea
- Support compressed file upload
- Added extracted_text field to API client and backend serializer
- Auto-process PDFs, DOCX, and images on file selection
Created comprehensive document processing library:
� src/lib/document-utils/
├── processor.ts - Главный процессор (интеллектуальная обработка)
├── ocr.ts - OCR через Tesseract.js (rus+eng)
├── pdf.ts - PDF операции (extract text, thumbnail, split, merge, rotate)
├── docx.ts - DOCX извлечение текста (mammoth.js)
├── image.ts - Image processing (compress, crop, rotate, thumbnail)
└── index.ts - Экспорты
Возможности:
✅ Автоматическое определение типа файла
✅ OCR для изображений (client-side, не нагружает сервер)
✅ Извлечение текста из PDF и DOCX
✅ Сжатие изображений перед загрузкой
✅ Генерация thumbnails
✅ Progress callbacks для UI
✅ Оценка времени обработки
✅ TypeScript типы для всех функций
Преимущества перед server-side:
- Моментальная обратная связь
- Не нагружает backend
- Приватность (файл не уходит на сервер до загрузки)
- Экономия трафика (сжатие до отправки)
- Можно показать preview extracted text ДО upload
Phase 2 & 3 Complete!
- Убраны поля document_type и tags из DocumentUploadForm
- Обновлен API клиент: createDocument и updateDocument без этих полей
- Обновлены TypeScript типы в api.ts
- Убраны document_type и tags из отображения в documents/page.tsx
- Форма теперь принимает только: title, description, file
Frontend:
- Установлен Sonner для toast уведомлений
- Создан Service Worker (public/sw.js) для Web Push
- Реализован хук useWebPush для управления подписками
- Добавлены утилиты Web Push (lib/push.ts)
- Создан компонент NotificationCenter с UI
- Интегрирован в AppShell (header desktop + mobile)
- Добавлен Toaster в Providers
API методы:
- getVapidPublicKey() - получение VAPID ключа
- subscribePush() - создание подписки
- unsubscribePush() - удаление подписки
- getPushSubscriptions() - список подписок
Возможности:
- � Web Push (работают даже когда вкладка закрыта)
- � NotificationCenter с badge и историей
- � Toast уведомления (Sonner)
- ⚙️ Настройки push подписок
- � Респонсивный дизайн
Документация: frontend/NOTIFICATIONS_IMPLEMENTATION.md
Backend:
- Created REST API endpoint /api/v1/search/
- Added SearchResultSerializer and SearchResponseSerializer
- Implemented search_api_view with model formatters (employee, department, post, request, chat, message, event)
- Registered search endpoint in api/v1/urls.py
- Added permission check for requests (HR can see all, users only their own)
Frontend:
- Added SearchResponse, SearchResult, SearchModelType types
- Added apiClient.search() method in lib/api.ts
- Completely rewrote search/page.tsx:
* Single API call instead of 6 parallel requests
* Cleaner UI with icons for each result type
* Real-time search with loading states
* Meta information display (email, phone, status, etc.)
* Better performance and UX
Benefits:
- Frontend: 220 lines → 178 lines (19% reduction)
- 1 API request instead of 6 (83% less network calls)
- Server-side full-text search via watson (better relevance)
- Unified search results with metadata
Testing:
- API endpoint verified at /api/v1/search/?q=test
- Returns JSON with query, results, counts, total
- Requires authentication (IsAuthenticated decorator)
- Удалено поле last_read_at из ChatReadState, используется только last_read_message FK
- Исправлена логика автоотметки: отмечается последнее ЗАГРУЖЕННОЕ сообщение, а не последнее в чате
- Убран вызов chat.mark_read() при WebSocket open_chat (отмечал последнее в чате вместо загруженного)
- Добавлен signal для мониторинга изменений ChatReadState
- Исправлена логика скролла: убран автоскролл при дозагрузке вниз
- Добавлена проверка разрывов при WebSocket сообщениях (предотвращает пропуск сообщений)
- Реализована автоотметка WebSocket сообщений (только если пользователь внизу)
- Асимметричная загрузка: 24 контекста + 6 новых сообщений
- Добавлен ScrollableMessageList компонент для корректной работы скролла
- Миграции: 0028 (удаление last_read_at), 0029 (индекс на last_read_message)
- Добавлены API методы в api.ts:
* getChats, getChat, createChat
* getChatMessages, sendMessage, sendMessageWithFiles
* updateMessage, deleteMessage
* markChatAsRead, togglePinChat, toggleChatNotifications
- Создан компонент NewChatModal:
* Поиск и выбор сотрудников
* Поддержка приватных и групповых чатов
* Автоматическое название для групп
- Интегрирована кнопка 'Новый чат' в Chatscope UI
- При создании чата автоматически открывается диалог
- Реализована возможность конвертации повторяющегося события в обычное:
* При снятии галочки 'Повторяющееся событие' rule_id сбрасывается в null
* Событие становится одиночным, все occurrence исчезают
- Добавлен метод updateRule() в apiClient:
* Позволяет обновлять существующие правила повторения
* Изменения применяются ко всем occurrence события
* Использует PUT запрос к /api/v1/schedule/rules/{id}/
- Исправлено использование repeatMode:
* Заменен устаревший useCount на repeatMode ('until' | 'count' | 'forever')
* Корректная обработка end_recurring_period только для режима 'until'
- Добавлена универсальная функция normalizeByweekday():
* Решена проблема с разными форматами byweekday с backend:
- Массив: [0, 4] ✓
- Строка: '0,4' ✓
- Число: 4 ✓
* Функция используется во всех компонентах:
- EventModal: авто-выбор дней, отображение кнопок, сохранение
- ViewEventDetailsModal: отображение дней недели
* Исправлены ошибки '.map is not a function' и '.includes is not a function'
- Улучшена логика handleSave() в EventModal:
* Проверка необходимости сброса rule при снятии галочки
* Разделение логики создания и обновления правил
* Нормализация byweekday перед отправкой на backend
Closes: полная поддержка CRUD операций для повторяющихся событий
Backend:
- Расширен get_queryset в ScheduleEventViewSet: теперь пользователь видит события где он участник (EventRelation), даже если не имеет доступа к календарю
- Добавлен action my-events для получения только событий участника
- Исправлена архитектурная проблема: участники событий теперь могут видеть свои события
Frontend:
- Добавлен метод apiClient.getMyEvents() для получения событий пользователя
- Добавлена подсказка в EventModal о логике начала/конца для повторяющихся событий
- Улучшен UX: пользователи понимают что начало/конец применяются ко всем повторениям