feat: task problem/solution split + maintenance icons on rooms/calendar

- TechnicalPage: redesign task cards with separate "Задача" and "Решение" sections
  - "Задача": problem description + problem photos (editable before done)
  - "Решение": technician resolution comment + resolution photos (green section)
  - Resolution comment in CompletionModal now saves to resolution_notes field
  - Resolution photos save to resolution_photos (no longer mixed with problem photos)
- RoomModal history tab: maintenance entries show separate problem/resolution sections
- Backend: add resolution_notes, resolution_photos to PATCH allowed fields
- Migration 029: resolution_notes TEXT + resolution_photos TEXT[] columns
- RoomsPage: load active maintenance tasks, show 🔧 неисправность badge on room cards
- CalendarPage: load active maintenance tasks, show 🔧 неиспр. label in calendar row
- BookingCalendar: activeMaintenance prop, WS handler updates maintenance set on task changes
- CalendarPage WS: handle housekeeping_task_created to update activeMaintenance set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 11:45:24 +03:00
parent 14f0b8e0f2
commit c83a9ca714
10 changed files with 237 additions and 107 deletions

View File

@@ -16,12 +16,14 @@ import { ru } from 'date-fns/locale'
function normalizeTask(raw: Record<string, unknown>): Record<string, unknown> {
return {
...raw,
roomNumber: raw.roomNumber ?? raw.room_number,
roomId: raw.roomId ?? raw.room_id,
assigneeName: raw.assigneeName ?? raw.assignee_name,
dueDate: raw.dueDate ?? raw.due_date,
completedAt: raw.completedAt ?? raw.completed_at,
startedAt: raw.startedAt ?? raw.started_at,
roomNumber: raw.roomNumber ?? raw.room_number,
roomId: raw.roomId ?? raw.room_id,
assigneeName: raw.assigneeName ?? raw.assignee_name,
dueDate: raw.dueDate ?? raw.due_date,
completedAt: raw.completedAt ?? raw.completed_at,
startedAt: raw.startedAt ?? raw.started_at,
resolutionNotes: raw.resolutionNotes ?? raw.resolution_notes,
resolutionPhotos: raw.resolutionPhotos ?? raw.resolution_photos,
}
}