Update project overview and clarify date handling rules

Update the project overview section in README.md and introduce mandatory rules for handling date/timezone conversions to prevent bugs, with specific examples and references to affected files and previous commits.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: e5565357-90e1-419f-b9a8-6ee8394636df
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e5565357-90e1-419f-b9a8-6ee8394636df/1nTItRR
This commit is contained in:
marco370 2025-10-23 09:05:47 +00:00
parent bd4a55e001
commit eef9b6027d
2 changed files with 21 additions and 131 deletions

View File

@ -19,10 +19,6 @@ externalPort = 80
localPort = 33035
externalPort = 3001
[[ports]]
localPort = 38781
externalPort = 5173
[[ports]]
localPort = 41295
externalPort = 6000

148
replit.md
View File

@ -1,7 +1,7 @@
# VigilanzaTurni - Sistema Gestione Turni per Istituti di Vigilanza
## Overview
VigilanzaTurni is a professional 24/7 shift management system designed for security companies. It offers multi-role authentication (Admin, Coordinator, Guard, Client), comprehensive guard and site management, 24/7 shift planning, a live operational dashboard with KPIs, reporting for worked hours, and a notification system. The system supports multi-location operations (Roccapiemonte, Milano, Roma) managing 250+ security personnel across different branches. The project aims to streamline operations and enhance efficiency for security institutes.
VigilanzaTurni is a professional 24/7 shift management system for security companies, designed to streamline operations and enhance efficiency. It supports multi-role authentication (Admin, Coordinator, Guard, Client) and multi-location operations, managing over 250 security personnel across different branches (Roccapiemonte, Milano, Roma). Key capabilities include comprehensive guard and site management, 24/7 shift planning, a live operational dashboard with KPIs, reporting for worked hours, and a notification system.
## User Preferences
- Interfaccia in italiano
@ -10,43 +10,6 @@ VigilanzaTurni is a professional 24/7 shift management system designed for secur
- Focus su efficienza e densità informativa
- **Testing**: Tutti i test vengono eseguiti ESCLUSIVAMENTE sul server esterno (vt.alfacom.it) con autenticazione locale (non Replit Auth)
## ⚠️ CRITICAL: Date/Timezone Handling Rules
**PROBLEMA RICORRENTE**: Quando si assegna una guardia per il giorno X, appare assegnata al giorno X±1 a causa di conversioni timezone.
**REGOLE OBBLIGATORIE** per evitare questo bug:
1. **MAI usare `parseISO()` su date YYYY-MM-DD**
- ❌ SBAGLIATO: `const date = parseISO("2025-10-20")` → converte in UTC causando shift
- ✅ CORRETTO: `const [y, m, d] = "2025-10-20".split("-").map(Number); const date = new Date(y, m-1, d)`
2. **Costruire Date da componenti, NON da stringhe ISO**
```typescript
// ✅ CORRETTO - date components (no timezone conversion)
const [year, month, day] = startDate.split("-").map(Number);
const shiftDate = new Date(year, month - 1, day);
const shiftStart = new Date(year, month - 1, day, startHour, startMin, 0, 0);
// ❌ SBAGLIATO - parseISO o new Date(string ISO)
const date = parseISO(startDate); // converte in UTC!
const date = new Date("2025-10-20"); // timezone-dependent!
```
3. **Validazione date: usare regex, NON parseISO**
```typescript
// ✅ CORRETTO
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(dateStr)) { /* invalid */ }
// ❌ SBAGLIATO
const parsed = parseISO(dateStr);
if (!isValid(parsed)) { /* invalid */ }
```
4. **File da verificare sempre**: `server/routes.ts` - tutte le route che ricevono date dal frontend
5. **Testare sempre**: Assegnare guardia giorno X → verificare appaia nel giorno X (non X±1)
**RIFERIMENTI FIX**: Vedere commit "Fix timezone bug in shift creation" - linee 1148-1184, 615-621, 753-759 in server/routes.ts
## System Architecture
### Stack Tecnologico
@ -65,94 +28,29 @@ VigilanzaTurni is a professional 24/7 shift management system designed for secur
- **Componenti**: Shadcn UI with an operational design.
### Database Schema
The database includes core tables for `users`, `guards`, `certifications`, `sites`, `shifts`, `shift_assignments`, and `notifications`. Advanced scheduling and constraints are managed via `guard_constraints`, `site_preferences`, `contract_parameters`, `training_courses`, `holidays`, `holiday_assignments`, `absences`, and `absence_affected_shifts`. All tables include appropriate foreign keys and unique constraints to maintain data integrity.
The database includes tables for `users`, `guards`, `certifications`, `sites`, `shifts`, `shift_assignments`, `notifications`, `customers`, and various tables for advanced scheduling and constraints (`guard_constraints`, `site_preferences`, `contract_parameters`, `training_courses`, `holidays`, `holiday_assignments`, `absences`, `absence_affected_shifts`). Service types include specialized parameters like `fixedPostHours`, `patrolPassages`, `inspectionFrequency`, and `responseTimeMinutes`. Sites support multi-location (`location` field) and contract management (`contractReference`, `contractStartDate`, `contractEndDate`).
**Recent Schema Updates (October 2025)**:
- Service types now include specialized parameters: `fixedPostHours` (ore presidio fisso), `patrolPassages` (numero passaggi pattuglia), `inspectionFrequency` (frequenza ispezioni), `responseTimeMinutes` (tempo risposta pronto intervento)
- Sites include service schedule fields: `serviceStartTime` and `serviceEndTime` (formato HH:MM)
- **Contract Management**: Sites now include contract fields: `contractReference` (codice contratto), `contractStartDate`, `contractEndDate` (date validità contratto in formato YYYY-MM-DD)
- Sites now reference service types via `serviceTypeId` foreign key; `shiftType` is optional and can be derived from service type
- **Multi-Location Support**: Added `location` field (enum: roccapiemonte, milano, roma) to `sites`, `guards`, and `vehicles` tables for complete multi-sede resource isolation
- **Customer Management (October 23, 2025)**: Added `customers` table with `sites.customerId` foreign key for customer-centric organization. Customers include: name, business name, VAT/fiscal code, address, city, province, ZIP, phone, email, PEC, contact person, notes, active status.
**Recent Features (October 23, 2025)**:
- **Customer Management (Anagrafica Clienti)**: New `/customers` page with full CRUD operations:
- Comprehensive customer form: name, business name, VAT/fiscal code, address, contacts (phone/email/PEC), referent, notes
- Customer status toggle (active/inactive)
- Delete confirmation with cascade considerations
- Sidebar menu entry for admin/coordinator roles
- Backend: Full CRUD routes with validation
- **Reports per Cliente**: New customer-centric billing reports replacing site-based approach:
- Backend endpoint `/api/reports/customer-billing` aggregating by customer → sites → service types
- Separate counters based on service type:
* Presidio Fisso → Hours worked
* Pattuglia/Ronda → Number of passages (from `serviceType.patrolPassages`)
* Ispezione → Number of inspections counted
* Pronto Intervento → Number of interventions counted
- Frontend: "Report Clienti" tab with 5 KPI cards (customers, hours, passages, inspections, interventions)
- Hierarchical display: Customer header → Sites list → Service type details with conditional badges
- CSV export with 8 columns: Cliente, Sito, Tipologia Servizio, Ore, Turni, Passaggi, Ispezioni, Interventi
- Maintains existing "Report Guardie" and "Report Siti" tabs for compatibility
**Recent Features (October 17-18, 2025)**:
- **Multi-Sede Operational Planning**: Redesigned operational planning workflow with location-first approach:
1. Select sede (Roccapiemonte/Milano/Roma) - first step with default value
2. Select date
3. View uncovered sites filtered by selected sede
4. Select site → view available resources (guards and vehicles) filtered by sede
5. Assign resources and create shift
- **Location-Based Filtering**: Backend endpoints use INNER JOIN with sites table to ensure complete resource isolation between locations - guards/vehicles in one sede remain available even when assigned to shifts in other sedi
- **Site Management**: Added sede selection in site creation/editing forms with visual badges showing location in site listings
- **Planning Fissi (October 18, 2025)**: New weekly planning overview feature showing all sites × 7 days in table format:
- **Contract filtering**: Shows only sites with active contracts in the week dates (`contractStartDate <= weekEnd AND contractEndDate >= weekStart`)
- Backend endpoint `/api/general-planning?weekStart=YYYY-MM-DD&location=sede` with complex joins and location filtering
- Automatic missing guards calculation: `ceil(totalShiftHours / maxHoursPerGuard) × minGuards - assignedGuards` (e.g., 24h shift, 2 guards min, 9h max = 6 total needed)
- **Weekly summary**: Shows total guards needed, guards assigned (counting slots, not unique people), and guards missing for the entire week
- Table cells display: assigned guards with hours, vehicles, missing guards badge (if any), shift count, total hours
- Interactive cells with click handler opening detail dialog
- Dialog shows: shift count, total hours, guard list with hours and badge numbers, vehicle list, missing guards warning with explanation
- **Direct Shift Creation from Dialog**: Users can now create multi-day shifts directly from the Planning Generale dialog:
- Select guard from dropdown showing name + weekly available hours (max 45h - assigned hours)
- Specify number of consecutive days (1-7)
- Backend endpoint `POST /api/general-planning/shifts` with atomic transaction using `db.transaction()` - all shifts created or none (rollback on error)
- Validates contract dates, site and guard existence before transaction
- Automatically creates shifts spanning multiple days with correct time ranges from site service schedule
- TanStack Query mutation with cache invalidation for real-time planning grid updates
- "Modifica in Pianificazione Operativa" button in dialog navigates to operational planning page with pre-filled date/location parameters
- Week navigation (previous/next week) with location selector
- Operational planning page now supports query parameters (`?date=YYYY-MM-DD&location=sede`) for seamless integration
**Recent Bug Fixes (October 17-18, 2025)**:
- **Operational Planning Date Handling**: Fixed date sanitization in `/api/operational-planning/uncovered-sites` and `/api/operational-planning/availability` endpoints to handle malformed date inputs (e.g., "2025-10-17/2025-10-17"). Both endpoints now validate dates using `parseISO`/`isValid` and return 400 for invalid formats.
- **Checkbox Event Propagation**: Fixed double-toggle bug in operational planning resource selection by wrapping vehicle and guard checkboxes in `<div onClick={e => e.stopPropagation()}>` to prevent Card onClick from firing when clicking checkboxes.
- **Multi-Sede Resource Isolation**: Fixed critical bug where resources from different sedi were incorrectly marked as unavailable due to global shift queries. Now both availability and uncovered-sites endpoints filter shifts by location using JOIN with sites table.
- **QueryKey Cache Invalidation**: Fixed queryKey structure from single-string to hierarchical array with custom queryFn to enable targeted cache invalidation by location and date while preventing URL concatenation errors.
- **apiRequest Parameter Order (October 18, 2025)**: Fixed inverted parameters bug in Planning Generale shift creation mutation. Changed `apiRequest(url, method, data)` to correct signature `apiRequest(method, url, data)` matching queryClient.ts function definition.
### API Endpoints
Comprehensive RESTful API endpoints are provided for Authentication, Users, Guards, Sites, Shifts, and Notifications, supporting full CRUD operations with role-based access control.
### Frontend Routes
Key frontend routes include `/`, `/guards`, `/sites`, `/shifts`, `/reports`, `/notifications`, and `/users`, with access controlled by user roles.
### Core Features
- **Multi-Sede Operational Planning**: Location-first approach for shift planning, filtering sites, guards, and vehicles by selected branch.
- **Service Type Classification**: Service types are classified as "fisso" (fixed posts) or "mobile" (patrols, inspections) to route sites to appropriate planning modules (Planning Fissi, Planning Mobile).
- **Planning Fissi**: Weekly planning grid showing all sites with active contracts, allowing direct shift creation for multiple days with guard availability checks.
- **Planning Mobile**: Dedicated guard-centric interface for mobile services, displaying guard availability and hours for mobile-classified sites. Includes a map placeholder for future integration.
- **Customer Management**: Full CRUD operations for customers with comprehensive details.
- **Customer-Centric Reports**: New reports aggregating data by customer, replacing site-based billing, with specific counters for fixed posts (hours), patrols (passages), inspections, and interventions. CSV export is supported.
- **Dashboard Operativa**: Live KPIs and real-time shift status.
- **Gestione Guardie**: Complete profiles with skill matrix, certification management, and unique badge numbers.
- **Gestione Siti/Commesse**: Service types with specialized parameters and minimum requirements. Sites include service schedule, contract management, and location assignment.
- **Pianificazione Turni**: 24/7 calendar, manual guard assignment, basic constraints, and shift statuses.
- **Advanced Planning**: Management of guard constraints, site preferences, contract parameters, training courses, holidays, and absences.
### User Roles
- **Admin**: Full access to all functionalities, managing guards, sites, shifts, and reports.
- **Coordinator**: Shift planning, guard assignment, operational site management, and reporting.
- **Guard**: View assigned shifts, future time-punching, notifications, and personal profile.
- **Client**: View assigned sites, service reporting, and KPIs.
- **Admin**: Full access.
- **Coordinator**: Shift planning, guard assignment, operational site management, reporting.
- **Guard**: View assigned shifts, time-punching, notifications, personal profile.
- **Client**: View assigned sites, service reporting, KPIs.
### Key Features
- **Dashboard Operativa**: Live KPIs (active shifts, total guards, active sites, expiring certifications) and real-time shift status.
- **Gestione Guardie**: Complete profiles with skill matrix (armed, fire safety, first aid, driver's license), certification management with automatic expiry, and unique badge numbers.
- **Gestione Siti/Commesse**: Service types with specialized parameters (fixed post hours, patrol passages, inspection frequency, response time) and minimum requirements (guard count, armed, driver's license). Sites include service schedule (start/end time), contract management (reference code, validity period with start/end dates), and location/sede assignment. Contract status is visualized with badges (active/expiring/expired) and enforces shift creation only within active contract periods.
- **Pianificazione Operativa Multi-Sede**: Location-aware workflow for shift assignment:
1. Select sede (Roccapiemonte/Milano/Roma) → filters all subsequent data by location
2. Select date → view uncovered sites with coverage status (sede-filtered)
3. Select site → view available resources (guards and vehicles matching sede and requirements)
4. Assign resources → create shift with atomic guard assignments and vehicle allocation
- **Pianificazione Turni**: 24/7 calendar, manual guard assignment, basic constraints, and shift statuses (planned, active, completed, cancelled).
- **Reportistica**: Total hours worked, monthly hours per guard, shift statistics, and data export capabilities.
- **Advanced Planning**: Management of guard constraints (preferences, max hours, rest days), site preferences (preferred/blacklisted guards), contract parameters, training courses, holidays, and absences with substitution system.
### Critical Date/Timezone Handling
To prevent timezone-related bugs, especially when assigning shifts, dates should always be constructed from components (`new Date(year, month-1, day)`) and never parsed from ISO strings directly using `parseISO()` or `new Date(string ISO)`. Date validation should use regex instead of `parseISO()`.
## External Dependencies
- **Replit Auth**: For OpenID Connect (OIDC) based authentication.
@ -162,8 +60,4 @@ Key frontend routes include `/`, `/guards`, `/sites`, `/shifts`, `/reports`, `/n
- **Zod**: For schema validation.
- **TanStack Query**: For data fetching and state management.
- **Wouter**: For client-side routing.
- **date-fns**: For date manipulation and formatting.
- **PM2**: Production process manager for Node.js applications.
- **Nginx**: As a reverse proxy for the production environment.
- **Let's Encrypt**: For SSL/TLS certificates.
- **GitLab CI/CD**: For continuous integration and deployment.
- **date-fns**: For date manipulation and formatting.