diff --git a/application/src/api/index.ts b/application/src/api/index.ts index c4f7f62..1fa86b7 100644 --- a/application/src/api/index.ts +++ b/application/src/api/index.ts @@ -11,19 +11,19 @@ const api = { * Handle API requests */ async handleRequest(path, method, body) { - console.log(`API request: ${method} ${path}`, body); + // console.log(`API request: ${method} ${path}`, body); // Route to the appropriate handler if (path === '/api/realtime') { - console.log("Routing to realtime handler"); + // console.log("Routing to realtime handler"); return await realtime(body); } else if (path === '/api/settings' || path.startsWith('/api/settings/')) { - console.log("Routing to settings handler"); + // console.log("Routing to settings handler"); return await settingsApi(body, path); } // Return 404 for unknown routes - console.error(`Endpoint not found: ${path}`); + // console.error(`Endpoint not found: ${path}`); return { status: 404, json: { @@ -40,7 +40,7 @@ const originalFetch = window.fetch; window.fetch = async (url, options = {}) => { // Check if this is an API request to our mock endpoints if (typeof url === 'string' && url.startsWith('/api/')) { - console.log('Intercepting API request:', url, options); + // console.log('Intercepting API request:', url, options); try { let body = {}; diff --git a/application/src/api/settings/index.ts b/application/src/api/settings/index.ts index 1be26bc..50d2b7d 100644 --- a/application/src/api/settings/index.ts +++ b/application/src/api/settings/index.ts @@ -8,7 +8,7 @@ import { testEmail } from './actions/testEmail'; * Settings API handler */ const settingsApi = async (body: any, path?: string) => { - console.log('Settings API called with path:', path, 'body:', body); + // console.log('Settings API called with path:', path, 'body:', body); // Handle test email endpoint specifically if (path === '/api/settings/test/email') { @@ -18,7 +18,7 @@ const settingsApi = async (body: any, path?: string) => { // Handle regular settings API with action-based routing const action = body?.action; - console.log('Settings API called with action:', action, 'data:', body?.data); + // console.log('Settings API called with action:', action, 'data:', body?.data); switch (action) { case 'getSettings': diff --git a/application/src/components/dashboard/Header.tsx b/application/src/components/dashboard/Header.tsx index bc98045..0e0815d 100644 --- a/application/src/components/dashboard/Header.tsx +++ b/application/src/components/dashboard/Header.tsx @@ -53,7 +53,7 @@ export const Header = ({ // Log avatar data for debugging useEffect(() => { if (currentUser) { - console.log("Avatar URL in Header:", currentUser.avatar); + // console.log("Avatar URL in Header:", currentUser.avatar); } }, [currentUser]); @@ -66,7 +66,7 @@ export const Header = ({ } else { avatarUrl = currentUser.avatar; } - console.log("Final avatar URL:", avatarUrl); + // console.log("Final avatar URL:", avatarUrl); } return ( diff --git a/application/src/components/schedule-incident/ScheduleIncidentContent.tsx b/application/src/components/schedule-incident/ScheduleIncidentContent.tsx index a3b8422..05ee42a 100644 --- a/application/src/components/schedule-incident/ScheduleIncidentContent.tsx +++ b/application/src/components/schedule-incident/ScheduleIncidentContent.tsx @@ -22,12 +22,12 @@ export const ScheduleIncidentContent = () => { // Initialize maintenance notifications when the component mounts useEffect(() => { - console.log("Initializing maintenance notifications"); + // console.log("Initializing maintenance notifications"); initMaintenanceNotifications(); // Clean up when the component unmounts return () => { - console.log("Cleaning up maintenance notifications"); + // console.log("Cleaning up maintenance notifications"); stopMaintenanceNotifications(); }; }, []); @@ -43,7 +43,7 @@ export const ScheduleIncidentContent = () => { const handleMaintenanceCreated = () => { // Refresh data by incrementing the refresh trigger const newTriggerValue = refreshTrigger + 1; - console.log("Maintenance created, refreshing data with new trigger value:", newTriggerValue); + // console.log("Maintenance created, refreshing data with new trigger value:", newTriggerValue); setRefreshTrigger(newTriggerValue); // Show success toast @@ -56,7 +56,7 @@ export const ScheduleIncidentContent = () => { const handleIncidentCreated = () => { // Refresh data by incrementing the refresh trigger const newTriggerValue = incidentRefreshTrigger + 1; - console.log("Incident created, refreshing data with new trigger value:", newTriggerValue); + // console.log("Incident created, refreshing data with new trigger value:", newTriggerValue); setIncidentRefreshTrigger(newTriggerValue); // Show success toast diff --git a/application/src/components/schedule-incident/hooks/useIncidentData.ts b/application/src/components/schedule-incident/hooks/useIncidentData.ts index d6b32cb..2e0a998 100644 --- a/application/src/components/schedule-incident/hooks/useIncidentData.ts +++ b/application/src/components/schedule-incident/hooks/useIncidentData.ts @@ -22,13 +22,13 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => const fetchIncidentData = useCallback(async (force = false) => { // Skip if already fetching if (isFetchingRef.current) { - console.log('Already fetching data, skipping additional request'); + // console.log('Already fetching data, skipping additional request'); return; } // Skip if not forced and already initialized if (initialized && !force) { - console.log('Data already initialized and no force refresh, skipping fetch'); + // console.log('Data already initialized and no force refresh, skipping fetch'); return; } @@ -46,22 +46,22 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => setError(null); try { - console.log(`Fetching incident data (force=${force})`); + // console.log(`Fetching incident data (force=${force})`); const allIncidents = await incidentService.getAllIncidents(force); if (Array.isArray(allIncidents)) { setIncidents(allIncidents); - console.log(`Successfully set ${allIncidents.length} incidents to state`); + // console.log(`Successfully set ${allIncidents.length} incidents to state`); } else { setIncidents([]); - console.warn('No incidents returned from service'); + // console.warn('No incidents returned from service'); } setInitialized(true); setLoading(false); setIsRefreshing(false); } catch (error) { - console.error('Error fetching incident data:', error); + // console.error('Error fetching incident data:', error); setError('Failed to load incident data. Please try again later.'); setIncidents([]); setInitialized(true); @@ -79,7 +79,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => useEffect(() => { // Skip if the refresh trigger hasn't changed (prevents duplicate effect calls) if (refreshTrigger === lastRefreshTriggerRef.current && initialized) { - console.log('Refresh trigger unchanged, skipping fetch'); + // console.log('Refresh trigger unchanged, skipping fetch'); return; } @@ -90,7 +90,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => const abortController = new AbortController(); let isMounted = true; - console.log(`useIncidentData effect running, refreshTrigger: ${refreshTrigger}`); + // console.log(`useIncidentData effect running, refreshTrigger: ${refreshTrigger}`); // Use a longer delay to ensure we don't trigger too many API calls const fetchTimer = setTimeout(() => { @@ -101,7 +101,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => // Cleanup function to abort any in-flight requests and clear timers return () => { - console.log('Cleaning up incident data fetch effect'); + // console.log('Cleaning up incident data fetch effect'); isMounted = false; clearTimeout(fetchTimer); abortController.abort(); @@ -112,7 +112,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) => const incidentData = useMemo(() => { if (!initialized || incidents.length === 0) return []; - console.log(`Filtering incidents by: ${filter}`); + // console.log(`Filtering incidents by: ${filter}`); if (filter === "unresolved") { return incidents.filter(item => { diff --git a/application/src/components/schedule-incident/maintenance/form/MaintenanceNotificationSettingsField.tsx b/application/src/components/schedule-incident/maintenance/form/MaintenanceNotificationSettingsField.tsx index 65174a6..9ec629a 100644 --- a/application/src/components/schedule-incident/maintenance/form/MaintenanceNotificationSettingsField.tsx +++ b/application/src/components/schedule-incident/maintenance/form/MaintenanceNotificationSettingsField.tsx @@ -27,7 +27,7 @@ export const MaintenanceNotificationSettingsField = () => { try { setIsLoading(true); const channels = await alertConfigService.getAlertConfigurations(); - console.log("Fetched notification channels for form:", channels); + // console.log("Fetched notification channels for form:", channels); // Only show enabled channels const enabledChannels = channels.filter(channel => channel.enabled); @@ -38,18 +38,18 @@ export const MaintenanceNotificationSettingsField = () => { const currentChannel = getValues('notification_channel_id'); const shouldNotify = getValues('notify_subscribers'); - console.log("Current notification values:", { - currentChannel, - shouldNotify, - availableChannels: enabledChannels.length - }); + // console.log("Current notification values:", { + // currentChannel, + // shouldNotify, + // availableChannels: enabledChannels.length + // }); if (shouldNotify && (!currentChannel || currentChannel === 'none') && enabledChannels.length > 0) { - console.log("Setting default notification channel:", enabledChannels[0].id); + // console.log("Setting default notification channel:", enabledChannels[0].id); setValue('notification_channel_id', enabledChannels[0].id); } } catch (error) { - console.error('Error fetching notification channels:', error); + // console.error('Error fetching notification channels:', error); toast({ title: t('error'), description: t('errorFetchingNotificationChannels'), @@ -64,12 +64,12 @@ export const MaintenanceNotificationSettingsField = () => { }, [t, toast, setValue, getValues]); // Log value changes for debugging - useEffect(() => { - console.log("Current notification settings:", { - channel_id: getValues('notification_channel_id'), - notify: notifySubscribers - }); - }, [notifySubscribers, notificationChannelId, getValues]); + // useEffect(() => { + // console.log("Current notification settings:", { + // channel_id: getValues('notification_channel_id'), + // notify: notifySubscribers + // }); + // }, [notifySubscribers, notificationChannelId, getValues]); return (
@@ -98,7 +98,7 @@ export const MaintenanceNotificationSettingsField = () => { checked={field.value} onCheckedChange={(checked) => { field.onChange(checked); - console.log("Notification toggle changed to:", checked); + // console.log("Notification toggle changed to:", checked); // If notifications are disabled, also clear the notification channel if (!checked) { setValue('notification_channel_id', ''); @@ -120,10 +120,10 @@ export const MaintenanceNotificationSettingsField = () => { // Make sure to handle both empty string and "none" as special cases const displayValue = field.value || ""; - console.log("Rendering notification channel field with value:", { - fieldValue: field.value, - displayValue - }); + // console.log("Rendering notification channel field with value:", { + // fieldValue: field.value, + // displayValue + // }); return ( @@ -135,7 +135,7 @@ export const MaintenanceNotificationSettingsField = () => { { - console.log("Notification channel changed to:", value); - field.onChange(value === "none" ? "" : value); - }} - value={displayValue} - > - - - - - None - {alertConfigs.map((config) => ( + name="notificationStatus" + render={({ field }) => ( + +
+ + Enable Notifications + + + Enable or disable notifications for this service + +
+ + { + field.onChange(checked ? "enabled" : "disabled"); + // Clear notification channels when disabled + if (!checked) { + form.setValue("notificationChannels", []); + } + }} + /> + +
+ )} + /> + + ( + + Notification Channels + + {notificationStatus === "enabled" + ? "Select notification channels for this service" + : "Enable notifications first to select channels"} + + + {/* Display selected channels as badges */} + {notificationChannels && notificationChannels.length > 0 && ( +
+ {getSelectedChannelNames().map((channelName, index) => ( + + {channelName} + handleChannelRemove(notificationChannels[index])} + /> + + ))} +
+ )} + + + - -
- ); - }} +
+ + +
+ )} /> - + Default - {templates?.map((template) => ( - - {template.name} - - ))} + {/* Add templates here when available */} + + {notificationStatus === "enabled" + ? "Choose a template for alert messages" + : "Enable notifications first to select template"} + ); }} /> ); -} \ No newline at end of file +} diff --git a/application/src/components/services/add-service/serviceFormUtils.ts b/application/src/components/services/add-service/serviceFormUtils.ts new file mode 100644 index 0000000..7d9171d --- /dev/null +++ b/application/src/components/services/add-service/serviceFormUtils.ts @@ -0,0 +1,122 @@ + +import { Service } from "@/types/service.types"; +import { ServiceFormData } from "./types"; + +export const getServiceFormDefaults = (): ServiceFormData => ({ + name: "", + type: "http", + url: "", + port: "", + interval: "60", + retries: "3", + notificationStatus: "disabled", + notificationChannels: [], + alertTemplate: "", + regionalMonitoringEnabled: false, + regionalAgent: "", +}); + +export const mapServiceToFormData = (service: Service): ServiceFormData => { + // Ensure the type is one of the allowed values + const serviceType = (service.type || "http").toLowerCase(); + const validType = ["http", "ping", "tcp", "dns"].includes(serviceType) + ? serviceType as "http" | "ping" | "tcp" | "dns" + : "http"; + + // For PING services, use host field; for DNS use domain field; for TCP use host field; others use url + let urlValue = ""; + let portValue = ""; + + if (validType === "ping") { + urlValue = service.host || ""; + } else if (validType === "dns") { + urlValue = service.domain || ""; + } else if (validType === "tcp") { + urlValue = service.host || ""; + portValue = String(service.port || ""); + } else { + urlValue = service.url || ""; + } + + // Handle regional monitoring data - check regional_status field + const isRegionalEnabled = service.regional_status === "enabled"; + const regionalAgent = isRegionalEnabled && service.region_name && service.agent_id + ? `${service.region_name}|${service.agent_id}` + : ""; + + // Handle notification channels - convert notification_channel and notificationChannel to array + const notificationChannels: string[] = []; + + // Check for notification_channel field (from database) + if (service.notification_channel) { + notificationChannels.push(service.notification_channel); + } + + // Also check for notificationChannel field (backward compatibility) + if (service.notificationChannel && !notificationChannels.includes(service.notificationChannel)) { + notificationChannels.push(service.notificationChannel); + } + + console.log("Mapping service to form data:", { + serviceName: service.name, + notification_status: service.notification_status, + notification_channel: service.notification_channel, + notificationChannel: service.notificationChannel, + mappedChannels: notificationChannels + }); + + return { + name: service.name || "", + type: validType, + url: urlValue, + port: portValue, + interval: String(service.interval || 60), + retries: String(service.retries || 3), + notificationStatus: service.notification_status || "disabled", + notificationChannels: notificationChannels, + alertTemplate: service.alertTemplate === "default" ? "" : service.alertTemplate || "", + regionalMonitoringEnabled: isRegionalEnabled, + regionalAgent: regionalAgent, + }; +}; + +export const mapFormDataToServiceData = (data: ServiceFormData) => { + // Parse regional agent selection + let regionName = ""; + let agentId = ""; + let regionalStatus: "enabled" | "disabled" = "disabled"; + + // Set regional status and agent data based on form values + if (data.regionalMonitoringEnabled) { + regionalStatus = "enabled"; + if (data.regionalAgent && data.regionalAgent !== "") { + const [parsedRegionName, parsedAgentId] = data.regionalAgent.split("|"); + regionName = parsedRegionName || ""; + agentId = parsedAgentId || ""; + } + } + + // Prepare service data with proper field mapping + return { + name: data.name, + type: data.type, + interval: parseInt(data.interval), + retries: parseInt(data.retries), + notificationStatus: data.notificationStatus || "disabled", + notificationChannels: data.notificationChannels || [], + alertTemplate: data.alertTemplate === "default" ? "" : data.alertTemplate, + // Use regional_status field instead of regionalMonitoringEnabled + regionalStatus: regionalStatus, + regionName: regionName, + agentId: agentId, + // Map the URL field to appropriate database field based on service type + ...(data.type === "dns" + ? { domain: data.url, url: "", host: "", port: undefined } // DNS: store in domain field + : data.type === "ping" + ? { host: data.url, url: "", domain: "", port: undefined } // PING: store in host field + : data.type === "tcp" + ? { host: data.url, port: parseInt(data.port || "80"), url: "", domain: "" } // TCP: store in host and port fields + : { url: data.url, domain: "", host: "", port: undefined } // HTTP: store in url field + ) + }; +}; \ No newline at end of file diff --git a/application/src/components/services/add-service/types.ts b/application/src/components/services/add-service/types.ts index c276e4d..3d269e5 100644 --- a/application/src/components/services/add-service/types.ts +++ b/application/src/components/services/add-service/types.ts @@ -11,11 +11,12 @@ export const serviceSchema = z.object({ port: z.string().optional(), interval: z.string(), retries: z.string(), - notificationChannel: z.string().optional(), + notificationStatus: z.enum(["enabled", "disabled"]).optional(), + notificationChannels: z.array(z.string()).optional(), alertTemplate: z.string().optional(), // Regional monitoring fields regionalMonitoringEnabled: z.boolean().optional(), regionalAgent: z.string().optional(), }); -export type ServiceFormData = z.infer; \ No newline at end of file +export type ServiceFormData = z.infer; diff --git a/application/src/components/services/hooks/useConsolidatedUptimeData.ts b/application/src/components/services/hooks/useConsolidatedUptimeData.ts index 5fb40f7..e8c24a8 100644 --- a/application/src/components/services/hooks/useConsolidatedUptimeData.ts +++ b/application/src/components/services/hooks/useConsolidatedUptimeData.ts @@ -46,23 +46,23 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte queryKey: ['consolidatedUptimeHistory', serviceId, serviceType], queryFn: async () => { if (!serviceId) { - console.log('No serviceId provided, skipping fetch'); + // console.log('No serviceId provided, skipping fetch'); return []; } - console.log(`Fetching consolidated uptime data for service ${serviceId} of type ${serviceType}`); + // console.log(`Fetching consolidated uptime data for service ${serviceId} of type ${serviceType}`); // Get ALL uptime history data - this should include both default and regional data const rawData = await uptimeService.getUptimeHistory(serviceId, 100, undefined, undefined, serviceType); - console.log(`Retrieved ${rawData.length} total records for service ${serviceId}`); - console.log('Raw data sample:', rawData.slice(0, 5).map(d => ({ - timestamp: d.timestamp, - region_name: d.region_name, - agent_id: d.agent_id, - status: d.status, - service_id: d.service_id, - response_time: d.responseTime - }))); + // console.log(`Retrieved ${rawData.length} total records for service ${serviceId}`); + // console.log('Raw data sample:', rawData.slice(0, 5).map(d => ({ + // timestamp: d.timestamp, + // region_name: d.region_name, + // agent_id: d.agent_id, + // status: d.status, + // service_id: d.service_id, + // response_time: d.responseTime + // }))); return rawData; }, @@ -78,7 +78,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte const processConsolidatedData = (data: UptimeData[]): ConsolidatedTimeSlot[] => { if (!data || data.length === 0) return []; - console.log(`Processing ${data.length} uptime records for consolidation`); + // console.log(`Processing ${data.length} uptime records for consolidation`); // Create a map to group records by normalized timestamp (minute precision) const timeSlotMap = new Map>(); @@ -99,17 +99,17 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte // Regional monitoring data sourceName = `${regionName} (Agent ${agentId})`; isDefault = false; - console.log(`Found regional data: ${sourceName} for normalized timestamp ${normalizedTimestamp}`); + // console.log(`Found regional data: ${sourceName} for normalized timestamp ${normalizedTimestamp}`); } else if (agentId && !regionName) { // Default monitoring with specific agent sourceName = `Default (Agent ${agentId})`; isDefault = true; - console.log(`Found default monitoring: ${sourceName} for normalized timestamp ${normalizedTimestamp}`); + // console.log(`Found default monitoring: ${sourceName} for normalized timestamp ${normalizedTimestamp}`); } else { // Default monitoring fallback - sourceName = 'Default (Agent 1)'; + sourceName = 'Default System Check (Agent 1)'; isDefault = true; - console.log(`Using fallback default monitoring for normalized timestamp ${normalizedTimestamp}`); + // console.log(`Using fallback default monitoring for normalized timestamp ${normalizedTimestamp}`); } // Get or create the array for this normalized timestamp @@ -130,9 +130,9 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte isDefault }); - console.log(`Added record to normalized timestamp ${normalizedTimestamp}: Source=${sourceName}, Status=${record.status}, IsDefault=${isDefault}, ResponseTime=${record.responseTime}ms`); + // console.log(`Added record to normalized timestamp ${normalizedTimestamp}: Source=${sourceName}, Status=${record.status}, IsDefault=${isDefault}, ResponseTime=${record.responseTime}ms`); } else { - console.log(`Skipping duplicate record for source ${sourceName} at timestamp ${normalizedTimestamp}`); + // console.log(`Skipping duplicate record for source ${sourceName} at timestamp ${normalizedTimestamp}`); } }); @@ -150,13 +150,13 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) .slice(0, 20); // Take the most recent 20 time slots - console.log(`Created ${consolidatedTimeline.length} consolidated time slots with normalized timestamps`); - consolidatedTimeline.forEach((slot, index) => { - console.log(`Slot ${index} - Normalized Timestamp: ${slot.timestamp}, Items: ${slot.items.length}`); - slot.items.forEach((item, itemIndex) => { - console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}ms, IsDefault=${item.isDefault}`); - }); - }); + // console.log(`Created ${consolidatedTimeline.length} consolidated time slots with normalized timestamps`); + // consolidatedTimeline.forEach((slot, index) => { + // console.log(`Slot ${index} - Normalized Timestamp: ${slot.timestamp}, Items: ${slot.items.length}`); + // slot.items.forEach((item, itemIndex) => { + // console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}ms, IsDefault=${item.isDefault}`); + // }); + // }); return consolidatedTimeline; }; @@ -164,12 +164,12 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte // Update consolidated items when data changes useEffect(() => { if (uptimeData && uptimeData.length > 0) { - console.log(`Processing consolidated uptime data for service ${serviceId}`); + // console.log(`Processing consolidated uptime data for service ${serviceId}`); const processedData = processConsolidatedData(uptimeData); // If service is currently paused, override ONLY the latest (first) bar with paused status if (status === "paused" && processedData.length > 0) { - console.log(`Service ${serviceId} is paused, overriding latest bar with paused status`); + // console.log(`Service ${serviceId} is paused, overriding latest bar with paused status`); // Create a paused entry for the latest timestamp const latestTimestamp = new Date(); @@ -191,11 +191,11 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte // Replace the first item with paused status, keep the rest as historical data const updatedData = [pausedSlot, ...processedData.slice(0, 19)]; - console.log(`Updated data with paused latest bar, total bars: ${updatedData.length}`); + // console.log(`Updated data with paused latest bar, total bars: ${updatedData.length}`); setConsolidatedItems(updatedData); } else { // Service is active (up/down/warning) - merge real data with any existing paused bars - console.log(`Service ${serviceId} is active with status: ${status}, merging with existing paused bars`); + // console.log(`Service ${serviceId} is active with status: ${status}, merging with existing paused bars`); // Get existing paused bars from current state const existingPausedBars = consolidatedItems.filter(slot => @@ -213,7 +213,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte const hasConflict = processedData.some(slot => slot.timestamp === pausedSlot.timestamp); if (!hasConflict) { mergedData.push(pausedSlot); - console.log(`Preserved paused bar at timestamp: ${pausedSlot.timestamp}`); + // console.log(`Preserved paused bar at timestamp: ${pausedSlot.timestamp}`); } }); @@ -222,12 +222,12 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) .slice(0, 20); - console.log(`Final merged data has ${finalData.length} slots`); + // console.log(`Final merged data has ${finalData.length} slots`); setConsolidatedItems(finalData); } } else if (!serviceId || (uptimeData && uptimeData.length === 0)) { // Generate placeholder data when no real data is available - console.log(`No uptime data available for service ${serviceId}, generating placeholder with status: ${status}`); + // console.log(`No uptime data available for service ${serviceId}, generating placeholder with status: ${status}`); // Use the actual service status for placeholder data const statusValue = status === "paused" ? "paused" : @@ -252,7 +252,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte }; }); - console.log(`Generated ${placeholderHistory.length} placeholder slots with status: ${statusValue}`); + // console.log(`Generated ${placeholderHistory.length} placeholder slots with status: ${statusValue}`); setConsolidatedItems(placeholderHistory); } }, [uptimeData, serviceId, status, interval, consolidatedItems]); diff --git a/application/src/components/services/hooks/useServiceActions.ts b/application/src/components/services/hooks/useServiceActions.ts index 0dc8a5e..85b0b9b 100644 --- a/application/src/components/services/hooks/useServiceActions.ts +++ b/application/src/components/services/hooks/useServiceActions.ts @@ -23,7 +23,7 @@ export function useServiceActions(initialServices: Service[]) { }; const handleViewDetail = (service: Service) => { - console.log(`Navigating to service detail for service ID: ${service.id}`); + // console.log(`Navigating to service detail for service ID: ${service.id}`); navigate(`/service/${service.id}`); }; @@ -115,7 +115,7 @@ export function useServiceActions(initialServices: Service[]) { setSelectedService(null); } catch (error) { - console.error("Error deleting service:", error); + // console.error("Error deleting service:", error); toast({ variant: "destructive", title: "Error", @@ -134,7 +134,7 @@ export function useServiceActions(initialServices: Service[]) { // Toggle the mute alerts status for this specific service const newMuteStatus = !isMuted; - console.log(`${newMuteStatus ? "Muting" : "Unmuting"} alerts for service ${service.id} (${service.name})`); + // console.log(`${newMuteStatus ? "Muting" : "Unmuting"} alerts for service ${service.id} (${service.name})`); // First update the local state immediately for better UI responsiveness // Using proper type casting to ensure TypeScript knows we're creating valid Service objects @@ -165,7 +165,7 @@ export function useServiceActions(initialServices: Service[]) { await queryClient.invalidateQueries({ queryKey: ["services"] }); } catch (error) { - console.error("Error updating alert settings:", error); + // console.error("Error updating alert settings:", error); // Revert the local state change if the server update failed const revertedServices = services.map(s => { diff --git a/application/src/components/services/incident-history/LatestChecksTable.tsx b/application/src/components/services/incident-history/LatestChecksTable.tsx index c133347..a3143ea 100644 --- a/application/src/components/services/incident-history/LatestChecksTable.tsx +++ b/application/src/components/services/incident-history/LatestChecksTable.tsx @@ -27,8 +27,8 @@ export function LatestChecksTable({ uptimeData }: { uptimeData: UptimeData[] }) // Filter incidents by status const incidents = useMemo(() => { const statusChanges = getStatusChangeEvents(uptimeData); - console.log(`Total status changes: ${statusChanges.length}`); - console.log(`Status types in incidents: ${[...new Set(statusChanges.map(i => i.status))].join(', ')}`); + // console.log(`Total status changes: ${statusChanges.length}`); + // console.log(`Status types in incidents: ${[...new Set(statusChanges.map(i => i.status))].join(', ')}`); if (statusFilter === "all") return statusChanges; @@ -58,7 +58,7 @@ export function LatestChecksTable({ uptimeData }: { uptimeData: UptimeData[] }) // Calculate items per page for pagination display const itemsPerPage = pageSize === "all" ? incidents.length : parseInt(pageSize, 10); - console.log(`Status Filter: ${statusFilter}, Incidents: ${incidents.length}, Includes paused: ${incidents.some(i => i.status === 'paused')}`); + // console.log(`Status Filter: ${statusFilter}, Incidents: ${incidents.length}, Includes paused: ${incidents.some(i => i.status === 'paused')}`); return ( diff --git a/application/src/components/services/incident-history/utils.tsx b/application/src/components/services/incident-history/utils.tsx index 77560e5..b4aa977 100644 --- a/application/src/components/services/incident-history/utils.tsx +++ b/application/src/components/services/incident-history/utils.tsx @@ -68,7 +68,7 @@ export const getStatusChangeEvents = (uptimeData: UptimeData[]): UptimeData[] => } } - console.log(`Found ${statusChanges.length} status changes, including paused status changes: ${statusChanges.some(i => i.status === 'paused')}`); + // console.log(`Found ${statusChanges.length} status changes, including paused status changes: ${statusChanges.some(i => i.status === 'paused')}`); return statusChanges; }; diff --git a/application/src/components/services/index.ts b/application/src/components/services/index.ts index a1daa8c..d314f50 100644 --- a/application/src/components/services/index.ts +++ b/application/src/components/services/index.ts @@ -13,3 +13,4 @@ export * from './ServicesTableView'; export * from './ServiceDeleteDialog'; export * from './ServiceHistoryDialog'; export * from './ServiceEditDialog'; +export * from './ServiceForm'; \ No newline at end of file diff --git a/application/src/components/settings/alerts-templates/TemplateDialog.tsx b/application/src/components/settings/alerts-templates/TemplateDialog.tsx index a9dbc18..4b9b13d 100644 --- a/application/src/components/settings/alerts-templates/TemplateDialog.tsx +++ b/application/src/components/settings/alerts-templates/TemplateDialog.tsx @@ -40,11 +40,11 @@ export const TemplateDialog: React.FC = ({ // For debugging purposes useEffect(() => { if (open) { - console.log("Template dialog opened. Edit mode:", isEditMode, "Template ID:", templateId); + // console.log("Template dialog opened. Edit mode:", isEditMode, "Template ID:", templateId); // Log form values when they change const subscription = form.watch((value) => { - console.log("Current form values:", value); + // console.log("Current form values:", value); }); return () => subscription.unsubscribe(); diff --git a/application/src/components/ssl-domain/AddSSLCertificateForm.tsx b/application/src/components/ssl-domain/AddSSLCertificateForm.tsx index 9b21707..c78ff22 100644 --- a/application/src/components/ssl-domain/AddSSLCertificateForm.tsx +++ b/application/src/components/ssl-domain/AddSSLCertificateForm.tsx @@ -54,7 +54,7 @@ export const AddSSLCertificateForm = ({ setIsLoading(true); try { const configs = await alertConfigService.getAlertConfigurations(); - console.log("Fetched notification channels:", configs); + // console.log("Fetched notification channels:", configs); // Only include enabled channels const enabledConfigs = configs.filter(config => { // Handle the possibility of enabled being a string @@ -66,7 +66,7 @@ export const AddSSLCertificateForm = ({ }); setAlertConfigs(enabledConfigs); } catch (error) { - console.error("Error fetching notification channels:", error); + // console.error("Error fetching notification channels:", error); toast.error(t('failedToLoadCertificates')); } finally { setIsLoading(false); @@ -90,7 +90,7 @@ export const AddSSLCertificateForm = ({ await onSubmit(certData); form.reset(); } catch (error) { - console.error("Error adding SSL certificate:", error); + // console.error("Error adding SSL certificate:", error); toast.error(t('failedToAddCertificate')); } }; diff --git a/application/src/components/ssl-domain/EditSSLCertificateForm.tsx b/application/src/components/ssl-domain/EditSSLCertificateForm.tsx index 0e1cad1..a53a1a2 100644 --- a/application/src/components/ssl-domain/EditSSLCertificateForm.tsx +++ b/application/src/components/ssl-domain/EditSSLCertificateForm.tsx @@ -52,7 +52,7 @@ export const EditSSLCertificateForm = ({ certificate, onSubmit, onCancel, isPend setIsLoading(true); try { const configs = await alertConfigService.getAlertConfigurations(); - console.log("Fetched notification channels:", configs); + // console.log("Fetched notification channels:", configs); // Only include enabled channels const enabledConfigs = configs.filter(config => { // Handle the possibility of enabled being a string @@ -64,7 +64,7 @@ export const EditSSLCertificateForm = ({ certificate, onSubmit, onCancel, isPend }); setAlertConfigs(enabledConfigs); } catch (error) { - console.error("Error fetching notification channels:", error); + // console.error("Error fetching notification channels:", error); toast.error(t('failedToLoadCertificates')); } finally { setIsLoading(false); diff --git a/application/src/components/ssl-domain/SSLDomainContent.tsx b/application/src/components/ssl-domain/SSLDomainContent.tsx index bc7af16..6769462 100644 --- a/application/src/components/ssl-domain/SSLDomainContent.tsx +++ b/application/src/components/ssl-domain/SSLDomainContent.tsx @@ -30,12 +30,12 @@ export const SSLDomainContent = () => { queryKey: ['ssl-certificates'], queryFn: async () => { try { - console.log("Fetching SSL certificates from SSLDomainContent..."); + // console.log("Fetching SSL certificates from SSLDomainContent..."); const result = await fetchSSLCertificates(); - console.log("Received SSL certificates:", result); + // console.log("Received SSL certificates:", result); return result; } catch (error) { - console.error("Error fetching certificates:", error); + // console.error("Error fetching certificates:", error); toast.error(t('failedToLoadCertificates')); throw error; } @@ -53,7 +53,7 @@ export const SSLDomainContent = () => { toast.success(t('sslCertificateAdded')); }, onError: (error) => { - console.error("Error adding SSL certificate:", error); + // console.error("Error adding SSL certificate:", error); toast.error(error instanceof Error ? error.message : t('failedToAddCertificate')); } }); @@ -61,7 +61,7 @@ export const SSLDomainContent = () => { // Edit certificate mutation - Updated to ensure thresholds are properly updated const editMutation = useMutation({ mutationFn: async (certificate: SSLCertificate) => { - console.log("Updating certificate with data:", certificate); + // console.log("Updating certificate with data:", certificate); // Create the update data object const updateData = { @@ -70,12 +70,12 @@ export const SSLDomainContent = () => { notification_channel: certificate.notification_channel, }; - console.log("Update data to be sent:", updateData); + // console.log("Update data to be sent:", updateData); // Update certificate in the database using PocketBase directly const updated = await pb.collection('ssl_certificates').update(certificate.id, updateData); - console.log("PocketBase update response:", updated); + // console.log("PocketBase update response:", updated); // After updating the settings, refresh the certificate to ensure it's up to date // This will also check if notification needs to be sent based on updated thresholds @@ -90,7 +90,7 @@ export const SSLDomainContent = () => { toast.success(t('sslCertificateUpdated')); }, onError: (error) => { - console.error("Error updating SSL certificate:", error); + // console.error("Error updating SSL certificate:", error); toast.error(error instanceof Error ? error.message : t('failedToUpdateCertificate')); } }); @@ -103,7 +103,7 @@ export const SSLDomainContent = () => { toast.success(t('sslCertificateDeleted')); }, onError: (error) => { - console.error("Error deleting SSL certificate:", error); + // console.error("Error deleting SSL certificate:", error); toast.error(error instanceof Error ? error.message : t('failedToDeleteCertificate')); } }); @@ -117,7 +117,7 @@ export const SSLDomainContent = () => { toast.success(t('sslCertificateRefreshed').replace('{domain}', data.domain)); }, onError: (error) => { - console.error("Error refreshing SSL certificate:", error); + // console.error("Error refreshing SSL certificate:", error); let errorMessage = t('failedToCheckCertificate'); @@ -149,7 +149,7 @@ export const SSLDomainContent = () => { } }, onError: (error) => { - console.error("Error refreshing all certificates:", error); + // console.error("Error refreshing all certificates:", error); toast.error(t('failedToCheckCertificate')); setIsRefreshingAll(false); @@ -174,7 +174,7 @@ export const SSLDomainContent = () => { }; const handleUpdateCertificate = (certificate: SSLCertificate) => { - console.log("Handling certificate update with data:", certificate); + // console.log("Handling certificate update with data:", certificate); editMutation.mutate(certificate); }; diff --git a/application/src/components/ui/badge.tsx b/application/src/components/ui/badge.tsx index f000e3e..8963a4d 100644 --- a/application/src/components/ui/badge.tsx +++ b/application/src/components/ui/badge.tsx @@ -1,3 +1,4 @@ + import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" diff --git a/application/src/hooks/useSystemSettings.tsx b/application/src/hooks/useSystemSettings.tsx index f7f37f4..31bdb82 100644 --- a/application/src/hooks/useSystemSettings.tsx +++ b/application/src/hooks/useSystemSettings.tsx @@ -29,7 +29,7 @@ export function useSystemSettings() { queryKey: ['generalSettings'], queryFn: async (): Promise => { try { - console.log('Fetching settings from API...'); + // console.log('Fetching settings from API...'); const response = await fetch('/api/settings', { method: 'POST', headers: { @@ -38,14 +38,14 @@ export function useSystemSettings() { body: JSON.stringify({ action: 'getSettings' }) }); - console.log('API response status:', response.status); + // console.log('API response status:', response.status); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result: ApiResponse = await response.json(); - console.log('API response data:', result); + // console.log('API response data:', result); if (!result.success) { throw new Error(result.message || 'Failed to fetch settings'); @@ -53,7 +53,7 @@ export function useSystemSettings() { return result.data || null; } catch (error) { - console.error('Error fetching settings:', error); + // console.error('Error fetching settings:', error); toast({ title: t("errorFetchingSettings", "settings"), description: error instanceof Error ? error.message : String(error), @@ -68,7 +68,7 @@ export function useSystemSettings() { // Update settings mutation const updateSettingsMutation = useMutation({ mutationFn: async (updatedSettings: GeneralSettings): Promise => { - console.log('Updating settings:', updatedSettings); + // console.log('Updating settings:', updatedSettings); const response = await fetch('/api/settings', { method: 'POST', headers: { @@ -101,7 +101,7 @@ export function useSystemSettings() { }); }, onError: (error) => { - console.error('Error updating settings:', error); + // console.error('Error updating settings:', error); toast({ title: t("errorSavingSettings", "settings"), description: error instanceof Error ? error.message : String(error), @@ -113,7 +113,7 @@ export function useSystemSettings() { // Test email connection const testEmailConnectionMutation = useMutation({ mutationFn: async (smtpConfig: any): Promise<{success: boolean, message: string}> => { - console.log('Testing email connection:', smtpConfig); + // console.log('Testing email connection:', smtpConfig); const response = await fetch('/api/settings', { method: 'POST', headers: { @@ -143,7 +143,7 @@ export function useSystemSettings() { }); }, onError: (error) => { - console.error('Error testing connection:', error); + // console.error('Error testing connection:', error); toast({ title: t("connectionFailed", "settings"), description: error instanceof Error ? error.message : String(error), diff --git a/application/src/pages/Dashboard.tsx b/application/src/pages/Dashboard.tsx index 34437ce..a61dd8e 100644 --- a/application/src/pages/Dashboard.tsx +++ b/application/src/pages/Dashboard.tsx @@ -20,7 +20,7 @@ const Dashboard = () => { // For debugging user data useEffect(() => { - console.log("Current user data:", currentUser); + // console.log("Current user data:", currentUser); }, [currentUser]); // Handle logout @@ -40,7 +40,7 @@ const Dashboard = () => { useEffect(() => { const startActiveServices = async () => { await serviceService.startAllActiveServices(); - console.log("Active services monitoring started"); + // console.log("Active services monitoring started"); }; startActiveServices(); diff --git a/application/src/pages/SslDomain.tsx b/application/src/pages/SslDomain.tsx index a7de6ee..5b15bc7 100644 --- a/application/src/pages/SslDomain.tsx +++ b/application/src/pages/SslDomain.tsx @@ -26,13 +26,13 @@ const SslDomain = () => { const { data: certificates = [], isLoading, error, refetch } = useQuery({ queryKey: ['ssl-certificates'], queryFn: async () => { - console.log("Fetching SSL certificates from SslDomain page..."); + // console.log("Fetching SSL certificates from SslDomain page..."); try { const result = await fetchSSLCertificates(); - console.log("SSL certificates fetch successful, count:", result.length); + // console.log("SSL certificates fetch successful, count:", result.length); return result; } catch (err) { - console.error("Error fetching SSL certificates from page:", err); + // console.error("Error fetching SSL certificates from page:", err); throw err; } }, @@ -46,7 +46,7 @@ const SslDomain = () => { const checkCertificates = async () => { // Check if we should run daily check if (shouldRunDailyCheck()) { - console.log("Running daily SSL certificate check..."); + // console.log("Running daily SSL certificate check..."); await checkAllCertificatesAndNotify(); // Refresh certificate list after daily check refetch(); diff --git a/application/src/services/alertConfigService.ts b/application/src/services/alertConfigService.ts index fa00ff1..51c07e9 100644 --- a/application/src/services/alertConfigService.ts +++ b/application/src/services/alertConfigService.ts @@ -22,13 +22,13 @@ export interface AlertConfiguration { export const alertConfigService = { async getAlertConfigurations(): Promise { - console.info("Fetching alert configurations"); + // console.info("Fetching alert configurations"); try { const response = await pb.collection('alert_configurations').getList(1, 50); - console.info("Alert configurations response:", response); + // console.info("Alert configurations response:", response); return response.items as AlertConfiguration[]; } catch (error) { - console.error("Error fetching alert configurations:", error); + // console.error("Error fetching alert configurations:", error); toast({ title: "Error", description: "Failed to load notification settings", @@ -39,17 +39,17 @@ export const alertConfigService = { }, async createAlertConfiguration(config: Omit): Promise { - console.info("Creating alert configuration:", config); + // console.info("Creating alert configuration:", config); try { const result = await pb.collection('alert_configurations').create(config); - console.info("Alert configuration created:", result); + // console.info("Alert configuration created:", result); toast({ title: "Success", description: "Notification settings saved successfully", }); return result as AlertConfiguration; } catch (error) { - console.error("Error creating alert configuration:", error); + // console.error("Error creating alert configuration:", error); toast({ title: "Error", description: "Failed to save notification settings", @@ -60,17 +60,17 @@ export const alertConfigService = { }, async updateAlertConfiguration(id: string, config: Partial): Promise { - console.info(`Updating alert configuration ${id}:`, config); + // console.info(`Updating alert configuration ${id}:`, config); try { const result = await pb.collection('alert_configurations').update(id, config); - console.info("Alert configuration updated:", result); + // console.info("Alert configuration updated:", result); toast({ title: "Success", description: "Notification settings updated successfully", }); return result as AlertConfiguration; } catch (error) { - console.error("Error updating alert configuration:", error); + // console.error("Error updating alert configuration:", error); toast({ title: "Error", description: "Failed to update notification settings", @@ -81,17 +81,17 @@ export const alertConfigService = { }, async deleteAlertConfiguration(id: string): Promise { - console.info(`Deleting alert configuration ${id}`); + // console.info(`Deleting alert configuration ${id}`); try { await pb.collection('alert_configurations').delete(id); - console.info("Alert configuration deleted"); + // console.info("Alert configuration deleted"); toast({ title: "Success", description: "Notification channel removed", }); return true; } catch (error) { - console.error("Error deleting alert configuration:", error); + // console.error("Error deleting alert configuration:", error); toast({ title: "Error", description: "Failed to remove notification channel", diff --git a/application/src/services/authService.ts b/application/src/services/authService.ts index a87d706..bfd64c8 100644 --- a/application/src/services/authService.ts +++ b/application/src/services/authService.ts @@ -19,7 +19,7 @@ export const authService = { try { // First try to login as a regular admin user try { - console.log("Attempting to login as admin user"); + // console.log("Attempting to login as admin user"); const authData = await pb.collection('users').authWithPassword(email, password); return { @@ -30,7 +30,7 @@ export const authService = { role: authData.record.role || "admin" }; } catch (error) { - console.log("Failed to login as admin, trying as superadmin", error); + // console.log("Failed to login as admin, trying as superadmin", error); // If regular user login fails, try superadmin const authData = await pb.collection('_superusers').authWithPassword(email, password); @@ -44,7 +44,7 @@ export const authService = { }; } } catch (error) { - console.error('Login failed:', error); + // console.error('Login failed:', error); throw new Error('Authentication failed. Please check your credentials.'); } }, @@ -63,7 +63,7 @@ export const authService = { if (!userData) return null; // Log the full user data for debugging - console.log("Raw user data from authStore:", userData); + //console.log("Raw user data from authStore:", userData); // Determine if this is a superadmin by checking the collection name const isSuperAdmin = userData.collectionName === '_superusers'; @@ -90,13 +90,13 @@ export const authService = { try { // Fetch the latest user data from the server const userId = (pb.authStore.model as any).id; - console.log("Refreshing user data for ID:", userId); + // console.log("Refreshing user data for ID:", userId); // Use the getOne method directly to refresh the auth store await pb.collection('users').getOne(userId); - console.log("User data refreshed successfully"); + // console.log("User data refreshed successfully"); } catch (error) { - console.error('Failed to refresh user data:', error); + // console.error('Failed to refresh user data:', error); } } }; \ No newline at end of file diff --git a/application/src/services/incident/incidentCache.ts b/application/src/services/incident/incidentCache.ts index e34651b..9094bf3 100644 --- a/application/src/services/incident/incidentCache.ts +++ b/application/src/services/incident/incidentCache.ts @@ -3,12 +3,12 @@ import { IncidentItem } from './types'; // Export functions to update and invalidate the cache export const updateCache = (data: IncidentItem[]) => { - console.log(`Updating cache with ${data.length} incidents`); +// console.log(`Updating cache with ${data.length} incidents`); // The actual cache is now maintained in incidentFetch.ts }; // Reset cache and request state export const invalidateCache = () => { - console.log('Invalidating incidents cache'); +// console.log('Invalidating incidents cache'); // The invalidation is handled in incidentFetch.ts implementation }; diff --git a/application/src/services/incident/incidentFetch.ts b/application/src/services/incident/incidentFetch.ts index ca1ea9b..8db21c8 100644 --- a/application/src/services/incident/incidentFetch.ts +++ b/application/src/services/incident/incidentFetch.ts @@ -25,7 +25,7 @@ export const isCacheValid = (): boolean => { export const getAllIncidents = async (forceRefresh = false): Promise => { // If a request is in progress, wait for it to complete rather than making a new one if (isRequestInProgress) { - console.log('Request already in progress, waiting for completion'); + // console.log('Request already in progress, waiting for completion'); try { if (pendingRequest) { await pendingRequest; @@ -39,12 +39,12 @@ export const getAllIncidents = async (forceRefresh = false): Promise => { try { - console.log(`Fetching incident with ID: ${id}`); + // console.log(`Fetching incident with ID: ${id}`); // First check if the incident exists in the cache if (isCacheValid() && incidentsCache) { const cachedIncident = incidentsCache.data.find(incident => incident.id === id); if (cachedIncident) { - console.log('Incident found in cache'); + // console.log('Incident found in cache'); return cachedIncident; } } @@ -136,7 +136,7 @@ export const getIncidentById = async (id: string): Promise return normalizedIncident; } catch (error) { - console.error(`Error fetching incident with ID ${id}:`, error); + // console.error(`Error fetching incident with ID ${id}:`, error); if (error instanceof Error) { throw new Error(`Failed to fetch incident: ${error.message}`); diff --git a/application/src/services/maintenance/maintenanceNotificationService.ts b/application/src/services/maintenance/maintenanceNotificationService.ts index 75e77cc..8c58f20 100644 --- a/application/src/services/maintenance/maintenanceNotificationService.ts +++ b/application/src/services/maintenance/maintenanceNotificationService.ts @@ -16,20 +16,20 @@ export const maintenanceNotificationService = { */ async sendMaintenanceNotification({ maintenance, notificationType }: NotificationParams): Promise { try { - console.log(`Preparing to send ${notificationType} notification for maintenance: ${maintenance.title}`); + // console.log(`Preparing to send ${notificationType} notification for maintenance: ${maintenance.title}`); // Get notification channel ID - try both fields let notificationChannelId = maintenance.notification_channel_id; // If notification_channel_id is empty, try to use notification_id if (!notificationChannelId && maintenance.notification_id) { - console.log(`No notification_channel_id found, using notification_id: ${maintenance.notification_id}`); + // console.log(`No notification_channel_id found, using notification_id: ${maintenance.notification_id}`); notificationChannelId = maintenance.notification_id; } // Check if maintenance has notification channel configured if (!notificationChannelId) { - console.log("No notification channel configured for this maintenance"); + // console.log("No notification channel configured for this maintenance"); return false; } @@ -41,19 +41,19 @@ export const maintenanceNotificationService = { const config = await pb.collection('alert_configurations').getOne(notificationChannelId); notificationConfig = config as unknown as AlertConfiguration; } catch (error) { - console.error("Failed to fetch notification configuration:", error); + // console.error("Failed to fetch notification configuration:", error); return false; } if (!notificationConfig.enabled) { - console.log("Notification channel is disabled"); + // console.log("Notification channel is disabled"); return false; } // Create notification message based on type const message = this.generateMaintenanceMessage(maintenance, notificationType); - console.log(`Sending ${notificationConfig.notification_type} notification with message: ${message}`); + // console.log(`Sending ${notificationConfig.notification_type} notification with message: ${message}`); // Send notification based on channel type if (notificationConfig.notification_type === 'telegram') { @@ -62,10 +62,10 @@ export const maintenanceNotificationService = { // Add more notification types here as needed - console.log(`Unsupported notification type: ${notificationConfig.notification_type}`); + // console.log(`Unsupported notification type: ${notificationConfig.notification_type}`); return false; } catch (error) { - console.error("Error sending maintenance notification:", error); + // console.error("Error sending maintenance notification:", error); return false; } }, @@ -115,12 +115,12 @@ export const maintenanceNotificationService = { // Set up scheduled maintenance notifications export const setupMaintenanceNotificationsScheduler = () => { - console.log("Setting up maintenance notifications scheduler"); + // console.log("Setting up maintenance notifications scheduler"); // Check every minute for maintenance that needs notifications const checkInterval = setInterval(async () => { try { - console.log("Checking for maintenance notifications to send..."); + // console.log("Checking for maintenance notifications to send..."); const now = new Date(); // Fetch upcoming and ongoing maintenance @@ -143,7 +143,7 @@ export const setupMaintenanceNotificationsScheduler = () => { startTime <= new Date(now.getTime() + 60000) && startTime > new Date(now.getTime() - 60000)) { - console.log(`Maintenance ${maintenance.title} is starting now, sending notification`); + // console.log(`Maintenance ${maintenance.title} is starting now, sending notification`); await maintenanceNotificationService.sendMaintenanceNotification({ maintenance, notificationType: 'start' @@ -160,7 +160,7 @@ export const setupMaintenanceNotificationsScheduler = () => { endTime <= new Date(now.getTime() + 60000) && endTime > new Date(now.getTime() - 60000)) { - console.log(`Maintenance ${maintenance.title} is ending now, sending notification`); + // console.log(`Maintenance ${maintenance.title} is ending now, sending notification`); await maintenanceNotificationService.sendMaintenanceNotification({ maintenance, notificationType: 'end' @@ -173,7 +173,7 @@ export const setupMaintenanceNotificationsScheduler = () => { } } } catch (error) { - console.error("Error checking maintenance notifications:", error); + // console.error("Error checking maintenance notifications:", error); } }, 60000); // Check every minute @@ -186,7 +186,7 @@ let notificationScheduler: NodeJS.Timeout | null = null; export const initMaintenanceNotifications = () => { if (notificationScheduler === null) { notificationScheduler = setupMaintenanceNotificationsScheduler(); - console.log("Maintenance notifications scheduler initialized"); + // console.log("Maintenance notifications scheduler initialized"); } }; @@ -194,6 +194,6 @@ export const stopMaintenanceNotifications = () => { if (notificationScheduler !== null) { clearInterval(notificationScheduler); notificationScheduler = null; - console.log("Maintenance notifications scheduler stopped"); + // console.log("Maintenance notifications scheduler stopped"); } }; diff --git a/application/src/services/monitoring/service-status/startAllServices.ts b/application/src/services/monitoring/service-status/startAllServices.ts index 731e341..51334ec 100644 --- a/application/src/services/monitoring/service-status/startAllServices.ts +++ b/application/src/services/monitoring/service-status/startAllServices.ts @@ -12,13 +12,13 @@ export async function startAllActiveServices(): Promise { filter: 'status != "paused"' }); - console.log(`Starting monitoring for ${result.items.length} active services`); + // console.log(`Starting monitoring for ${result.items.length} active services`); // Start monitoring each active service for (const service of result.items) { await startMonitoringService(service.id); } } catch (error) { - console.error("Error starting all active services:", error); + // console.error("Error starting all active services:", error); } } diff --git a/application/src/services/monitoring/service-status/startMonitoring.ts b/application/src/services/monitoring/service-status/startMonitoring.ts index 3a156ad..a1d7a11 100644 --- a/application/src/services/monitoring/service-status/startMonitoring.ts +++ b/application/src/services/monitoring/service-status/startMonitoring.ts @@ -9,7 +9,7 @@ export async function startMonitoringService(serviceId: string): Promise { try { // First check if the service is already being monitored if (monitoringIntervals.has(serviceId)) { - console.log(`Service ${serviceId} is already being monitored`); + // console.log(`Service ${serviceId} is already being monitored`); return; } @@ -18,11 +18,11 @@ export async function startMonitoringService(serviceId: string): Promise { // If service was manually paused, don't auto-resume if (service.status === "paused") { - console.log(`Service ${serviceId} (${service.name}) is paused. Not starting monitoring.`); + // console.log(`Service ${serviceId} (${service.name}) is paused. Not starting monitoring.`); return; } - console.log(`Starting monitoring for service ${serviceId} (${service.name})`); + // console.log(`Starting monitoring for service ${serviceId} (${service.name})`); // Update the service status to active/up in the database await pb.collection('services').update(serviceId, { @@ -32,18 +32,18 @@ export async function startMonitoringService(serviceId: string): Promise { // The actual service checking is now handled by the Go microservice // This frontend service just tracks the monitoring state const intervalMs = (service.heartbeat_interval || 60) * 1000; - console.log(`Service ${service.name} monitoring delegated to backend service`); + // console.log(`Service ${service.name} monitoring delegated to backend service`); // Store a placeholder interval to track that this service is being monitored const intervalId = window.setInterval(() => { - console.log(`Monitoring active for service ${service.name} (handled by backend)`); + // console.log(`Monitoring active for service ${service.name} (handled by backend)`); }, intervalMs); // Store the interval ID for this service monitoringIntervals.set(serviceId, intervalId); - console.log(`Monitoring registered for service ${serviceId}`); + // console.log(`Monitoring registered for service ${serviceId}`); } catch (error) { - console.error("Error starting service monitoring:", error); + // console.error("Error starting service monitoring:", error); } } \ No newline at end of file diff --git a/application/src/services/serviceService.ts b/application/src/services/serviceService.ts index 4a00345..5bb8327 100644 --- a/application/src/services/serviceService.ts +++ b/application/src/services/serviceService.ts @@ -1,4 +1,3 @@ - import { pb } from '@/lib/pocketbase'; import { Service, CreateServiceParams, UptimeData } from '@/types/service.types'; import { monitoringService } from './monitoring'; @@ -28,6 +27,7 @@ export const serviceService = { interval: item.heartbeat_interval || item.interval || 60, retries: item.max_retries || item.retries || 3, notificationChannel: item.notification_id, + notification_status: item.notification_status || "disabled", alertTemplate: item.template_id, muteAlerts: item.alerts === "muted", // Convert string to boolean for compatibility alerts: item.alerts || "unmuted", // Store actual database field @@ -39,12 +39,12 @@ export const serviceService = { regional_monitoring_enabled: item.regional_status === "enabled", // Backward compatibility })); } catch (error) { - console.error("Error fetching services:", error); + // console.error("Error fetching services:", error); throw new Error('Failed to load services data.'); } }, - async createService(params: CreateServiceParams): Promise { + async createService(params: any): Promise { try { // Convert service type to lowercase to avoid validation issues const serviceType = params.type.toLowerCase(); @@ -61,7 +61,10 @@ export const serviceService = { last_checked: new Date().toLocaleString(), heartbeat_interval: params.interval, max_retries: params.retries, - notification_id: params.notificationChannel, + notification_status: params.notificationStatus || "disabled", + notification_id: params.notificationChannels && params.notificationChannels.length > 0 + ? params.notificationChannels[0] // Store first channel for backward compatibility + : null, template_id: params.alertTemplate, // Regional monitoring fields - use regional_status regional_status: params.regionalStatus || "disabled", @@ -98,6 +101,7 @@ export const serviceService = { interval: record.heartbeat_interval || 60, retries: record.max_retries || 3, notificationChannel: record.notification_id, + notification_status: record.notification_status || "disabled", alertTemplate: record.template_id, regional_status: record.regional_status || "disabled", regional_monitoring_enabled: record.regional_status === "enabled", @@ -115,7 +119,7 @@ export const serviceService = { } }, - async updateService(id: string, params: CreateServiceParams): Promise { + async updateService(id: string, params: any): Promise { try { // Convert service type to lowercase to avoid validation issues const serviceType = params.type.toLowerCase(); @@ -128,7 +132,10 @@ export const serviceService = { service_type: serviceType, heartbeat_interval: params.interval, max_retries: params.retries, - notification_id: params.notificationChannel || null, + notification_status: params.notificationStatus || "disabled", + notification_id: params.notificationChannels && params.notificationChannels.length > 0 + ? params.notificationChannels[0] // Store first channel for backward compatibility + : null, template_id: params.alertTemplate || null, // Regional monitoring fields - use regional_status regional_status: params.regionalStatus || "disabled", @@ -172,6 +179,7 @@ export const serviceService = { interval: record.heartbeat_interval || 60, retries: record.max_retries || 3, notificationChannel: record.notification_id, + notification_status: record.notification_status || "disabled", alertTemplate: record.template_id, regional_status: record.regional_status || "disabled", regional_monitoring_enabled: record.regional_status === "enabled", diff --git a/application/src/services/ssl/sslFetchService.ts b/application/src/services/ssl/sslFetchService.ts index 3846236..9704914 100644 --- a/application/src/services/ssl/sslFetchService.ts +++ b/application/src/services/ssl/sslFetchService.ts @@ -8,7 +8,7 @@ import { toast } from "sonner"; */ export const fetchSSLCertificates = async (): Promise => { try { - console.log("Fetching SSL certificates from PocketBase..."); + // console.log("Fetching SSL certificates from PocketBase..."); // Using the direct API path to fetch SSL certificates const endpoint = "/api/collections/ssl_certificates/records"; @@ -23,7 +23,7 @@ export const fetchSSLCertificates = async (): Promise => { const queryString = new URLSearchParams(params as any).toString(); const fullEndpoint = `${endpoint}?${queryString}`; - console.log("Fetching SSL certificates from:", fullEndpoint); + // console.log("Fetching SSL certificates from:", fullEndpoint); const response = await pb.send(fullEndpoint, { method: "GET", headers: { @@ -39,14 +39,14 @@ export const fetchSSLCertificates = async (): Promise => { throw new Error("Invalid response format from PocketBase API"); } - console.log("Received SSL certificates:", response.items.length); + // console.log("Received SSL certificates:", response.items.length); // Map items to SSLCertificate[] type with validation return response.items.map(item => { const cert = item as SSLCertificate; // Log certificate details for debugging - console.log(`Certificate for ${cert.domain}: Issued by ${cert.issuer_o}, Days left: ${cert.days_left}`); + // console.log(`Certificate for ${cert.domain}: Issued by ${cert.issuer_o}, Days left: ${cert.days_left}`); // Ensure dates are valid try { @@ -54,7 +54,7 @@ export const fetchSSLCertificates = async (): Promise => { if (cert.valid_till) new Date(cert.valid_till).toISOString(); if (cert.last_notified) new Date(cert.last_notified).toISOString(); } catch (e) { - console.warn("Invalid date found in certificate", cert.id, e); + // console.warn("Invalid date found in certificate", cert.id, e); // Fix invalid dates if needed if (cert.valid_from && isNaN(new Date(cert.valid_from).getTime())) { cert.valid_from = new Date().toISOString(); @@ -74,7 +74,7 @@ export const fetchSSLCertificates = async (): Promise => { const diffTime = expirationDate.getTime() - currentDate.getTime(); cert.days_left = Math.ceil(diffTime / (1000 * 3600 * 24)); } catch (e) { - console.warn("Error calculating days_left for certificate", cert.id, e); + // console.warn("Error calculating days_left for certificate", cert.id, e); cert.days_left = 0; } } @@ -82,7 +82,7 @@ export const fetchSSLCertificates = async (): Promise => { return cert; }); } catch (error) { - console.error("Error fetching SSL certificates:", error); + // console.error("Error fetching SSL certificates:", error); toast.error("Failed to fetch SSL certificates. Please try again later."); throw error; } diff --git a/application/src/services/uptimeService.ts b/application/src/services/uptimeService.ts index 989895a..2da6452 100644 --- a/application/src/services/uptimeService.ts +++ b/application/src/services/uptimeService.ts @@ -31,7 +31,7 @@ const getCollectionForServiceType = (serviceType: string): string => { export const uptimeService = { async recordUptimeData(data: UptimeData): Promise { try { - console.log(`Recording uptime data for service ${data.serviceId || data.service_id}: Status ${data.status}, Response time: ${data.responseTime}ms`); + // console.log(`Recording uptime data for service ${data.serviceId || data.service_id}: Status ${data.status}, Response time: ${data.responseTime}ms`); const options = { $autoCancel: false, @@ -50,9 +50,9 @@ export const uptimeService = { const keysToDelete = Array.from(uptimeCache.keys()).filter(key => key.includes(`uptime_${serviceId}`)); keysToDelete.forEach(key => uptimeCache.delete(key)); - console.log(`Uptime data recorded successfully with ID: ${record.id}`); + // console.log(`Uptime data recorded successfully with ID: ${record.id}`); } catch (error) { - console.error("Error recording uptime data:", error); + // console.error("Error recording uptime data:", error); throw new Error(`Failed to record uptime data: ${error}`); } }, @@ -66,7 +66,7 @@ export const uptimeService = { ): Promise { try { if (!serviceId) { - console.log('No serviceId provided to getUptimeHistory'); + // console.log('No serviceId provided to getUptimeHistory'); return []; } @@ -75,13 +75,13 @@ export const uptimeService = { // Check cache const cached = uptimeCache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) { - console.log(`Using cached uptime history for service ${serviceId}`); + // console.log(`Using cached uptime history for service ${serviceId}`); return cached.data; } // Determine the correct collection based on service type const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data'; - console.log(`Fetching default uptime history for service ${serviceId} from collection ${collection}, limit: ${limit}`); + // console.log(`Fetching default uptime history for service ${serviceId} from collection ${collection}, limit: ${limit}`); // Build filter to get records for specific service_id let filter = `service_id='${serviceId}'`; @@ -91,7 +91,7 @@ export const uptimeService = { const startUTC = startDate.toISOString(); const endUTC = endDate.toISOString(); - console.log(`Date filter: ${startUTC} to ${endUTC}`); + // console.log(`Date filter: ${startUTC} to ${endUTC}`); filter += ` && timestamp >= "${startUTC}" && timestamp <= "${endUTC}"`; } @@ -102,16 +102,16 @@ export const uptimeService = { $cancelKey: `uptime_history_${serviceId}_${Date.now()}` }; - console.log(`Filter query for default data: ${filter} on collection: ${collection}`); + // console.log(`Filter query for default data: ${filter} on collection: ${collection}`); const response = await pb.collection(collection).getList(1, limit, options); - console.log(`Fetched ${response.items.length} records for service ${serviceId} from ${collection}`); + // console.log(`Fetched ${response.items.length} records for service ${serviceId} from ${collection}`); if (response.items.length > 0) { - console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`); + // console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`); } else { - console.log(`No records found for service_id '${serviceId}' in collection: ${collection}`); + // console.log(`No records found for service_id '${serviceId}' in collection: ${collection}`); } // Transform the response items to UptimeData format @@ -137,18 +137,18 @@ export const uptimeService = { return uptimeData; } catch (error) { - console.error(`Error fetching uptime history for service ${serviceId}:`, error); + // console.error(`Error fetching uptime history for service ${serviceId}:`, error); // Try to return cached data as fallback const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_default`; const cached = uptimeCache.get(cacheKey); if (cached) { - console.log(`Using expired cached data for service ${serviceId} due to fetch error`); + // console.log(`Using expired cached data for service ${serviceId} due to fetch error`); return cached.data; } // Return empty array instead of throwing to prevent UI crashes - console.log(`Returning empty array for service ${serviceId} due to fetch error`); + // console.log(`Returning empty array for service ${serviceId} due to fetch error`); return []; } }, @@ -164,7 +164,7 @@ export const uptimeService = { ): Promise { try { if (!regionName || !agentId) { - console.log('No region name or agent ID provided for regional query'); + // console.log('No region name or agent ID provided for regional query'); return []; } @@ -173,13 +173,13 @@ export const uptimeService = { // Check cache const cached = uptimeCache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) { - console.log(`Using cached regional uptime history for service ${serviceId}`); + // console.log(`Using cached regional uptime history for service ${serviceId}`); return cached.data; } // Determine the correct collection based on service type const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data'; - console.log(`Fetching regional uptime history from collection: ${collection} for service: ${serviceId}, region: ${regionName}, agent: ${agentId}`); + // console.log(`Fetching regional uptime history from collection: ${collection} for service: ${serviceId}, region: ${regionName}, agent: ${agentId}`); // Build filter for regional agent data let filter = `service_id="${serviceId}" && region_name="${regionName}" && agent_id="${agentId}"`; @@ -190,7 +190,7 @@ export const uptimeService = { filter += ` && timestamp>="${startISO}" && timestamp<="${endISO}"`; } - console.log(`Regional filter query: ${filter} on collection: ${collection}`); + // console.log(`Regional filter query: ${filter} on collection: ${collection}`); const records = await pb.collection(collection).getList(1, limit, { sort: '-timestamp', @@ -199,7 +199,7 @@ export const uptimeService = { $cancelKey: `regional_uptime_history_${serviceId}_${Date.now()}` }); - console.log(`Retrieved ${records.items.length} regional uptime records from ${collection} for region ${regionName}, agent ${agentId}`); + // console.log(`Retrieved ${records.items.length} regional uptime records from ${collection} for region ${regionName}, agent ${agentId}`); const uptimeData = records.items.map(item => ({ id: item.id, @@ -224,7 +224,7 @@ export const uptimeService = { return uptimeData; } catch (error) { const collectionForError = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data'; - console.error(`Error fetching regional uptime history from ${collectionForError}:`, error); + // console.error(`Error fetching regional uptime history from ${collectionForError}:`, error); return []; } } diff --git a/application/src/services/userService.ts b/application/src/services/userService.ts index 73e41bb..aceeb81 100644 --- a/application/src/services/userService.ts +++ b/application/src/services/userService.ts @@ -58,7 +58,7 @@ const convertToUserType = (record: any, role: string = "admin"): User => { export const userService = { async getUsers(): Promise { try { - console.log("Calling getUsers API"); + // console.log("Calling getUsers API"); // Get both regular users and superadmins const regularUsers = await pb.collection('users').getList(1, 50, { @@ -71,9 +71,9 @@ export const userService = { superadminUsers = await pb.collection('_superusers').getList(1, 50, { sort: 'created', }); - console.log("Successfully fetched superadmin users:", superadminUsers); + // console.log("Successfully fetched superadmin users:", superadminUsers); } catch (error) { - console.log("No superadmin collection or access rights:", error); + // console.log("No superadmin collection or access rights:", error); } // Combine both user types and mark superadmins @@ -82,39 +82,39 @@ export const userService = { ...superadminUsers.items.map((user: any) => convertToUserType(user, "superadmin")) ]; - console.log("Combined users list:", allUsers); + // console.log("Combined users list:", allUsers); return allUsers; } catch (error) { - console.error("Failed to fetch users:", error); + // console.error("Failed to fetch users:", error); return null; } }, async getUser(id: string): Promise { try { - console.log(`Fetching user with ID: ${id}`); + // console.log(`Fetching user with ID: ${id}`); // Try fetching from regular users first try { const user = await pb.collection('users').getOne(id); - console.log("User fetch result (regular user):", user); + // console.log("User fetch result (regular user):", user); return convertToUserType(user, user.role || "admin"); } catch (error) { - console.log("User not found in regular users, trying superadmin collection"); + // console.log("User not found in regular users, trying superadmin collection"); } // If not found, try in superadmins try { const user = await pb.collection('_superusers').getOne(id); - console.log("User fetch result (superadmin):", user); + // console.log("User fetch result (superadmin):", user); return convertToUserType(user, "superadmin"); } catch (error) { - console.log("User not found in superadmin collection either"); + // console.log("User not found in superadmin collection either"); return null; } } catch (error) { - console.error(`Failed to fetch user ${id}:`, error); + // console.error(`Failed to fetch user ${id}:`, error); return null; } }, @@ -130,11 +130,11 @@ export const userService = { } }); - console.log("Updating user with clean data:", cleanData); + // console.log("Updating user with clean data:", cleanData); // If there's nothing to update, return the current user if (Object.keys(cleanData).length === 0) { - console.log("No changes to update"); + // console.log("No changes to update"); const currentUser = await this.getUser(id); return currentUser; } @@ -197,16 +197,16 @@ export const userService = { await pb.collection('_superusers').delete(id); updatedUser = convertToUserType(newRegularUser, "admin"); } - console.log("User transferred between collections due to role change"); + // console.log("User transferred between collections due to role change"); } catch (error) { - console.error("Failed to transfer user between collections:", error); + // console.error("Failed to transfer user between collections:", error); throw new Error("Failed to change user role: " + (error instanceof Error ? error.message : "Unknown error")); } } else { // Regular update without changing collections if (Object.keys(cleanData).length > 0) { - console.log("Final update payload to PocketBase:", cleanData); + // console.log("Final update payload to PocketBase:", cleanData); try { // Use the appropriate collection @@ -214,15 +214,15 @@ export const userService = { const updatedRecord = await pb.collection(collection).update(id, cleanData); updatedUser = convertToUserType(updatedRecord, isCurrentlySuperadmin ? "superadmin" : "admin"); - console.log("PocketBase update response:", updatedUser); + // console.log("PocketBase update response:", updatedUser); // If email was updated successfully, show success message if (hasEmailChange) { - console.log("Email updated successfully to:", emailToUpdate); + // console.log("Email updated successfully to:", emailToUpdate); } } catch (error) { - console.error("Error updating user:", error); + // console.error("Error updating user:", error); // Provide more specific error messages for email issues if (hasEmailChange && error instanceof Error) { @@ -241,7 +241,7 @@ export const userService = { return updatedUser; } catch (error) { - console.error("Failed to update user:", error); + // console.error("Failed to update user:", error); throw error; // Re-throw to handle in the component } }, @@ -253,7 +253,7 @@ export const userService = { await pb.collection('users').delete(id); return true; } catch (error) { - console.log("User not found in regular users, trying superadmin collection"); + // console.log("User not found in regular users, trying superadmin collection"); } // If not found, try deleting from superadmin collection @@ -261,11 +261,11 @@ export const userService = { await pb.collection('_superusers').delete(id); return true; } catch (error) { - console.error("Failed to delete user from either collection:", error); + // console.error("Failed to delete user from either collection:", error); return false; } } catch (error) { - console.error("Failed to delete user:", error); + // console.error("Failed to delete user:", error); return false; } }, @@ -282,7 +282,7 @@ export const userService = { if (cleanData.avatar.startsWith('http') || cleanData.avatar.startsWith('/upload/') || cleanData.avatar.includes('api.dicebear.com')) { - console.log("Removing avatar URL for new user creation:", cleanData.avatar); + // console.log("Removing avatar URL for new user creation:", cleanData.avatar); delete cleanData.avatar; } } @@ -291,18 +291,18 @@ export const userService = { const isSuperAdmin = cleanData.role === "superadmin"; const collection = isSuperAdmin ? '_superusers' : 'users'; - console.log(`Creating new user in ${collection} collection with data:`, { - ...cleanData, - password: "[REDACTED]", - passwordConfirm: "[REDACTED]" - }); + /// console.log(`Creating new user in ${collection} collection with data:`, { + // ...cleanData, + // password: "[REDACTED]", + // passwordConfirm: "[REDACTED]" + // }); // Create the user in the appropriate collection const result = await pb.collection(collection).create(cleanData); return convertToUserType(result, isSuperAdmin ? "superadmin" : "admin"); } catch (error) { - console.error("Failed to create user:", error); + // console.error("Failed to create user:", error); throw error; } } diff --git a/application/src/types/service.types.ts b/application/src/types/service.types.ts index 2653ea4..5071174 100644 --- a/application/src/types/service.types.ts +++ b/application/src/types/service.types.ts @@ -17,6 +17,7 @@ export interface Service { updated?: string; notification_channel?: string; notificationChannel?: string; // Keep for backward compatibility + notification_status?: "enabled" | "disabled"; // Add notification_status field alertTemplate?: string; alerts?: "muted" | "unmuted"; // Make sure alerts is properly typed as union muteAlerts?: boolean; // Keep this to avoid breaking existing code diff --git a/server/pb_migrations/1750241370_updated_ping_data.js b/server/pb_migrations/1750241370_updated_ping_data.js new file mode 100644 index 0000000..f197b25 --- /dev/null +++ b/server/pb_migrations/1750241370_updated_ping_data.js @@ -0,0 +1,61 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_1168766540") + + // remove field + collection.fields.removeById("text1404634243") + + // update field + collection.fields.addAt(15, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text258142582", + "max": 0, + "min": 0, + "name": "region_name", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_1168766540") + + // add field + collection.fields.addAt(17, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text1404634243", + "max": 0, + "min": 0, + "name": "agent_ip_address", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + // update field + collection.fields.addAt(15, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text258142582", + "max": 0, + "min": 0, + "name": "region", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}) diff --git a/server/pb_migrations/1750241407_updated_regional_service.js b/server/pb_migrations/1750241407_updated_regional_service.js new file mode 100644 index 0000000..84a577c --- /dev/null +++ b/server/pb_migrations/1750241407_updated_regional_service.js @@ -0,0 +1,42 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_171698555") + + // update field + collection.fields.addAt(1, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text258142582", + "max": 0, + "min": 0, + "name": "region_name", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_171698555") + + // update field + collection.fields.addAt(1, new Field({ + "autogeneratePattern": "", + "hidden": false, + "id": "text258142582", + "max": 0, + "min": 0, + "name": "region", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + })) + + return app.save(collection) +}) diff --git a/server/pb_migrations/1750414552_deleted_server_processes.js b/server/pb_migrations/1750414552_deleted_server_processes.js new file mode 100644 index 0000000..034c38d --- /dev/null +++ b/server/pb_migrations/1750414552_deleted_server_processes.js @@ -0,0 +1,137 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_2018671343"); + + return app.delete(collection); +}, (app) => { + const collection = new Collection({ + "createRule": "", + "deleteRule": "", + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text407168695", + "max": 0, + "min": 0, + "name": "server_id", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1431356653", + "max": 0, + "min": 0, + "name": "pid", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1579384326", + "max": 0, + "min": 0, + "name": "name", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "number1391558374", + "max": null, + "min": null, + "name": "memory_percent", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "number2651913466", + "max": null, + "min": null, + "name": "cpu_percent", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text2063623452", + "max": 0, + "min": 0, + "name": "status", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "id": "pbc_2018671343", + "indexes": [], + "listRule": "", + "name": "server_processes", + "system": false, + "type": "base", + "updateRule": "", + "viewRule": "" + }); + + return app.save(collection); +}) diff --git a/server/pb_migrations/1750414561_deleted_server_notifications.js b/server/pb_migrations/1750414561_deleted_server_notifications.js new file mode 100644 index 0000000..4a4b0aa --- /dev/null +++ b/server/pb_migrations/1750414561_deleted_server_notifications.js @@ -0,0 +1,170 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_3414192583"); + + return app.delete(collection); +}, (app) => { + const collection = new Collection({ + "createRule": "", + "deleteRule": "", + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text407168695", + "max": 0, + "min": 0, + "name": "server_id", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3065852031", + "max": 0, + "min": 0, + "name": "message", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text887233555", + "max": 0, + "min": 0, + "name": "notification_type", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "date3805952114", + "max": "", + "min": "", + "name": "read_at", + "presentable": false, + "required": false, + "system": false, + "type": "date" + }, + { + "hidden": false, + "id": "number1377725610", + "max": null, + "min": null, + "name": "cpu_threshold", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "number3087505384", + "max": null, + "min": null, + "name": "ram_threshold", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "number2833320134", + "max": null, + "min": null, + "name": "disk_threshold", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "number1826572927", + "max": null, + "min": null, + "name": "network_threshold", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "number2184331740", + "max": null, + "min": null, + "name": "notification_config_id", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "id": "pbc_3414192583", + "indexes": [], + "listRule": "", + "name": "server_notifications", + "system": false, + "type": "base", + "updateRule": "", + "viewRule": "" + }); + + return app.save(collection); +}) diff --git a/server/pb_migrations/1750502263_updated_regional_service.js b/server/pb_migrations/1750502263_updated_regional_service.js new file mode 100644 index 0000000..230a6ea --- /dev/null +++ b/server/pb_migrations/1750502263_updated_regional_service.js @@ -0,0 +1,28 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_171698555") + + // update collection data + unmarshal({ + "createRule": "", + "deleteRule": "", + "listRule": "", + "updateRule": "", + "viewRule": "" + }, collection) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_171698555") + + // update collection data + unmarshal({ + "createRule": null, + "deleteRule": null, + "listRule": null, + "updateRule": null, + "viewRule": null + }, collection) + + return app.save(collection) +})