Fix geocoding bug, implement map zooming to site, allow guard assignment to sites, and enable patrol route sequencing via map marker clicks. 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/ZaT6tFl
9.9 KiB
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_typestable viaserviceTypeId(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 (customerIdFK tocustomers.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/geocodeendpoint 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
- Created POST
- 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
- Backend (
- 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 (
cityfrom sites,isActivefrom guards) from queries - Changed
innerJointoleftJoinfor service types to handle sites without serviceTypeId - Fixed
orderBysyntax (single field instead of multiple) - Added
hasDriverLicensefilter for guards (mobile services require driving)
- Removed non-existent fields (
- 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
- Backend Fixes:
- 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
- Zoom-to-Site:
- 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
shiftTypeenum values instead of dynamic service types from the database - Solution:
- Changed Sites form to use
serviceTypeId(FK toservice_types.id) instead of deprecatedshiftTypefield - Added dynamic service type dropdown loading from
/api/service-typesendpoint - 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
- Changed Sites form to use
- Impact: Sites now correctly reference service types configured in "Tipologie Servizi" page, ensuring consistency across the system
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).