## ๐Ÿ“… Holiday Calendar System - Complete Guide ## Overview The Holiday Calendar System allows administrators to manage organizational holidays that are excluded from TAT (Turnaround Time) calculations for **STANDARD priority** requests. **Key Features:** - โœ… Admin can add/edit/delete holidays - โœ… Supports different holiday types (National, Regional, Organizational, Optional) - โœ… Recurring holidays (e.g., Independence Day every year) - โœ… Department/location-specific holidays - โœ… Bulk import from CSV/JSON - โœ… Automatic integration with TAT calculations - โœ… Year-based calendar view --- ## ๐ŸŽฏ How It Works ### **For STANDARD Priority:** ``` Working Days = Monday-Friday (excluding weekends AND holidays) TAT Calculation = Skips Saturdays, Sundays, AND holidays ``` ### **For EXPRESS Priority:** ``` Calendar Days = All days (including weekends and holidays) TAT Calculation = Continuous (no skipping) ``` --- ## ๐Ÿ“Š Database Schema ### **Holidays Table:** ```sql CREATE TABLE holidays ( holiday_id UUID PRIMARY KEY, holiday_date DATE NOT NULL UNIQUE, holiday_name VARCHAR(200) NOT NULL, description TEXT, is_recurring BOOLEAN DEFAULT false, recurrence_rule VARCHAR(100), -- For annual recurring holiday_type ENUM('NATIONAL', 'REGIONAL', 'ORGANIZATIONAL', 'OPTIONAL'), is_active BOOLEAN DEFAULT true, applies_to_departments TEXT[], -- NULL = all departments applies_to_locations TEXT[], -- NULL = all locations created_by UUID REFERENCES users(user_id), updated_by UUID REFERENCES users(user_id), created_at TIMESTAMP, updated_at TIMESTAMP ); ``` --- ## ๐Ÿ”Œ API Endpoints ### **1. Get All Holidays** ``` GET /api/admin/holidays?year=2025 ``` **Response:** ```json { "success": true, "data": [ { "holidayId": "...", "holidayDate": "2025-01-26", "holidayName": "Republic Day", "description": "Indian Republic Day", "holidayType": "NATIONAL", "isRecurring": true, "isActive": true } ], "count": 15 } ``` ### **2. Get Holiday Calendar for Year** ``` GET /api/admin/holidays/calendar/2025 ``` **Response:** ```json { "success": true, "year": 2025, "holidays": [ { "date": "2025-01-26", "name": "Republic Day", "description": "...", "type": "NATIONAL", "isRecurring": true } ] } ``` ### **3. Create Holiday** ``` POST /api/admin/holidays Content-Type: application/json { "holidayDate": "2025-10-02", "holidayName": "Gandhi Jayanti", "description": "Mahatma Gandhi's Birthday", "holidayType": "NATIONAL", "isRecurring": true, "recurrenceRule": "FREQ=YEARLY;BYMONTH=10;BYMONTHDAY=2" } ``` ### **4. Update Holiday** ``` PUT /api/admin/holidays/:holidayId Content-Type: application/json { "holidayName": "Updated Name", "description": "Updated description" } ``` ### **5. Delete Holiday** ``` DELETE /api/admin/holidays/:holidayId ``` ### **6. Bulk Import Holidays** ``` POST /api/admin/holidays/bulk-import Content-Type: application/json { "holidays": [ { "holidayDate": "2025-01-26", "holidayName": "Republic Day", "holidayType": "NATIONAL" }, { "holidayDate": "2025-08-15", "holidayName": "Independence Day", "holidayType": "NATIONAL" } ] } ``` --- ## ๐ŸŽจ Frontend Implementation (Future) ### **Holiday Management Page:** ```tsx // Admin Dashboard โ†’ Settings โ†’ Holiday Calendar {/* Visual calendar showing all holidays */} Republic Day {/* List view with add/edit/delete */} ๐Ÿ“… Jan 26, 2025 - Republic Day ``` --- ## ๐Ÿ“ Sample Holidays Data ### **Indian National Holidays 2025:** ```json [ { "date": "2025-01-26", "name": "Republic Day", "type": "NATIONAL" }, { "date": "2025-03-14", "name": "Holi", "type": "NATIONAL" }, { "date": "2025-03-30", "name": "Ram Navami", "type": "NATIONAL" }, { "date": "2025-04-10", "name": "Mahavir Jayanti", "type": "NATIONAL" }, { "date": "2025-04-14", "name": "Ambedkar Jayanti", "type": "NATIONAL" }, { "date": "2025-04-18", "name": "Good Friday", "type": "NATIONAL" }, { "date": "2025-05-01", "name": "May Day", "type": "NATIONAL" }, { "date": "2025-08-15", "name": "Independence Day", "type": "NATIONAL" }, { "date": "2025-08-27", "name": "Janmashtami", "type": "NATIONAL" }, { "date": "2025-10-02", "name": "Gandhi Jayanti", "type": "NATIONAL" }, { "date": "2025-10-22", "name": "Dussehra", "type": "NATIONAL" }, { "date": "2025-11-01", "name": "Diwali", "type": "NATIONAL" }, { "date": "2025-11-05", "name": "Guru Nanak Jayanti", "type": "NATIONAL" }, { "date": "2025-12-25", "name": "Christmas", "type": "NATIONAL" } ] ``` --- ## ๐Ÿ”„ TAT Calculation Integration ### **How Holidays Affect TAT:** **Example: 48-hour TAT for STANDARD priority** **Without Holidays:** ``` Submit: Monday 10:00 AM Due: Wednesday 10:00 AM (48 working hours, skipping weekend) ``` **With Holiday (Tuesday is holiday):** ``` Submit: Monday 10:00 AM Holiday: Tuesday (skipped) Due: Thursday 10:00 AM (48 working hours, skipping Tuesday AND weekend) ``` ### **TAT Calculation Logic:** ```typescript // For STANDARD priority: 1. Start from submission time 2. Add hours one by one 3. Skip if: - Weekend (Saturday/Sunday) - Outside working hours (before 9 AM or after 6 PM) - Holiday (from holidays table) 4. Continue until all hours are added ``` --- ## ๐Ÿ—๏ธ Architecture ### **Holiday Cache System:** ``` Server Startup โ†“ Load holidays from database โ†“ Cache in memory (Set of dates) โ†“ Cache expires after 6 hours โ†“ Reload automatically ``` **Benefits:** - โœ… Fast lookups (no DB query for each hour) - โœ… Automatic refresh - โœ… Minimal memory footprint ### **TAT Calculation Flow:** ``` calculateTatMilestones() โ†“ addWorkingHours() โ†“ loadHolidaysCache() (if expired) โ†“ For each hour: isWorkingTime() โ”œโ”€ Check weekend? โ†’ Skip โ”œโ”€ Check working hours? โ†’ Skip if outside โ””โ”€ Check holiday? โ†’ Skip if holiday โ†“ Return calculated date ``` --- ## ๐Ÿ“‹ Admin Configuration ### **Admin Can Configure:** | Config Area | Options | Default | |-------------|---------|---------| | **TAT Settings** | Default TAT hours (Express/Standard) | 24h/48h | | | Reminder thresholds | 50%, 75% | | | Working hours | 9 AM - 6 PM | | **Holidays** | Add/edit/delete holidays | None | | | Bulk import holidays | - | | | Recurring holidays | - | | **Document Policy** | Max file size | 10 MB | | | Allowed file types | pdf,doc,... | | | Retention period | 365 days | | **AI Configuration** | Enable/disable AI remarks | Enabled | | | Max characters | 500 | | **Notifications** | Channels (email/push) | All | | | Frequency | Immediate | --- ## ๐Ÿงช Testing Holiday Integration ### **Test Scenario 1: Add Holiday** ```bash # 1. Add a holiday for tomorrow POST /api/admin/holidays { "holidayDate": "2025-11-05", "holidayName": "Test Holiday", "holidayType": "ORGANIZATIONAL" } # 2. Create request with 24-hour STANDARD TAT # Expected: Due date should skip the holiday # 3. Verify TAT calculation excludes the holiday ``` ### **Test Scenario 2: Recurring Holiday** ```bash # 1. Add Independence Day (recurring) POST /api/admin/holidays { "holidayDate": "2025-08-15", "holidayName": "Independence Day", "isRecurring": true, "recurrenceRule": "FREQ=YEARLY;BYMONTH=8;BYMONTHDAY=15" } # 2. Test requests spanning this date ``` --- ## ๐Ÿ“Š Holiday Statistics API ### **Get Holiday Count by Type:** ```sql SELECT holiday_type, COUNT(*) as count FROM holidays WHERE is_active = true AND EXTRACT(YEAR FROM holiday_date) = 2025 GROUP BY holiday_type; ``` ### **Get Upcoming Holidays:** ```sql SELECT holiday_name, holiday_date, holiday_type FROM holidays WHERE holiday_date >= CURRENT_DATE AND holiday_date <= CURRENT_DATE + INTERVAL '90 days' AND is_active = true ORDER BY holiday_date; ``` --- ## ๐Ÿ”’ Security ### **Admin Only Access:** All holiday and configuration management endpoints require: 1. โœ… Valid JWT token (`authenticateToken`) 2. โœ… Admin role (`requireAdmin`) **Middleware Chain:** ```typescript router.use(authenticateToken); // Must be logged in router.use(requireAdmin); // Must be admin ``` --- ## ๐ŸŽ“ Best Practices ### **1. Holiday Naming:** - Use clear, descriptive names - Include year if not recurring - Example: "Diwali 2025" or "Independence Day" (recurring) ### **2. Types:** - **NATIONAL**: Applies to entire country - **REGIONAL**: Specific to state/region - **ORGANIZATIONAL**: Company-specific - **OPTIONAL**: Optional holidays (float) ### **3. Department/Location Specific:** ```json { "holidayName": "Regional Holiday", "appliesToDepartments": ["Sales", "Marketing"], "appliesToLocations": ["Mumbai", "Delhi"] } ``` ### **4. Recurring Holidays:** ```json { "isRecurring": true, "recurrenceRule": "FREQ=YEARLY;BYMONTH=8;BYMONTHDAY=15" } ``` --- ## ๐Ÿš€ Deployment ### **Initial Setup:** 1. **Run Migrations:** ```bash npm run migrate ``` 2. **Import Indian Holidays:** ```bash curl -X POST http://localhost:5000/api/admin/holidays/bulk-import \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \ -d @sample_holidays_2025.json ``` 3. **Verify:** ```bash curl http://localhost:5000/api/admin/holidays?year=2025 ``` --- ## ๐Ÿ“š Related Documentation - **Admin Configuration**: See admin configuration tables - **TAT Calculation**: See `TAT_NOTIFICATION_SYSTEM.md` - **API Reference**: See API documentation --- **Last Updated**: November 4, 2025 **Version**: 1.0.0 **Team**: Royal Enfield Workflow