# 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).