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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user