Implement new routes and UI components for guards to view fixed and mobile shifts, and for coordinators to view site-specific guard assignments. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e5565357-90e1-419f-b9a8-6ee8394636df Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e5565357-90e1-419f-b9a8-6ee8394636df/WbUtQAg
155 lines
12 KiB
Markdown
155 lines
12 KiB
Markdown
# 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). |