From 470cd9262ba8a21b197e1c13c6912bb2de7df675 Mon Sep 17 00:00:00 2001 From: marco370 <48531002-marco370@users.noreply.replit.com> Date: Fri, 17 Oct 2025 14:57:46 +0000 Subject: [PATCH] Add contract management and service type linkage to site data Update the database schema to include contract details for sites and link sites to service types, while making shift type optional. 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/FlO7tHX --- .replit | 4 ---- replit.md | 4 +++- shared/schema.ts | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.replit b/.replit index f28aea5..c50bc15 100644 --- a/.replit +++ b/.replit @@ -31,10 +31,6 @@ externalPort = 3002 localPort = 43267 externalPort = 3003 -[[ports]] -localPort = 43839 -externalPort = 4200 - [env] PORT = "5000" diff --git a/replit.md b/replit.md index 6827afb..dfe6231 100644 --- a/replit.md +++ b/replit.md @@ -33,6 +33,8 @@ The database includes core tables for `users`, `guards`, `certifications`, `site **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 ### 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. @@ -49,7 +51,7 @@ Key frontend routes include `/`, `/guards`, `/sites`, `/shifts`, `/reports`, `/n ### 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). +- **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) and contract management (reference code, validity period with start/end dates). Contract status is visualized with badges (active/expiring/expired) and enforces shift creation only within active contract periods. - **Pianificazione Operativa Interattiva**: Three-step workflow for shift assignment: 1. Select date → view uncovered sites with coverage status 2. Select site → view filtered resources (guards and vehicles matching requirements) diff --git a/shared/schema.ts b/shared/schema.ts index c929854..496b098 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -205,7 +205,8 @@ export const sites = pgTable("sites", { location: locationEnum("location").notNull().default("roccapiemonte"), // Sede gestionale // Service requirements - shiftType: shiftTypeEnum("shift_type").notNull(), + serviceTypeId: varchar("service_type_id").references(() => serviceTypes.id), + shiftType: shiftTypeEnum("shift_type"), // Optional - can be derived from service type minGuards: integer("min_guards").notNull().default(1), requiresArmed: boolean("requires_armed").default(false), requiresDriverLicense: boolean("requires_driver_license").default(false),