Revízny systém - kompletná implementácia

- Backend: CRUD revízií, schedule endpoint (agregovaný plán), skip revízia, stats
- Shared utility revisionSchedule.ts - centralizovaná logika výpočtu cyklov
- Equipment detail s revíznym plánom, históriou a prílohami
- Frontend: RevisionsList s tabmi (nadchádzajúce/po termíne/vykonané/preskočené)
- Pozičné labeling cyklov (eliminuje drift 4×90≠365)
- EquipmentRevisionSchedule model (many-to-many typy revízií)
- Aktualizovaná dokumentácia HELPDESK_INIT_V2.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 21:59:23 +01:00
parent 2ca0c4f4d8
commit da265ff097
28 changed files with 4587 additions and 149 deletions

View File

@@ -6,7 +6,7 @@
**Verzia:** 2.0.0
**Účel:** Komplexný systém pre správu zákaziek, úloh, projektov, revíznych kontrol a reklamácií s dôrazom na flexibilitu a konfigurovateľnosť
**Jazyk UI:** Slovenčina
**Dátum:** 02.02.2026
**Dátum:** 23.02.2026
---
@@ -232,12 +232,13 @@ model RevisionType {
description String?
order Int @default(0)
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
revisions Revision[]
revisions Revision[]
equipmentSchedules EquipmentRevisionSchedule[]
@@index([active])
@@index([order])
}
@@ -646,24 +647,26 @@ model Equipment {
partNumber String? // PN
serialNumber String? // SN
installDate DateTime?
warrantyEnd DateTime?
warrantyStatus String? // "ACTIVE", "EXPIRED", "EXTENDED"
installDate DateTime?
revisionCycleStart DateTime? // Anchor pre výpočet revíznych cyklov (default = installDate)
warrantyEnd DateTime?
warrantyStatus String? // "ACTIVE", "EXPIRED", "EXTENDED"
description String? @db.Text
notes String? @db.Text
active Boolean @default(true)
createdById String
createdBy User @relation("EquipmentCreator", fields: [createdById], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
revisions Revision[]
attachments EquipmentAttachment[]
tags EquipmentTag[]
revisions Revision[]
revisionSchedules EquipmentRevisionSchedule[] // Priradené typy revízií
attachments EquipmentAttachment[]
tags EquipmentTag[]
@@index([typeId])
@@index([customerId])
@@ -672,37 +675,57 @@ model Equipment {
@@index([createdById])
}
// Priradenie revíznych typov k zariadeniu (many-to-many)
model EquipmentRevisionSchedule {
id String @id @default(cuid())
equipmentId String
equipment Equipment @relation(fields: [equipmentId], references: [id], onDelete: Cascade)
revisionTypeId String
revisionType RevisionType @relation(fields: [revisionTypeId], references: [id])
createdAt DateTime @default(now())
@@unique([equipmentId, revisionTypeId])
@@index([equipmentId])
@@index([revisionTypeId])
}
model Revision {
id String @id @default(cuid())
equipmentId String
equipment Equipment @relation(fields: [equipmentId], references: [id], onDelete: Cascade)
// Type relation (namiesto enum)
typeId String
type RevisionType @relation(fields: [typeId], references: [id])
status String @default("performed") // "performed" | "skipped"
performedDate DateTime
nextDueDate DateTime? // Auto-calculated: performedDate + type.intervalDays
nextDueDate DateTime? // Auto-calculated z cyklového anchoru
performedById String
performedBy User @relation(fields: [performedById], references: [id])
findings String? @db.Text
result String? // "OK", "MINOR_ISSUES", "CRITICAL"
notes String? @db.Text
skipReason String? // Dôvod preskočenia (ak status = "skipped")
reminderSent Boolean @default(false)
reminderDate DateTime? // Auto-calculated: nextDueDate - type.reminderDays
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([equipmentId])
@@index([typeId])
@@index([performedById])
@@index([nextDueDate])
@@index([reminderDate])
@@index([status])
}
model EquipmentAttachment {
@@ -1008,25 +1031,43 @@ POST /api/customers/import // Import z externej DB
### **🆕 Equipment**
```
GET /api/equipment
POST /api/equipment
GET /api/equipment/:id
PUT /api/equipment/:id
DELETE /api/equipment/:id
GET /api/equipment/:id/revisions
POST /api/equipment/:id/revisions
POST /api/equipment/:id/attachments
GET /api/equipment/reminders // Upcoming revisions
GET /api/equipment // Zoznam zariadení (stránkovaný, search, filtre)
POST /api/equipment // Vytvorenie zariadenia + revisionSchedules
GET /api/equipment/reminders // Upcoming revisions (PRED /:id!)
GET /api/equipment/:id // Detail zariadenia
PUT /api/equipment/:id // Úprava zariadenia + revisionSchedules
DELETE /api/equipment/:id // Soft delete (deaktivácia)
GET /api/equipment/:id/schedule // Revízny plán zariadenia (nadchádzajúce dátumy)
GET /api/equipment/:id/revisions // História revízií zariadenia
POST /api/equipment/:id/revisions // Pridanie revízie cez equipment detail
GET /api/equipment/:id/files // Zoznam príloh
POST /api/equipment/:id/files // Upload príloh (max 10)
DELETE /api/equipment/:id/files/:fileId // Zmazanie prílohy
```
### **🆕 Revisions**
```
GET /api/revisions
GET /api/revisions/upcoming
GET /api/revisions/overdue
PUT /api/revisions/:id
DELETE /api/revisions/:id
GET /api/revisions // Zoznam revízií (stránkovaný, status filter, search)
GET /api/revisions/stats // Štatistiky: { upcoming, overdue, performed, skipped }
GET /api/revisions/schedule // Agregovaný plán zo VŠETKÝCH zariadení (view=upcoming|overdue)
POST /api/revisions/skip // Preskočenie plánovanej revízie (s dôvodom)
GET /api/revisions/:id // Detail revízie
POST /api/revisions // Vytvorenie revízie
PUT /api/revisions/:id // Úprava revízie
DELETE /api/revisions/:id // Zmazanie revízie
```
**Query parametre pre `/schedule`:** `view` (upcoming|overdue), `typeId`, `customerId`, `search`, `page`, `limit`
**Body pre `/skip`:**
```json
{
"equipmentId": "string",
"typeId": "string",
"scheduledDate": "ISO date string",
"skipReason": "string (optional)"
}
```
### **🆕 RMA**
@@ -1135,6 +1176,70 @@ GET /api/logs/:entityType/:entityId
---
## 🔧 Revízny Systém - Architektúra
### Princípy
1. **Cyklový anchor** - Revízne termíny sú ukotvené na `revisionCycleStart` (alebo `installDate`). Cyklus sa NEposúva keď sa revízia vykoná po termíne.
2. **Pozičné labeling** - Cyklové body sa generujú LEN z najkratšieho intervalu (napr. štvrťročný = 90 dní). Pozícia v ročnom cykle určuje label: 1., 2., 3. Štvrťročná, alebo Ročná pri 4. pozícii. Toto eliminuje drift problém (4×90≠365).
3. **Pokrývajúce typy** - Dlhší interval pokrýva kratší (ročná pokrýva štvrťročnú). Po ročnej revízii sa nextDueDate počíta z najkratšieho intervalu.
4. **Skip mechanizmus** - Plánovaná revízia sa dá preskočiť s dôvodom. Vytvorí sa záznam so `status: "skipped"`.
### Seed dáta - Typy revízií
```
MONTHLY - Mesačná revízia (30 dní, reminder 7 dní)
QUARTERLY - Štvrťročná revízia (90 dní, reminder 14 dní)
BIANNUAL - Polročná revízia (180 dní, reminder 21 dní)
ANNUAL - Ročná revízia (365 dní, reminder 30 dní)
BIENNIAL - Dvojročná revízia (730 dní, reminder 60 dní)
TRIENNIAL - Trojročná revízia (1095 dní, reminder 90 dní)
QUADRENNIAL - Štvorročná revízia (1460 dní, reminder 90 dní)
QUINQUENNIAL - Päťročná revízia (1825 dní, reminder 90 dní)
EMERGENCY - Mimoriadna revízia (0 dní, bez opakovania)
```
### Seed dáta - Typy zariadení
```
EPS - Elektrická požiarna signalizácia
HSP - Hlasová signalizácia požiaru
EZS - Elektronický zabezpečovací systém
BLESKOZVOD - Bleskozvod
```
### Shared utility: `backend/src/utils/revisionSchedule.ts`
Centralizovaná logika zdieľaná medzi `equipment.controller.ts` a `revisions.controller.ts`:
| Funkcia | Popis |
|---------|-------|
| `calculateNextDueDateFromInstall()` | Výpočet nasledujúceho termínu z anchor dátumu a intervalu |
| `detectSkippedCycles()` | Detekcia preskočených cyklových bodov |
| `computeFirstUpcomingCycleDate()` | Prvý nadchádzajúci cyklový bod po dátume |
| `getCoveringTypeIds()` | Nájde typy s dlhším intervalom (pokrývajúce) |
| `calculateReminderDate()` | Dátum pripomienky = nextDueDate - reminderDays |
| `getShortestIntervalForEquipment()` | Najkratší interval zo všetkých plánov zariadenia |
| `computeNextDueAndReminder()` | Kompletný výpočet nextDueDate + reminderDate |
| `mergeOverlappingItems()` | Zlúčenie prekrývajúcich sa termínov rôznych typov |
### Equipment Schedule (`GET /api/equipment/:id/schedule`)
Vracia:
- `schedules` - Stav každého priradeného revízneho typu (posledná revízia, nasledujúci termín)
- `upcomingDates` - Nadchádzajúce dátumy s pozičným labelom (lookAhead = 365 dní)
- `revisionHistory` - Posledných N vykonaných/preskočených revízií
### Revisions Schedule (`GET /api/revisions/schedule`)
Agregovaný plán zo VŠETKÝCH zariadení. Pre každý equipment+revisionType pár:
- Ak existuje posledná revízia → `dueDate = latestRevision.nextDueDate`
- Ak neexistuje → vypočíta sa prvý cyklový bod po dnešku z anchoru
Filtrovateľné podľa: `view` (upcoming/overdue), `typeId`, `customerId`, `search`
---
## 🎨 Frontend Komponenty
### Rozšírená Štruktúra
@@ -1192,11 +1297,13 @@ src/
│ │
│ ├── equipment/ # NEW
│ │ ├── EquipmentList.tsx
│ │ ├── EquipmentDetail.tsx
│ │ ├── EquipmentForm.tsx
│ │ ── RevisionForm.tsx
│ │ ├── RevisionCalendar.tsx
│ └── EquipmentCard.tsx
│ │ ├── EquipmentDetail.tsx # Detail s revíznym plánom, históriou, prílohami
│ │ ├── EquipmentForm.tsx # Formulár s revisionSchedules (typ revízií)
│ │ ── RevisionForm.tsx
│ │
├── revisions/ # NEW
│ │ ├── RevisionsList.tsx # Hlavný zoznam s tabmi (upcoming/overdue/performed/skipped)
│ │ └── RevisionForm.tsx # Formulár pre pridanie/editáciu revízie
│ │
│ ├── rma/ # NEW
│ │ ├── RMAList.tsx
@@ -1233,6 +1340,19 @@ src/
│ │ └── Toast.tsx
│ │
│ └── ui/ (shadcn/ui)
├── hooks/
│ ├── useRevisionStatus.ts # Hook pre stav revízie (schedule/performed/skipped)
│ └── useSnoozeOptions.ts
├── services/
│ ├── equipment.api.ts
│ ├── revisions.api.ts # API pre revízie (CRUD, schedule, skip, stats)
│ ├── settings.api.ts
│ └── ...
└── types/
└── index.ts # Obsahuje Revision, RevisionScheduleItem, RevisionStats
```
---
@@ -1254,7 +1374,7 @@ src/
- [x] Task CRUD (s fallback pre default status/priority)
- [x] Task Comments (s kontrolou oprávnení - len autor/priradený)
- [x] **Customer CRUD**
- [x] **Equipment CRUD** (bez revízií zatiaľ)
- [x] **Equipment CRUD** (s revíznymi plánmi a prílohami)
- [x] **RMA CRUD** (basic, bez workflow)
- [x] **Settings API** (CRUD pre všetky config tables)
- [x] **Dashboard API** (`/dashboard`, `/dashboard/today`, `/dashboard/stats`)
@@ -1295,7 +1415,7 @@ src/
✅ Priradenie používateľov na úlohy (multi-select)
✅ Dashboard s mojimi úlohami a projektmi + urgentné úlohy
✅ Zákazníci
✅ Zariadenia (bez revízií)
✅ Zariadenia (s revíznymi plánmi)
✅ RMA (bez workflow)
✅ ROOT môže konfigurovať všetko cez Settings
✅ Žiadne hardcoded ENUMs
@@ -1329,10 +1449,15 @@ cd backend && npx prisma db seed
**Cieľ:** Swimlanes, revízie, RMA workflow, reminders, notifikácie
**Backend:**
- [ ] **Revision system**
- [ ] Create revision endpoint
- [ ] Auto-calculate nextDueDate
- [ ] Reminder scheduler
- [x] **Revision system**
- [x] CRUD endpoints (create, read, update, delete)
- [x] Auto-calculate nextDueDate (cyklový anchor, pozičné labeling)
- [x] Skip revision endpoint (preskočenie s dôvodom)
- [x] Agregovaný schedule endpoint (zo všetkých zariadení)
- [x] Stats endpoint (upcoming, overdue, performed, skipped)
- [x] Shared utility `revisionSchedule.ts`
- [x] Equipment schedule endpoint (nadchádzajúce dátumy s labelmi)
- [ ] Reminder scheduler (cron job na posielanie pripomienok)
- [ ] **RMA workflow**
- [ ] Status transitions validation
- [ ] Approval flow (customer RMAs)
@@ -1358,10 +1483,19 @@ cd backend && npx prisma db seed
- [ ] Drag & Drop
- [ ] Collapse/expand
- [ ] Progress indicators
- [ ] **Equipment Management**
- [ ] Revision form
- [ ] Revision calendar view
- [ ] Reminder notifications
- [x] **Equipment Management**
- [x] EquipmentList - zoznam zariadení s filtrami
- [x] EquipmentForm - formulár s revisionSchedules
- [x] EquipmentDetail - detail s revíznym plánom, históriou, prílohami
- [x] RevisionForm - formulár pre pridanie/editáciu revízie
- [x] Revízny plán s pozičným labelingom
- [x] File attachments
- [x] **Revisions Management**
- [x] RevisionsList - tabmi (nadchádzajúce, po termíne, vykonané, preskočené)
- [x] Filtrovacie tlačidlá podľa typu revízie
- [x] Preskočenie revízie s dôvodom
- [x] Vykonanie revízie z plánu (predvyplnený formulár)
- [x] useRevisionStatus hook
- [ ] **RMA Workflow**
- [ ] Status change UI
- [ ] Approval buttons (admin)
@@ -1387,7 +1521,8 @@ cd backend && npx prisma db seed
```
✅ Všetko z Fázy 1 +
⏳ Swimlanes board
Revízny systém funguje
Revízny systém (CRUD, plán, skip, schedule, stats)
✅ Equipment management (detail, plán, história, prílohy)
⏳ RMA workflow s approval
⏳ Email notifikácie
⏳ Live updates (WebSocket)