# VigilanzaTurni - Sistema Gestione Turni per Istituti di Vigilanza ## Overview 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 - Dark mode di default - Design operativo e funzionale (non decorativo) - 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) ## System Architecture ### Stack Tecnologico - **Frontend**: React + TypeScript + Tailwind CSS + Shadcn UI - **Backend**: Express.js + TypeScript - **Database**: PostgreSQL (Neon) with Drizzle ORM - **Autenticazione**: Replit Auth (OIDC) - **State Management**: TanStack Query v5 - **Routing**: Wouter - **Maps**: Leaflet + react-leaflet + OpenStreetMap tiles ### Design System - **Font Principale**: Inter (sans-serif) - **Font Monospace**: JetBrains Mono - **Colori**: Primary Blue, Status Green, Orange, Red, Gray for various operational states. - **Tema**: Dark mode by default, with light mode support. - **Componenti**: Shadcn UI with an operational design. ### Database Schema The database includes tables for `users`, `guards`, `certifications`, `sites`, `shifts`, `shift_assignments`, `notifications`, `customers`, `service_types`, 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), contract management (`contractReference`, `contractStartDate`, `contractEndDate`), and service type association (`serviceTypeId` FK to `service_types.id`). ### 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 interactive Leaflet map showing sites with GPS coordinates and automatic re-centering based on selected location. - **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**: Sites are associated with service types from the `service_types` table via `serviceTypeId` (FK). Service types are managed in the "Tipologie Servizi" page and include specialized parameters. Sites include service schedule, contract management, location assignment, and customer assignment (`customerId` FK to `customers.id`). - **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. - **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. ### 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()`. ## Recent Changes (October 2025) ### Automatic Geocoding Integration (October 23, 2025) - **Issue**: Users had to manually find and enter GPS coordinates for sites, which was time-consuming and error-prone - **Solution**: - **Backend (`server/routes.ts`)**: - Created POST `/api/geocode` endpoint integrating Nominatim API (OpenStreetMap) - Implemented in-memory rate limiter enforcing 1 request/second to comply with Nominatim usage policy - Added compliant User-Agent header: "VigilanzaTurni/1.0 (Security Shift Management System; contact: support@vigilanzaturni.it)" - Returns latitude, longitude, displayName, and full address object - **Frontend (`client/src/pages/sites.tsx`)**: - Added "📍 Trova Coordinate" button in both create and edit site dialogs - Button auto-populates latitude/longitude fields from address - Disabled state when address missing or geocoding in progress - Toast notifications for success (with found address) and error handling - Dedicated section with bg-muted/50 highlighting for GPS coordinates - **Impact**: Users can now automatically geocode site addresses with a single click, ensuring accurate GPS positioning for Planning Mobile map without manual coordinate lookup ### Planning Mobile - Leaflet Map Integration (October 23, 2025) - **Issue**: Planning Mobile page had errors in backend endpoints and lacked interactive map functionality - **Solution**: - **Backend Fixes**: - Removed non-existent fields (`city` from sites, `isActive` from guards) from queries - Changed `innerJoin` to `leftJoin` for service types to handle sites without serviceTypeId - Fixed `orderBy` syntax (single field instead of multiple) - Added `hasDriverLicense` filter for guards (mobile services require driving) - **Map Integration**: - Implemented Leaflet + react-leaflet with OpenStreetMap tiles (100% free, no API key) - Interactive markers for sites with GPS coordinates and classification="mobile" - Popup details showing site name, address, and service type - Automatic re-centering via `key={selectedLocation}` forcing MapContainer remount - Graceful fallback for sites without coordinates - **Impact**: Planning Mobile now fully functional with interactive map for patrol/inspection route planning ### Planning Mobile - Interactive Features (October 23, 2025) - **Issue**: Planning Mobile needed interactive map controls and patrol route sequencing workflow - **Critical Bug Fix - Geocoding**: - **Problem**: Toast showed "Indirizzo: undefined" when geocoding sites - **Root Cause**: `apiRequest()` returns Response object, not parsed JSON - **Fix**: Added `const result = await response.json()` after apiRequest in both handleGeocode() and handleGeocodeEdit() - **Impact**: Geocoding now correctly displays full address from Nominatim (e.g., "Via Tiburtina, Roma, Lazio, Italia") - **New Features**: - **Zoom-to-Site**: - MapController component with useMap() hook for programmatic map control - Navigation button on each site card triggers flyTo() animation (zoom level 16) - Toast feedback: "Mappa centrata - Visualizzazione di [nome sito]" - **Guard Assignment**: - "Assegna Guardia" button on site cards - Validates guard selection from dropdown - Toast feedback: "[Sito] assegnato a [Nome Cognome Guardia]" - **Patrol Route Sequencing**: - Click markers on map to build patrol route sequence - Visual feedback: Green "Tappa N" badges on markers and site cards - Dedicated UI section showing route in construction with numbered sequence - Remove/clear/save route controls - Auto-reset route when changing guard or location - **Note**: Backend persistence (save to database) not yet implemented - marked as TODO for future development - **Impact**: Operators can now interact with the map, assign guards to sites, and visually plan patrol routes by clicking sites in sequence ### Sites Form Fix - ServiceTypeId Integration (October 2025) - **Issue**: Sites form used hardcoded `shiftType` enum values instead of dynamic service types from the database - **Solution**: - Changed Sites form to use `serviceTypeId` (FK to `service_types.id`) instead of deprecated `shiftType` field - Added dynamic service type dropdown loading from `/api/service-types` endpoint - Updated both create and edit forms to properly handle service type selection - Card display now shows service type label from database instead of hardcoded labels - **Impact**: Sites now correctly reference service types configured in "Tipologie Servizi" page, ensuring consistency across the system ### Advanced Planning System Complete (October 23, 2025) - **Implementation**: Full planning system with guard views, exclusivity constraints, and database persistence - **Features**: - **Patrol Route Database Persistence**: - Backend endpoints: GET/POST/PUT/DELETE `/api/patrol-routes` - Database schema: `patrol_routes` table with `patrol_route_stops` for sequence - Planning Mobile loads existing routes when guard selected, saves to DB - Green markers on map for sites in current patrol route - **Exclusivity Constraint (fisso/mobile)**: - Validation in 3 backend endpoints: POST `/api/patrol-routes`, POST `/api/shift-assignments`, POST `/api/shifts/:shiftId/assignments` - Guards cannot be assigned to both fixed posts and mobile patrols on same date - Clear error messages when constraint violated - **Guard Planning Views**: - `/my-shifts-fixed`: Guards view their fixed post shifts with orari, dotazioni (armato, automezzo), location, sito - `/my-shifts-mobile`: Guards view patrol routes with sequenced site list, addresses, vehicle assignment - Backend endpoints: GET `/api/my-shifts/fixed`, GET `/api/my-shifts/mobile` with date range filters - **Site Planning View**: - `/site-planning-view`: Coordinators view all guards assigned to a site across a week - Shows guard name, badge, orari, dotazioni for each assignment - Backend endpoint: GET `/api/site-planning/:siteId` with date range filters - **Impact**: Complete end-to-end planning system supporting both coordinator and guard roles with database-backed route planning and operational equipment tracking ## External Dependencies - **Replit Auth**: For OpenID Connect (OIDC) based authentication. - **Neon**: Managed PostgreSQL database service. - **Tailwind CSS**: For utility-first CSS styling. - **Shadcn UI**: For UI components. - **Zod**: For schema validation. - **TanStack Query**: For data fetching and state management. - **Wouter**: For client-side routing. - **date-fns**: For date manipulation and formatting. - **Leaflet**: Interactive map library with react-leaflet bindings and OpenStreetMap tiles (free). - **Nominatim**: OpenStreetMap geocoding API for automatic address-to-coordinates conversion (free, rate limited to 1 req/sec).