From 7fd6d07c1046af84abe3cac40de04798daa82dff Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Thu, 10 Jul 2025 22:41:04 +0700 Subject: [PATCH 01/11] Added to detail Development Setup. - To include Go service operation and Distributed regional agent --- CONTRIBUTING.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ca2d9bc..0b8d2c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,16 +61,45 @@ npm install && npm run dev #Server Backend cd server -./pocketbase serve --dir pb_data +./pocketbase serve --dir pb_data + +If you're not using localhost, please run with this (./pocketbase serve --http=0.0.0.0:8090 --dir pb_data) +``` + +### 4. Start Service Check Operation + +```bash +#Server Backend +Start Service Operation (Check Service for PING, HTTP, TCP, DNS) + +cd server/service-operation + +go run main.go (you do not need to change the .env while it's the localhost connection) ``` +### 5. Start Distributed Regional Agent +```bash +#### 1. Fork the Repository +Click "Fork" on [GitHub](https://github.com/operacle/Distributed-Regional-Monitoring) to create your own copy. + +#### 2. Clone Your Fork +git clone --branch main https://github.com/operacle/Distributed-Regional-Monitoring.git +cd Distributed-Regional-Monitoring + +#### 3. Install Go Service (make sure you have installed the Go Service) + +Copy .env.example -> .env +Change regional agent configuration in .env file +and Run: go run main.go + +``` --- ## ✅ Pull Request Process 1. Ensure your code follows the existing style and naming conventions. 2. Write clear, concise commit messages. -3. Push your branch and open a Pull Request (PR) on the `main` branch. +3. Push your branch and open a Pull Request (PR) on the `develop` branch. 4. Provide a meaningful PR description (what/why/how). 5. Link related issues if applicable (e.g. `Closes #12`). 6. Make sure all checks pass (e.g., linting, tests). From de79eb963d0d7ea585af949a598e5361bbd05cef Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Thu, 10 Jul 2025 23:06:10 +0700 Subject: [PATCH 02/11] feat: Allow multiple selections for regional agents. - Allow multiple regional agents to be selected in the service dialog form, similar to the notification channels. --- .../services/add-service/ServiceForm.tsx | 27 ++-- .../add-service/ServiceRegionalFields.tsx | 150 +++++++++++------- .../services/add-service/serviceFormUtils.ts | 30 ++-- .../components/services/add-service/types.ts | 6 +- application/src/components/ui/badge.tsx | 2 +- application/src/components/ui/button.tsx | 5 +- 6 files changed, 135 insertions(+), 85 deletions(-) diff --git a/application/src/components/services/add-service/ServiceForm.tsx b/application/src/components/services/add-service/ServiceForm.tsx index 1fad41a..8e66a92 100644 --- a/application/src/components/services/add-service/ServiceForm.tsx +++ b/application/src/components/services/add-service/ServiceForm.tsx @@ -1,4 +1,3 @@ - import { Form } from "@/components/ui/form"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -47,18 +46,18 @@ export function ServiceForm({ form.reset(formData); // Log for debugging - console.log("Populating form with data:", { - type: formData.type, - url: formData.url, - port: formData.port, - regionalAgent: formData.regionalAgent, - regionalMonitoringEnabled: formData.regionalMonitoringEnabled, - regional_status: initialData.regional_status, - region_name: initialData.region_name, - agent_id: initialData.agent_id, - notification_status: initialData.notification_status, - notificationChannels: formData.notificationChannels - }); + // console.log("Populating form with data:", { + // type: formData.type, + // url: formData.url, + // port: formData.port, + // regionalAgents: formData.regionalAgents, + // regionalMonitoringEnabled: formData.regionalMonitoringEnabled, + // regional_status: initialData.regional_status, + // region_name: initialData.region_name, + // agent_id: initialData.agent_id, + // notification_status: initialData.notification_status, + // notificationChannels: formData.notificationChannels + // }); } }, [initialData, isEdit, form]); @@ -97,7 +96,7 @@ export function ServiceForm({ form.reset(); } } catch (error) { - console.error(`Error ${isEdit ? 'updating' : 'creating'} service:`, error); + // console.error(`Error ${isEdit ? 'updating' : 'creating'} service:`, error); toast({ title: `Failed to ${isEdit ? 'update' : 'create'} service`, description: `An error occurred while ${isEdit ? 'updating' : 'creating'} the service.`, diff --git a/application/src/components/services/add-service/ServiceRegionalFields.tsx b/application/src/components/services/add-service/ServiceRegionalFields.tsx index 39b9e3f..34473b2 100644 --- a/application/src/components/services/add-service/ServiceRegionalFields.tsx +++ b/application/src/components/services/add-service/ServiceRegionalFields.tsx @@ -6,7 +6,9 @@ import { UseFormReturn } from "react-hook-form"; import { ServiceFormData } from "./types"; import { useQuery } from "@tanstack/react-query"; import { regionalService } from "@/services/regionalService"; -import { MapPin, Loader2, X } from "lucide-react"; +import { MapPin, Loader2, X, Plus } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; interface ServiceRegionalFieldsProps { form: UseFormReturn; @@ -14,7 +16,7 @@ interface ServiceRegionalFieldsProps { export function ServiceRegionalFields({ form }: ServiceRegionalFieldsProps) { const regionalMonitoringEnabled = form.watch("regionalMonitoringEnabled"); - const currentRegionalAgent = form.watch("regionalAgent"); + const currentRegionalAgents = form.watch("regionalAgents") || []; const { data: regionalAgents = [], isLoading } = useQuery({ queryKey: ['regional-services'], @@ -27,15 +29,16 @@ export function ServiceRegionalFields({ form }: ServiceRegionalFieldsProps) { agent.connection === 'online' && agent.agent_id !== "1" ); - // Find the current agent name for display - const getCurrentAgentDisplay = () => { - if (!currentRegionalAgent || currentRegionalAgent === "unassign") { - return "Select a regional agent or unassign"; - } - - const [regionName, agentId] = currentRegionalAgent.split("|"); + // Get available agents (not already selected) + const availableAgents = onlineAgents.filter(agent => + !currentRegionalAgents.includes(`${agent.region_name}|${agent.agent_id}`) + ); + + // Get agent display name + const getAgentDisplayName = (agentValue: string) => { + const [regionName, agentId] = agentValue.split("|"); const agent = onlineAgents.find(agent => - `${agent.region_name}|${agent.agent_id}` === currentRegionalAgent + `${agent.region_name}|${agent.agent_id}` === agentValue ); if (agent) { @@ -43,25 +46,27 @@ export function ServiceRegionalFields({ form }: ServiceRegionalFieldsProps) { } // If agent is not found in online agents, it might be offline but still assigned - // Show the region name from the stored value if (regionName && agentId) { return `${regionName} (Agent ${agentId}) - Offline`; } - return "Select a regional agent or unassign"; + return agentValue; }; - // Get the proper select value - handle both assigned and unassigned cases - const getSelectValue = () => { - if (!regionalMonitoringEnabled) { - return "unassign"; + // Add regional agent + const addRegionalAgent = (agentValue: string) => { + if (agentValue && agentValue !== "select") { + const currentAgents = form.getValues("regionalAgents") || []; + if (!currentAgents.includes(agentValue)) { + form.setValue("regionalAgents", [...currentAgents, agentValue]); + } } - - if (!currentRegionalAgent || currentRegionalAgent === "") { - return "unassign"; - } - - return currentRegionalAgent; + }; + + // Remove regional agent + const removeRegionalAgent = (agentValue: string) => { + const currentAgents = form.getValues("regionalAgents") || []; + form.setValue("regionalAgents", currentAgents.filter(agent => agent !== agentValue)); }; return ( @@ -77,13 +82,19 @@ export function ServiceRegionalFields({ form }: ServiceRegionalFieldsProps) { Regional Monitoring
- Assign this service to a regional monitoring agent for distributed monitoring + Assign this service to regional monitoring agents for distributed monitoring
{ + field.onChange(checked); + // Clear agents when disabling regional monitoring + if (!checked) { + form.setValue("regionalAgents", []); + } + }} /> @@ -93,16 +104,36 @@ export function ServiceRegionalFields({ form }: ServiceRegionalFieldsProps) { {regionalMonitoringEnabled && ( ( - Regional Agent + Regional Agents + + {/* Display selected agents */} + {currentRegionalAgents.length > 0 && ( +
+ {currentRegionalAgents.map((agentValue) => ( + +
+ {getAgentDisplayName(agentValue)} + +
+ ))} +
+ )} + + {/* Add new agent selector */} + + {regionalMonitoringEnabled && onlineAgents.length === 0 && !isLoading && (

No online regional agents found. Services will use default monitoring.

)} - {currentRegionalAgent && currentRegionalAgent !== "" && ( -

- Currently assigned to: {getCurrentAgentDisplay()} + + {currentRegionalAgents.length === 0 && regionalMonitoringEnabled && ( +

+ No regional agents selected. Service will use default monitoring.

)} - {(!currentRegionalAgent || currentRegionalAgent === "") && regionalMonitoringEnabled && ( -

- Service is unassigned and will use default monitoring. + + {currentRegionalAgents.length > 0 && ( +

+ Service assigned to {currentRegionalAgents.length} regional agent{currentRegionalAgents.length > 1 ? 's' : ''}.

)}
diff --git a/application/src/components/services/add-service/serviceFormUtils.ts b/application/src/components/services/add-service/serviceFormUtils.ts index 7d9171d..599768c 100644 --- a/application/src/components/services/add-service/serviceFormUtils.ts +++ b/application/src/components/services/add-service/serviceFormUtils.ts @@ -13,7 +13,7 @@ export const getServiceFormDefaults = (): ServiceFormData => ({ notificationChannels: [], alertTemplate: "", regionalMonitoringEnabled: false, - regionalAgent: "", + regionalAgents: [], }); export const mapServiceToFormData = (service: Service): ServiceFormData => { @@ -40,9 +40,12 @@ export const mapServiceToFormData = (service: Service): ServiceFormData => { // 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}` - : ""; + const regionalAgents: string[] = []; + + // For backward compatibility, if there's a single regional agent, add it to the array + if (isRegionalEnabled && service.region_name && service.agent_id) { + regionalAgents.push(`${service.region_name}|${service.agent_id}`); + } // Handle notification channels - convert notification_channel and notificationChannel to array const notificationChannels: string[] = []; @@ -62,7 +65,8 @@ export const mapServiceToFormData = (service: Service): ServiceFormData => { notification_status: service.notification_status, notification_channel: service.notification_channel, notificationChannel: service.notificationChannel, - mappedChannels: notificationChannels + mappedChannels: notificationChannels, + regionalAgents: regionalAgents }); return { @@ -76,21 +80,23 @@ export const mapServiceToFormData = (service: Service): ServiceFormData => { notificationChannels: notificationChannels, alertTemplate: service.alertTemplate === "default" ? "" : service.alertTemplate || "", regionalMonitoringEnabled: isRegionalEnabled, - regionalAgent: regionalAgent, + regionalAgents: regionalAgents, }; }; export const mapFormDataToServiceData = (data: ServiceFormData) => { - // Parse regional agent selection + // Parse regional agent selection - for now, use the first agent for backward compatibility let regionName = ""; let agentId = ""; let regionalStatus: "enabled" | "disabled" = "disabled"; // Set regional status and agent data based on form values - if (data.regionalMonitoringEnabled) { + if (data.regionalMonitoringEnabled && data.regionalAgents && data.regionalAgents.length > 0) { regionalStatus = "enabled"; - if (data.regionalAgent && data.regionalAgent !== "") { - const [parsedRegionName, parsedAgentId] = data.regionalAgent.split("|"); + // Use the first agent for backward compatibility with single-agent database schema + const firstAgent = data.regionalAgents[0]; + if (firstAgent && firstAgent !== "") { + const [parsedRegionName, parsedAgentId] = firstAgent.split("|"); regionName = parsedRegionName || ""; agentId = parsedAgentId || ""; } @@ -109,6 +115,10 @@ export const mapFormDataToServiceData = (data: ServiceFormData) => { regionalStatus: regionalStatus, regionName: regionName, agentId: agentId, + // Store multiple agents as a comment for future use (when backend supports it) + regionalAgentsNote: data.regionalAgents && data.regionalAgents.length > 1 + ? `Multiple agents selected: ${data.regionalAgents.join(', ')}` + : undefined, // 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 diff --git a/application/src/components/services/add-service/types.ts b/application/src/components/services/add-service/types.ts index 3d269e5..4269a42 100644 --- a/application/src/components/services/add-service/types.ts +++ b/application/src/components/services/add-service/types.ts @@ -14,9 +14,9 @@ export const serviceSchema = z.object({ notificationStatus: z.enum(["enabled", "disabled"]).optional(), notificationChannels: z.array(z.string()).optional(), alertTemplate: z.string().optional(), - // Regional monitoring fields + // Regional monitoring fields - now supports multiple agents regionalMonitoringEnabled: z.boolean().optional(), - regionalAgent: z.string().optional(), + regionalAgents: z.array(z.string()).optional(), }); -export type ServiceFormData = z.infer; +export type ServiceFormData = z.infer; \ No newline at end of file diff --git a/application/src/components/ui/badge.tsx b/application/src/components/ui/badge.tsx index 8963a4d..f64cf19 100644 --- a/application/src/components/ui/badge.tsx +++ b/application/src/components/ui/badge.tsx @@ -34,4 +34,4 @@ function Badge({ className, variant, ...props }: BadgeProps) { ) } -export { Badge, badgeVariants } +export { Badge, badgeVariants } \ No newline at end of file diff --git a/application/src/components/ui/button.tsx b/application/src/components/ui/button.tsx index 36496a2..fede5fc 100644 --- a/application/src/components/ui/button.tsx +++ b/application/src/components/ui/button.tsx @@ -1,3 +1,4 @@ + import * as React from "react" import { Slot } from "@radix-ui/react-slot" import { cva, type VariantProps } from "class-variance-authority" @@ -5,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { @@ -53,4 +54,4 @@ const Button = React.forwardRef( ) Button.displayName = "Button" -export { Button, buttonVariants } +export { Button, buttonVariants } \ No newline at end of file From 35e161e40d0e991fcb83c5c047b5f9d928037506 Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Fri, 11 Jul 2025 14:18:41 +0700 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=94=90=20docs(security):=20update?= =?UTF-8?q?=20Security=20Policy=20to=20reflect=20TypeScript=20and=20Go=20s?= =?UTF-8?q?tack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Clarify that CheckCle is built with both TypeScript and Go - Add mention of Go-specific security practices (govulncheck, Go modules) - Improve clarity and consistency of security considerations --- SECURITY.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 90d9f98..94303c0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ ## 📊 Project: [checkcle](https://github.com/operacle/checkcle) -**checkcle** is a lightweight, TypeScript-based built for uptime and server monitoring tools. +**checkcle** is a self-hosted uptime and server monitoring tool built with TypeScript and Go. We care about the security and privacy of users running this project in production environments. @@ -47,22 +47,21 @@ We support the latest stable release of `checkcle`. Security patches may also be ## 🔍 Security Practices -This project adheres to the following practices to enhance security: +CheckCle follows these practices to improve overall security: -- 🔎 Regular vulnerability checks using `npm audit` -- ⛓ Dependency pinning via `package-lock.json` -- ✅ Type-safe code using `TypeScript` -- 🧪 Continuous testing and CI +- 🔎 Regular vulnerability scanning (npm audit for JavaScript dependencies, govulncheck for Go modules) +- ⛓ Dependency pinning (package-lock.json and Go modules) +- ✅ Type-safe code in TypeScript and memory-safe design in Go +- 🧪 Continuous testing and CI pipelines - 🔐 No data is stored or transmitted unless explicitly configured by the user -- 🧑‍💻 All contributions are reviewed before being merged +- 🧑‍💻 All code contributions are reviewed before merging --- ## ⚠ Known Security Limitations -- `checkcle` makes outbound HTTPS requests to check certificate details — avoid running in untrusted or high-risk environments without proper network policies. -- Output may contain certificate metadata (e.g., CN, SANs, expiry dates) — avoid exposing this to public logs unless sanitized. -- The data may be lost upon system restarts or crashes. Always ensure that backup and recovery mechanisms are in place in production environments. +- Outbound HTTPS requests: CheckCle agents perform outbound HTTPS connections to send metric data to the backend server. Avoid deploying in untrusted or high-risk environments without appropriate network policies and monitoring. +- The data may be lost upon system restarts or crashes. Always ensure that backup (pb_data) and recovery mechanisms are in place in production environments. --- From 59dcdcb5dfc4c3b26841a4c4a84cd9071b8e1fe6 Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Fri, 11 Jul 2025 17:57:32 +0700 Subject: [PATCH 04/11] Fix: Persist multiple notification channels - The notification channels field in the service dialog form was not saving or applying multiple selections --- application/src/services/serviceService.ts | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/application/src/services/serviceService.ts b/application/src/services/serviceService.ts index 5bb8327..4421f5b 100644 --- a/application/src/services/serviceService.ts +++ b/application/src/services/serviceService.ts @@ -1,3 +1,4 @@ + import { pb } from '@/lib/pocketbase'; import { Service, CreateServiceParams, UptimeData } from '@/types/service.types'; import { monitoringService } from './monitoring'; @@ -27,6 +28,7 @@ export const serviceService = { interval: item.heartbeat_interval || item.interval || 60, retries: item.max_retries || item.retries || 3, notificationChannel: item.notification_id, + notification_channel: item.notification_channel, // Add this field for multiple channels support notification_status: item.notification_status || "disabled", alertTemplate: item.template_id, muteAlerts: item.alerts === "muted", // Convert string to boolean for compatibility @@ -39,7 +41,7 @@ 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.'); } }, @@ -50,7 +52,7 @@ export const serviceService = { const serviceType = params.type.toLowerCase(); // Debug log to check what we're sending - console.log("Creating service with params:", params); + // console.log("Creating service with params:", params); const data = { name: params.name, @@ -62,8 +64,13 @@ export const serviceService = { heartbeat_interval: params.interval, max_retries: params.retries, notification_status: params.notificationStatus || "disabled", + // Store multiple notification channels as JSON string + notification_channel: params.notificationChannels && params.notificationChannels.length > 0 + ? JSON.stringify(params.notificationChannels) + : null, + // Store multiple notification IDs as comma-separated string in notification_id field notification_id: params.notificationChannels && params.notificationChannels.length > 0 - ? params.notificationChannels[0] // Store first channel for backward compatibility + ? params.notificationChannels.join(',') : null, template_id: params.alertTemplate, // Regional monitoring fields - use regional_status @@ -81,9 +88,9 @@ export const serviceService = { ) }; - console.log("Creating service with data:", data); + // console.log("Creating service with data:", data); const record = await pb.collection('services').create(data); - console.log("Service created, returned record:", record); + // console.log("Service created, returned record:", record); // Return the newly created service const newService = { @@ -101,6 +108,7 @@ export const serviceService = { interval: record.heartbeat_interval || 60, retries: record.max_retries || 3, notificationChannel: record.notification_id, + notification_channel: record.notification_channel, notification_status: record.notification_status || "disabled", alertTemplate: record.template_id, regional_status: record.regional_status || "disabled", @@ -114,7 +122,7 @@ export const serviceService = { return newService; } catch (error) { - console.error("Error creating service:", error); + // console.error("Error creating service:", error); throw new Error('Failed to create service.'); } }, @@ -125,7 +133,7 @@ export const serviceService = { const serviceType = params.type.toLowerCase(); // Debug log to check what we're updating - console.log("Updating service with params:", params); + // console.log("Updating service with params:", params); const data = { name: params.name, @@ -133,8 +141,13 @@ export const serviceService = { heartbeat_interval: params.interval, max_retries: params.retries, notification_status: params.notificationStatus || "disabled", + // Store multiple notification channels as JSON string + notification_channel: params.notificationChannels && params.notificationChannels.length > 0 + ? JSON.stringify(params.notificationChannels) + : null, + // Store multiple notification IDs as comma-separated string in notification_id field notification_id: params.notificationChannels && params.notificationChannels.length > 0 - ? params.notificationChannels[0] // Store first channel for backward compatibility + ? params.notificationChannels.join(',') : null, template_id: params.alertTemplate || null, // Regional monitoring fields - use regional_status @@ -152,7 +165,7 @@ export const serviceService = { ) }; - console.log("Updating service with data:", data); + // console.log("Updating service with data:", data); // Use timeout to ensure the request doesn't hang const timeoutPromise = new Promise((_, reject) => { @@ -161,7 +174,7 @@ export const serviceService = { const updatePromise = pb.collection('services').update(id, data); const record = await Promise.race([updatePromise, timeoutPromise]) as any; - console.log("Service updated, returned record:", record); + // console.log("Service updated, returned record:", record); // Return the updated service const updatedService = { @@ -179,6 +192,7 @@ export const serviceService = { interval: record.heartbeat_interval || 60, retries: record.max_retries || 3, notificationChannel: record.notification_id, + notification_channel: record.notification_channel, notification_status: record.notification_status || "disabled", alertTemplate: record.template_id, regional_status: record.regional_status || "disabled", @@ -189,7 +203,7 @@ export const serviceService = { return updatedService; } catch (error) { - console.error("Error updating service:", error); + //console.error("Error updating service:", error); throw new Error(`Failed to update service: ${error instanceof Error ? error.message : 'Unknown error'}`); } }, From 5daea8138cd0b8f26126bf42ebfadddea42f4598 Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Fri, 11 Jul 2025 17:58:46 +0700 Subject: [PATCH 05/11] Change Default monitoring fallback source value (uptime service) --- .../src/components/services/hooks/useConsolidatedUptimeData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/components/services/hooks/useConsolidatedUptimeData.ts b/application/src/components/services/hooks/useConsolidatedUptimeData.ts index e8c24a8..195a8fd 100644 --- a/application/src/components/services/hooks/useConsolidatedUptimeData.ts +++ b/application/src/components/services/hooks/useConsolidatedUptimeData.ts @@ -107,7 +107,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte // console.log(`Found default monitoring: ${sourceName} for normalized timestamp ${normalizedTimestamp}`); } else { // Default monitoring fallback - sourceName = 'Default System Check (Agent 1)'; + sourceName = 'Default (Agent 1)'; isDefault = true; // console.log(`Using fallback default monitoring for normalized timestamp ${normalizedTimestamp}`); } From a013f9170ad0c1a67b87b535b6831585a667fe16 Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Fri, 11 Jul 2025 17:59:03 +0700 Subject: [PATCH 06/11] feat: Allow multiple regional agents - Allow multiple selections for regional agents in the service dialog form, similar to notification channels. --- .../services/add-service/serviceFormUtils.ts | 106 ++++++++++++------ 1 file changed, 73 insertions(+), 33 deletions(-) diff --git a/application/src/components/services/add-service/serviceFormUtils.ts b/application/src/components/services/add-service/serviceFormUtils.ts index 599768c..3429c41 100644 --- a/application/src/components/services/add-service/serviceFormUtils.ts +++ b/application/src/components/services/add-service/serviceFormUtils.ts @@ -42,32 +42,65 @@ export const mapServiceToFormData = (service: Service): ServiceFormData => { const isRegionalEnabled = service.regional_status === "enabled"; const regionalAgents: string[] = []; - // For backward compatibility, if there's a single regional agent, add it to the array + // Parse multiple regional agents from comma-separated region_name and agent_id fields if (isRegionalEnabled && service.region_name && service.agent_id) { - regionalAgents.push(`${service.region_name}|${service.agent_id}`); + const regionNames = service.region_name.includes(',') + ? service.region_name.split(',').map(name => name.trim()).filter(name => name) + : [service.region_name]; + + const agentIds = service.agent_id.includes(',') + ? service.agent_id.split(',').map(id => id.trim()).filter(id => id) + : [service.agent_id]; + + // Combine region names and agent IDs (they should have the same length) + const maxLength = Math.max(regionNames.length, agentIds.length); + for (let i = 0; i < maxLength; i++) { + const regionName = regionNames[i] || regionNames[0] || ""; + const agentId = agentIds[i] || agentIds[0] || ""; + if (regionName && agentId) { + regionalAgents.push(`${regionName}|${agentId}`); + } + } } - // Handle notification channels - convert notification_channel and notificationChannel to array + // Handle notification channels - prioritize notification_channel field which contains JSON array const notificationChannels: string[] = []; - // Check for notification_channel field (from database) + // First check for notification_channel field (JSON string of array) if (service.notification_channel) { - notificationChannels.push(service.notification_channel); + try { + const parsedChannels = JSON.parse(service.notification_channel); + if (Array.isArray(parsedChannels)) { + notificationChannels.push(...parsedChannels); + } + } catch (error) { + // console.warn("Failed to parse notification_channel JSON:", error); + // If parsing fails, treat as single channel ID + notificationChannels.push(service.notification_channel); + } } - // Also check for notificationChannel field (backward compatibility) - if (service.notificationChannel && !notificationChannels.includes(service.notificationChannel)) { - notificationChannels.push(service.notificationChannel); + // Fallback to comma-separated notification_id field + if (notificationChannels.length === 0 && service.notificationChannel) { + // Check if it's comma-separated + if (service.notificationChannel.includes(',')) { + const channels = service.notificationChannel.split(',').map(id => id.trim()).filter(id => id); + notificationChannels.push(...channels); + } else { + 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, - regionalAgents: regionalAgents - }); +// 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, + // regionalAgents: regionalAgents, + // region_name: service.region_name, + /// agent_id: service.agent_id + // }); return { name: service.name || "", @@ -85,21 +118,32 @@ export const mapServiceToFormData = (service: Service): ServiceFormData => { }; export const mapFormDataToServiceData = (data: ServiceFormData) => { - // Parse regional agent selection - for now, use the first agent for backward compatibility - let regionName = ""; - let agentId = ""; + // Parse regional agent selections - store multiple agents as comma-separated values + let regionNames = ""; + let agentIds = ""; let regionalStatus: "enabled" | "disabled" = "disabled"; // Set regional status and agent data based on form values if (data.regionalMonitoringEnabled && data.regionalAgents && data.regionalAgents.length > 0) { regionalStatus = "enabled"; - // Use the first agent for backward compatibility with single-agent database schema - const firstAgent = data.regionalAgents[0]; - if (firstAgent && firstAgent !== "") { - const [parsedRegionName, parsedAgentId] = firstAgent.split("|"); - regionName = parsedRegionName || ""; - agentId = parsedAgentId || ""; - } + + // Extract region names and agent IDs from the selected agents + const parsedRegions: string[] = []; + const parsedAgentIds: string[] = []; + + data.regionalAgents.forEach(agentValue => { + if (agentValue && agentValue !== "") { + const [regionName, agentId] = agentValue.split("|"); + if (regionName && agentId) { + parsedRegions.push(regionName); + parsedAgentIds.push(agentId); + } + } + }); + + // Store as comma-separated strings + regionNames = parsedRegions.join(','); + agentIds = parsedAgentIds.join(','); } // Prepare service data with proper field mapping @@ -111,14 +155,10 @@ export const mapFormDataToServiceData = (data: ServiceFormData) => { notificationStatus: data.notificationStatus || "disabled", notificationChannels: data.notificationChannels || [], alertTemplate: data.alertTemplate === "default" ? "" : data.alertTemplate, - // Use regional_status field instead of regionalMonitoringEnabled + // Use regional_status field and store multiple agents as comma-separated values regionalStatus: regionalStatus, - regionName: regionName, - agentId: agentId, - // Store multiple agents as a comment for future use (when backend supports it) - regionalAgentsNote: data.regionalAgents && data.regionalAgents.length > 1 - ? `Multiple agents selected: ${data.regionalAgents.join(', ')}` - : undefined, + regionName: regionNames, + agentId: agentIds, // 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 From 53d8b110c97d711d0c21cbb466563c8de0b8689e Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Fri, 11 Jul 2025 20:12:20 +0700 Subject: [PATCH 07/11] Update .gitignore with .DS_Store removed --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8a74b8a..efda3c4 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ dist-ssr *.sw? application/src/lib/pocketbase.ts Dockerfile +application/src/lib/pocketbase-prod.ts From 1b40a1b663c4e57befd9197fe0cda3e0c9d6dc99 Mon Sep 17 00:00:00 2001 From: gnsworks Date: Sat, 12 Jul 2025 10:06:50 +0900 Subject: [PATCH 08/11] Add README_ja.md --- README_ja.md | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 README_ja.md diff --git a/README_ja.md b/README_ja.md new file mode 100644 index 0000000..8009ec1 --- /dev/null +++ b/README_ja.md @@ -0,0 +1,148 @@ +![CheckCle Platform](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/server-detail-page.png) + +# 🚀 CheckCleずは + +CheckCleは、フルスタックシステム、アプリケヌション、むンフラストラクチャのシヌムレスでリアルタむムな監芖を実珟するオヌプン゜ヌス゜リュヌションです。開発者、システム管理者、DevOpsチヌムに察しお、環境の党レむダヌサヌバヌ、アプリケヌション、サヌビスにわたる深い掞察ず実甚的なデヌタを提䟛したす。CheckCleにより、テクノロゞヌスタック党䜓の可芖性、制埡、最適なパフォヌマンスの確保が可胜になりたす。 + +## 🎯 ラむブデモ +👉 **今すぐ詊す:** [CheckCle ラむブデモ](https://demo.checkcle.io) + +## 🌟 䞻芁機胜 + +### アップタむムサヌビス & むンフラストラクチャサヌバヌ監芖 +- HTTP、DNS、Pingプロトコルの監芖 +- TCPベヌスのAPIサヌビスFTP、SMTP、HTTPなどの監芖 +- 詳现なアップタむム、レスポンス時間、パフォヌマンス問題の远跡 +- 分散地域監芖 +- むンシデント履歎UP/DOWN/WARNING/PAUSE +- SSL & ドメむン監芖ドメむン、発行者、有効期限、残り日数、ステヌタス、最終通知日 +- むンフラストラクチャサヌバヌ監芖Linux🐧 Debian、Ubuntu、CentOS、Red HatなどおよびWindowsベヌタ版をサポヌト。ワンラむン・むンストヌル・゚ヌゞェント・スクリプトによるサヌバヌメトリクスCPU、RAM、ディスク䜿甚量、ネットワヌク掻動の監芖 +- メンテナンススケゞュヌル & むンシデント管理 +- 運甚ステヌタス / パブリックステヌタスペヌゞ +- メヌル、Telegram、Discord、Slack経由の通知 +- レポヌト & 分析 +- 蚭定パネルナヌザヌ管理、デヌタ保持、倚蚀語、テヌマダヌク & ラむトモヌド、通知ずチャネル、アラヌトテンプレヌト + +## #⃣ はじめに + +### 珟圚サポヌトされおいるアヌキテクチャ +* ✅ x86_64 PC、ラップトップ、サヌバヌamd64 +* ✅ 最新のRaspberry Pi 3/4/564ビットOS、Apple Silicon Macarm64 + +### 以䞋のオプションのいずれかを䜿甚しおCheckCleをむンストヌルしたす。 + +1. CheckCle ワンクリックむンストヌル - タヌミナルにコピヌしお実行するだけ +```bash +curl -fsSL https://checkcle.io/install.sh | bash + +``` +2. docker runでむンストヌル。以䞋の準備枈みdocker runコマンドをコピヌするだけ +```bash +docker run -d \ + --name checkcle \ + --restart unless-stopped \ + -p 8090:8090 \ + -v /opt/pb_data:/mnt/pb_data \ + --ulimit nofile=4096:8192 \ + operacle/checkcle:latest + +``` +3. Docker compose蚭定でむンストヌル +```bash + +version: '3.9' + +services: + checkcle: + image: operacle/checkcle:latest + container_name: checkcle + restart: unless-stopped + ports: + - "8090:8090" # Webアプリケヌション + volumes: + - /opt/pb_data:/mnt/pb_data # ホストディレクトリをコンテナパスにマップ + ulimits: + nofile: + soft: 4096 + hard: 8192 + +``` +3. 管理Web画面 + + デフォルトURL: http://0.0.0.0:8090 + ナヌザヌ: admin@example.com + パスワヌド: Admin123456 + +4. https://docs.checkcle.io のクむックスタヌトガむドに埓っおください + +### +![checkcle-collapse-black](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/uptime-monitoring.png) +![Service Detail Page](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/uptime-service-detail.png) +![checkcle-server-instance](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/instance-server-monitoring.png) +![Schedule Maintenance](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/checkcle-schedule-maintenance.png) +![SSL Monitoring](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/ssl-monitoring.png) + +## 📝 開発ロヌドマップ + +- ✅ ヘルスチェック & アップタむム監芖HTTP +- ✅ ラむブ統蚈情報付きダッシュボヌドUI +- ✅ マルチナヌザヌシステム認蚌管理者 +- ✅ 通知Telegram +- ✅ Dockerコンテナ化 +- ✅ CheckCle りェブサむト +- ✅ CheckCle デモサヌバヌ +- ✅ SSL & ドメむン監芖 +- ✅ メンテナンススケゞュヌル +- ✅ むンシデント管理 +- [ ] むンフラストラクチャサヌバヌ監芖 +- ✅ 運甚ステヌタス / パブリックステヌタスペヌゞ +- ✅ アップタむム監芖HTTP、TCP、PING、DNSフル機胜 +- ✅ 分散地域監芖゚ヌゞェント [サポヌト運甚](https://github.com/operacle/Distributed-Regional-Monitoring) +- ✅ システム蚭定パネルメヌル蚭定 +- ✅ ナヌザヌ暩限ロヌル +- [ ] 通知Email/Slack/Discord/Signal +- ✅ デヌタ保持 & 自動圧瞮デヌタ & デヌタベヌス圧瞮のマルチオプション +- ✅ 完党なドキュメント付きオヌプン゜ヌスリリヌス + +## 🌟 CheckCleはコミュニティのため +- **情熱を持っお開発**: コミュニティのためのオヌプン゜ヌス愛奜家によっお䜜成 +- **フリヌ & オヌプン゜ヌス**: 隠れたコストなしで完党に無料で䜿甚可胜 +- **協力 & ぀ながり**: オヌプン゜ヌスに情熱を持぀同志ず出䌚う + +--- + +## 🀝 貢献の方法 + +CheckCleの改善にご協力いただける方法をご玹介したす + +- 🐞 **バグ報告** – 䞍具合を発芋したしたか[GitHub Issue](https://github.com/operacle/checkcle/issues)を開いおお知らせください。 +- 🌟 **機胜提案** – アむデアはありたすか[ディスカッション](https://github.com/operacle/checkcle/discussions)を開始するか、機胜リク゚ストのissueを開いおください。 +- 🛠 **プルリク゚スト送信** – コヌドの改善、バグ修正、機胜远加、ドキュメントの改良を行っおください。 +- 📝 **ドキュメント改善** – タむポ修正でも助かりたす +- 🌍 **口コミ宣䌝** – リポゞトリに⭐を぀け、SNSでシェアし、他の人を貢献に招埅しおください + +--- + +## 🌍 ぀ながりを保぀ +- りェブサむト: [checkcle.io](https://checkcle.io) +- ドキュメント: [docs.checkcle.io](https://docs.checkcle.io) +- GitHubリポゞトリ: ⭐ [CheckCle](https://github.com/operacle/checkcle.git) +- コミュニティチャンネル: ディスカッションやissuesで参加しおください +- Discord: コミュニティに参加 [@discord](https://discord.gg/xs9gbubGwX) +- X: [@tlengoss](https://x.com/tlengoss) + +## 📜 ラむセンス + +CheckCleはMITラむセンスの䞋でリリヌスされおいたす。 + +--- +## 👥 貢献者 + +[![](https://contrib.rocks/image?repo=operacle/checkcle)](https://github.com/operacle/checkcle/graphs/contributors) + + +## スタヌ履歎 + +[![Star History Chart](https://api.star-history.com/svg?repos=operacle/checkcle&type=Date)](https://www.star-history.com/#operacle/checkcle&Date) + +CheckCleで情報を把握し、オンラむンを維持したしょう 🌐 \ No newline at end of file From 9fd977ed15e8acc8fc736ef8fdb1d834472942c1 Mon Sep 17 00:00:00 2001 From: gnsworks Date: Sat, 12 Jul 2025 10:07:54 +0900 Subject: [PATCH 09/11] Add CONTRIBUTING_ja.md --- CONTRIBUTING_ja.md | 118 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 CONTRIBUTING_ja.md diff --git a/CONTRIBUTING_ja.md b/CONTRIBUTING_ja.md new file mode 100644 index 0000000..82a5133 --- /dev/null +++ b/CONTRIBUTING_ja.md @@ -0,0 +1,118 @@ +# 🛠 CheckCleぞの貢献 + +**CheckCle**ぞの貢献にご興味をお持ちいただき、ありがずうございたす — リアルタむムフルスタック監芖のための究極のオヌプン゜ヌスプラットフォヌムです。バグの報告、機胜の提案、ドキュメントの改善、たたはコヌドの提出など、どのような圢でのご貢献でも歓迎いたしたす + +倧小を問わず、あらゆる皮類の貢献を歓迎したす。このガむドが始めるのに圹立ちたす。 + +--- + +## 📌 目次 +- [行動芏範](#-行動芏範) +- [貢献の方法](#-貢献の方法) +- [開発環境のセットアップ](#-開発環境のセットアップ) +- [プルリク゚ストのプロセス](#-プルリク゚ストのプロセス) +- [バグず問題の報告](#-バグず問題の報告) +- [機胜リク゚スト](#-機胜リク゚スト) +- [コミュニティずサポヌト](#-コミュニティずサポヌト) +- [ラむセンス](#-ラむセンス) + +--- + +## 📜 行動芏範 + +私たちは[行動芏範](https://opensource.guide/code-of-conduct/)に埓い、オヌプンで歓迎するコミュニティを促進しおいたす。参加するこずで、これらの基準を守るこずに同意したものずしたす。 + +--- + +## 🀝 貢献の方法 + +CheckCleの改善に圹立぀方法をいく぀か玹介したす + +- 🐞 **バグの報告** – 䞍具合を芋぀けたしたか[GitHub Issue](https://github.com/operacle/checkcle/issues)を開いおお知らせください。 +- 🌟 **機胜の提案** – アむデアはありたすか[Discussion](https://github.com/operacle/checkcle/discussions)を始めるか、機胜リク゚ストのissueを開いおください。 +- 🛠 **プルリク゚ストの提出** – コヌドの改善、バグの修正、機胜の远加、ドキュメントの改善を行っおください。 +- 📝 **ドキュメントの改善** – タむポの修正でも倧倉助かりたす +- 🌍 **宣䌝の協力** – リポゞトリに⭐を぀けお、SNSでシェアし、他の方にも貢献を呌びかけおください + +--- + +## 🧰 開発環境のセットアップ + +コヌドに貢献する前に、プロゞェクトをロヌカルで蚭定しおください + +### 1. リポゞトリをフォヌク +[GitHub](https://github.com/operacle/checkcle)で「Fork」をクリックしお、自分のコピヌを䜜成しおください。 + +### 2. フォヌクをクロヌン +```bash +git clone --branch develop https://github.com/operacle/checkcle.git +cd checkcle +``` + +### 3. 䟝存関係のむンストヌル +READMEたたはプロゞェクトドキュメントの指瀺に埓っお、必芁なパッケヌゞをむンストヌルし、ロヌカル開発サヌバヌを実行しおください。 + +### 4. ロヌカル開発の開始 +```bash +#Webアプリケヌション +cd application/ +npm install && npm run dev + +#サヌバヌバック゚ンド +cd server +./pocketbase serve --dir pb_data +``` + +--- + +## ✅ プルリク゚ストのプロセス + +1. コヌドが既存のスタむルず呜名芏則に埓っおいるこずを確認しおください。 +2. 明確で簡朔なコミットメッセヌゞを曞いおください。 +3. ブランチをプッシュし、`main`ブランチにプルリク゚ストPRを開いおください。 +4. 意味のあるPRの説明を提䟛しおください䜕を/なぜ/どのように。 +5. 関連するissueがある堎合はリンクしおください䟋`Closes #12`。 +6. すべおのチェックが通るこずを確認しおください䟋リンティング、テスト。 + +PRをレビュヌし、必芁に応じお倉曎をリク゚ストし、準備ができ次第マヌゞしたす + +--- + +## 🐛 バグず問題の報告 + +可胜な限り倚くの情報を含めおください +- 明確で説明的なタむトル +- 再珟手順 +- 期埅される動䜜ず実際の動䜜 +- 環境情報OS、ブラりザ、デバむスなど +- 該圓する堎合はスクリヌンショットやログ + +報告には[Issue Tracker](https://github.com/operacle/checkcle/issues)をご利甚ください。 + +--- + +## 💡 機胜リク゚スト + +アむデアをお聞かせください[Discussion](https://github.com/operacle/checkcle/discussions)たたは機胜リク゚ストのissueを開いおください。[ロヌドマップ](https://github.com/operacle/checkcle#development-roadmap)に既に蚘茉されおいないこずを確認しおください。 + +--- + +## 🌍 コミュニティずサポヌト + +ヘルプが必芁ですか぀ながりたいですか + +- 💬 [Discordに参加](https://discord.gg/xs9gbubGwX) +- 🗣 [GitHub Discussion](https://github.com/operacle/checkcle/discussions)を開始たたは参加 +- 🐊 [XTwitter](https://x.com/tl)でフォロヌ + +--- + +## 📜 ラむセンス + +貢献するこずで、あなたの貢献が[MITラむセンス](LICENSE)の䞋でラむセンスされるこずに同意したものずしたす。 + +--- + +## 🙏 ありがずうございたす + +CheckCleを䞀緒に構築できるこずを嬉しく思いたす — **コミュニティによる、コミュニティのための**匷力な監芖プラットフォヌム。あなたのサポヌトは私たちにずっおずおも倧切です💙 \ No newline at end of file From 2621544b24047504eb460555bf3ddd03ba6f2514 Mon Sep 17 00:00:00 2001 From: gnsworks Date: Sat, 12 Jul 2025 10:31:03 +0900 Subject: [PATCH 10/11] Add Japanese translation --- .../src/components/dashboard/Header.tsx | 3 + application/src/translations/index.ts | 4 +- application/src/translations/ja/about.ts | 17 +++ application/src/translations/ja/common.ts | 29 +++++ application/src/translations/ja/incident.ts | 54 +++++++++ application/src/translations/ja/index.ts | 24 ++++ application/src/translations/ja/login.ts | 22 ++++ .../src/translations/ja/maintenance.ts | 67 +++++++++++ application/src/translations/ja/menu.ts | 20 ++++ application/src/translations/ja/services.ts | 11 ++ application/src/translations/ja/settings.ts | 51 +++++++++ application/src/translations/ja/ssl.ts | 106 ++++++++++++++++++ 12 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 application/src/translations/ja/about.ts create mode 100644 application/src/translations/ja/common.ts create mode 100644 application/src/translations/ja/incident.ts create mode 100644 application/src/translations/ja/index.ts create mode 100644 application/src/translations/ja/login.ts create mode 100644 application/src/translations/ja/maintenance.ts create mode 100644 application/src/translations/ja/menu.ts create mode 100644 application/src/translations/ja/services.ts create mode 100644 application/src/translations/ja/settings.ts create mode 100644 application/src/translations/ja/ssl.ts diff --git a/application/src/components/dashboard/Header.tsx b/application/src/components/dashboard/Header.tsx index 0e0815d..143789a 100644 --- a/application/src/components/dashboard/Header.tsx +++ b/application/src/components/dashboard/Header.tsx @@ -129,6 +129,9 @@ export const Header = ({ setLanguage("de")} className={language === "de" ? "bg-accent" : ""}> {t("Deutsch")} + setLanguage("ja")} className={language === "ja" ? "bg-accent" : ""}> + {t("japanese")} + diff --git a/application/src/translations/index.ts b/application/src/translations/index.ts index e087b36..8ae73b8 100644 --- a/application/src/translations/index.ts +++ b/application/src/translations/index.ts @@ -1,13 +1,15 @@ import enTranslations from './en'; import kmTranslations from './km'; import deTranslations from './de'; +import jaTranslations from './ja'; -export type Language = "en" | "km" | "de"; +export type Language = "en" | "km" | "de" | "ja"; export const translations = { en: enTranslations, km: kmTranslations, de: deTranslations, + ja: jaTranslations, }; // Type for accessing translations by module and key diff --git a/application/src/translations/ja/about.ts b/application/src/translations/ja/about.ts new file mode 100644 index 0000000..b8965f1 --- /dev/null +++ b/application/src/translations/ja/about.ts @@ -0,0 +1,17 @@ +import { AboutTranslations } from '../types/about'; + +export const aboutTranslations: AboutTranslations = { + aboutCheckcle: "Checkcleに぀いお", + systemDescription: "Checkcleは、サヌバヌずサヌビスの健党性に関するリアルタむム監芖、むンシデント管理、運甚の透明性を提䟛するオヌプン゜ヌスの監芖スタックです。MIT ラむセンスの䞋で公開されおいたす。", + systemVersion: "システムバヌゞョン", + license: "ラむセンス", + mitLicense: "MIT ラむセンス", + links: "リンク", + viewOnGithub: "GitHubで衚瀺", + viewDocumentation: "ドキュメントを衚瀺", + followOnX: "Xでフォロヌ", + joinDiscord: "Discordに参加", + quickActions: "クむックアクション", + quickActionsDescription: "䞀般的な監芖操䜜ず機胜に玠早くアクセスできたす。開始するには、以䞋のアクションを遞択しおください。", + quickTips: "クむックヒント", +}; \ No newline at end of file diff --git a/application/src/translations/ja/common.ts b/application/src/translations/ja/common.ts new file mode 100644 index 0000000..dedc536 --- /dev/null +++ b/application/src/translations/ja/common.ts @@ -0,0 +1,29 @@ +import { CommonTranslations } from '../types/common'; + +export const commonTranslations: CommonTranslations = { + welcome: "ようこそ", + logout: "ログアりト", + language: "蚀語", + english: "English", + khmer: "Khmer", + german: "Deutsch", + japanese: "日本語", + goodMorning: "おはようございたす", + goodAfternoon: "こんにちは", + goodEvening: "こんばんは", + profile: "プロファむル", + settings: "蚭定", + documentation: "ドキュメント", + notifications: "通知", + close: "閉じる", + cancel: "キャンセル", + view: "衚瀺", + edit: "線集", + delete: "削陀", + status: "ステヌタス", + time: "時間", + title: "タむトル", + description: "説明", + success: "成功", + error: "゚ラヌ", +}; \ No newline at end of file diff --git a/application/src/translations/ja/incident.ts b/application/src/translations/ja/incident.ts new file mode 100644 index 0000000..b591f3c --- /dev/null +++ b/application/src/translations/ja/incident.ts @@ -0,0 +1,54 @@ +import { IncidentTranslations } from '../types/incident'; + +export const incidentTranslations: IncidentTranslations = { + incidentManagement: 'むンシデント管理', + incidentsManagementDesc: 'サヌビスのむンシデントずその解決を远跡・管理する', + unresolvedIncidents: '未解決', + resolvedIncidents: '解決枈み', + activeIncidents: 'アクティブなむンシデント', + criticalIssues: '重芁な問題', + avgResolutionTime: '平均解決時間', + noIncidents: 'アクティブなむンシデントはありたせん', + createIncident: 'むンシデントを䜜成', + investigating: '調査䞭', + identified: '特定枈み', + monitoring: '監芖䞭', + resolved: '解決枈み', + scheduleIncidentManagement: 'スケゞュヌル・むンシデント管理', + incidentName: 'むンシデント名', + incidentStatus: 'むンシデントステヌタス', + highPriority: '高優先床', + configurationSettings: '蚭定', + incidentCreatedSuccess: 'むンシデントが正垞に䜜成されたした', + basicInfo: '基本情報', + serviceId: 'サヌビスID', + assignedTo: '担圓者', + unassigned: '未割り圓お', + timeline: 'タむムラむン', + incidentTime: 'むンシデント発生時刻', + resolutionTime: '解決時刻', + systems: 'システム', + noSystems: '圱響を受けるシステムはありたせん', + impactAnalysis: '圱響分析', + rootCause: '根本原因', + resolutionSteps: '解決手順', + lessonsLearned: '孊んだ教蚓', + resolutionDetails: '解決詳现', + assignment: '割り圓お', + download: 'ダりンロヌド', + downloadPdf: 'PDFダりンロヌド', + print: '印刷', + confidentialNote: 'この文曞は機密情報であり、内郚䜿甚のみを目的ずしおいたす。', + generatedOn: '生成日時', + enterResolutionSteps: 'むンシデント解決のために取った手順を入力しおください', + enterLessonsLearned: 'このむンシデントから孊んだ教蚓を入力しおください', + editIncident: 'むンシデントを線集', + editIncidentDesc: 'このむンシデントの詳现を曎新', + updating: '曎新䞭...', + update: '曎新', + create: '䜜成', + creating: '䜜成䞭...', + configuration: '蚭定', + failedToUpdateStatus: 'ステヌタスの曎新に倱敗したした', + inProgress: '進行䞭', +}; \ No newline at end of file diff --git a/application/src/translations/ja/index.ts b/application/src/translations/ja/index.ts new file mode 100644 index 0000000..1359325 --- /dev/null +++ b/application/src/translations/ja/index.ts @@ -0,0 +1,24 @@ +import { Translations } from '../types'; +import { commonTranslations } from './common'; +import { menuTranslations } from './menu'; +import { loginTranslations } from './login'; +import { aboutTranslations } from './about'; +import { servicesTranslations } from './services'; +import { maintenanceTranslations } from './maintenance'; +import { incidentTranslations } from './incident'; +import { sslTranslations } from './ssl'; +import { settingsTranslations } from './settings'; + +const jaTranslations: Translations = { + common: commonTranslations, + menu: menuTranslations, + login: loginTranslations, + about: aboutTranslations, + services: servicesTranslations, + maintenance: maintenanceTranslations, + incident: incidentTranslations, + ssl: sslTranslations, + settings: settingsTranslations +}; + +export default jaTranslations; \ No newline at end of file diff --git a/application/src/translations/ja/login.ts b/application/src/translations/ja/login.ts new file mode 100644 index 0000000..8a923ea --- /dev/null +++ b/application/src/translations/ja/login.ts @@ -0,0 +1,22 @@ +import { LoginTranslations } from '../types/login'; + +export const loginTranslations: LoginTranslations = { + signInToYourAccount: "アカりントにサむンむン", + dontHaveAccount: "アカりントをお持ちでない堎合", + createOne: "䜜成する", + signInWithGoogle: "Googleでサむンむン", + orContinueWith: "たたは", + email: "メヌル", + password: "パスワヌド", + forgot: "忘れた堎合", + signIn: "サむンむン", + signingIn: "サむンむン䞭...", + loginSuccessful: "ログむン成功", + loginSuccessMessage: "正垞にログむンしたした。", + loginFailed: "ログむン倱敗", + authenticationFailed: "認蚌に倱敗したした", + bySigningIn: "サむンむンするこずで、", + termsAndConditions: "利甚芏玄", + and: "ず", + privacyPolicy: "プラむバシヌポリシヌ", +}; \ No newline at end of file diff --git a/application/src/translations/ja/maintenance.ts b/application/src/translations/ja/maintenance.ts new file mode 100644 index 0000000..393d3ab --- /dev/null +++ b/application/src/translations/ja/maintenance.ts @@ -0,0 +1,67 @@ +import { MaintenanceTranslations } from '../types/maintenance'; + +export const maintenanceTranslations: MaintenanceTranslations = { + scheduledMaintenance: 'スケゞュヌル枈みメンテナンス', + scheduledMaintenanceDesc: 'システムずサヌビスの蚈画されたメンテナンスりィンドりを衚瀺・管理', + upcomingMaintenance: '予定', + ongoingMaintenance: '実行䞭', + completedMaintenance: '完了', + createMaintenanceWindow: 'メンテナンス䜜成', + totalScheduledHours: '総スケゞュヌル時間', + maintenanceName: 'メンテナンス名', + maintenanceStatus: 'ステヌタス', + scheduledStart: 'スケゞュヌル開始', + scheduledEnd: 'スケゞュヌル終了', + affectedServices: '圱響を受けるサヌビス', + impact: '圱響', + minor: '軜埮', + major: '重芁', + critical: '重倧', + none: 'なし', + actions: 'アクション', + scheduled: 'スケゞュヌル枈み', + inprogress: '進行䞭', + completed: '完了', + cancelled: 'キャンセル', + markAsInProgress: '進行䞭ずしおマヌク', + markAsCompleted: '完了ずしおマヌク', + markAsCancelled: 'キャンセルずしおマヌク', + confirmDelete: '削陀確認', + deleteMaintenanceConfirmation: 'このメンテナンスりィンドりを削陀しおもよろしいですか', + thisActionCannotBeUndone: 'この操䜜は元に戻せたせん。', + maintenanceDeleted: 'メンテナンス削陀完了', + maintenanceDeletedDesc: 'メンテナンスりィンドりが正垞に削陀されたした。', + errorDeletingMaintenance: 'メンテナンスりィンドりの削陀䞭に゚ラヌが発生したした。', + statusUpdated: 'ステヌタス曎新完了', + maintenanceStatusUpdated: 'メンテナンスステヌタスが正垞に曎新されたした。', + errorUpdatingMaintenanceStatus: 'メンテナンスステヌタスの曎新䞭に゚ラヌが発生したした。', + createMaintenance: 'メンテナンス䜜成', + createMaintenanceDesc: 'サヌビスの新しいメンテナンスりィンドりをスケゞュヌル', + enterTitle: 'メンテナンスタむトルを入力', + enterDescription: 'メンテナンスの詳现説明を入力', + startTime: '開始時刻', + endTime: '終了時刻', + selectDate: '日付を遞択', + enterAffectedServices: '圱響を受けるサヌビスを入力', + separateServicesWithComma: '耇数のサヌビスはカンマで区切っおください', + priority: '優先床', + selectPriority: '優先床を遞択', + selectStatus: 'ステヌタスを遞択', + selectImpact: '圱響を遞択', + notifySubscribers: '賌読者に通知', + notifySubscribersDesc: 'このメンテナンスが開始されたずきに党賌読者に通知を送信', + maintenanceCreated: 'メンテナンス䜜成完了', + maintenanceCreatedDesc: 'メンテナンスりィンドりが正垞にスケゞュヌルされたした。', + errorCreatingMaintenance: 'メンテナンスりィンドりの䜜成䞭に゚ラヌが発生したした。', + errorFetchingMaintenanceData: 'メンテナンスデヌタの取埗䞭に゚ラヌが発生したした。', + low: '䜎', + medium: 'äž­', + high: '高', + created: '䜜成枈み', + lastUpdated: '最終曎新', + subscribersWillBeNotified: 'メンテナンス開始時に賌読者に通知されたす', + noNotifications: '通知は送信されたせん', + noScheduledMaintenance: 'スケゞュヌル枈みメンテナンスなし', + noMaintenanceWindows: 'この期間にメンテナンスりィンドりはありたせん。「メンテナンス䜜成」ボタンをクリックしお䜜成しおください。', + maintenanceCreatedSuccess: 'メンテナンスりィンドりが正垞に䜜成されたした', +}; \ No newline at end of file diff --git a/application/src/translations/ja/menu.ts b/application/src/translations/ja/menu.ts new file mode 100644 index 0000000..cda8377 --- /dev/null +++ b/application/src/translations/ja/menu.ts @@ -0,0 +1,20 @@ +import { MenuTranslations } from '../types/menu'; + +export const menuTranslations: MenuTranslations = { + uptimeMonitoring: "皌働監芖", + instanceMonitoring: "むンスタンス監芖", + sslDomain: "SSL・ドメむン", + scheduleIncident: "スケゞュヌル・むンシデント", + operationalPage: "運甚ペヌゞ", + reports: "レポヌト", + regionalMonitoring: "地域監芖", + settingPanel: "蚭定パネル", + generalSettings: "䞀般蚭定", + userManagement: "ナヌザヌ管理", + notificationSettings: "通知蚭定", + alertsTemplates: "アラヌトテンプレヌト", + rolesManagement: "ロヌル管理", + dataRetention: "デヌタ保持", + backupSettings: "バックアップ蚭定", + aboutSystem: "システム情報", +}; \ No newline at end of file diff --git a/application/src/translations/ja/services.ts b/application/src/translations/ja/services.ts new file mode 100644 index 0000000..668a644 --- /dev/null +++ b/application/src/translations/ja/services.ts @@ -0,0 +1,11 @@ +import { ServicesTranslations } from '../types/services'; + +export const servicesTranslations: ServicesTranslations = { + serviceName: "サヌビス名", + serviceType: "サヌビスタむプ", + serviceStatus: "サヌビスステヌタス", + responseTime: "応答時間", + uptime: "皌働時間", + lastChecked: "最終チェック", + noServices: "フィルタ条件に䞀臎するサヌビスがありたせん。", +}; \ No newline at end of file diff --git a/application/src/translations/ja/settings.ts b/application/src/translations/ja/settings.ts new file mode 100644 index 0000000..8c4ec80 --- /dev/null +++ b/application/src/translations/ja/settings.ts @@ -0,0 +1,51 @@ +import { SettingsTranslations } from '../types/settings'; + +export const settingsTranslations: SettingsTranslations = { + // タブ + systemSettings: "システム蚭定", + mailSettings: "メヌル蚭定", + + // システム蚭定 + appName: "アプリケヌション名", + appURL: "アプリケヌションURL", + senderName: "送信者名", + senderEmail: "送信者メヌルアドレス", + hideControls: "コントロヌルを非衚瀺", + + // メヌル蚭定 + smtpSettings: "SMTP蚭定", + smtpEnabled: "SMTPを有効にする", + smtpHost: "SMTPホスト", + smtpPort: "SMTPポヌト", + smtpUsername: "SMTPナヌザヌ名", + smtpPassword: "SMTPパスワヌド", + smtpAuthMethod: "認蚌方匏", + enableTLS: "TLSを有効にする", + localName: "ロヌカル名", + + // テストメヌル + testEmail: "テストメヌル", + sendTestEmail: "テストメヌルを送信", + emailTemplate: "メヌルテンプレヌト", + verification: "認蚌", + passwordReset: "パスワヌドリセット", + confirmEmailChange: "メヌルアドレス倉曎確認", + otp: "OTP", + loginAlert: "ログむンアラヌト", + authCollection: "認蚌コレクション", + selectCollection: "コレクションを遞択", + toEmailAddress: "宛先メヌルアドレス", + enterEmailAddress: "メヌルアドレスを入力", + sending: "送信䞭...", + + // アクションずステヌタス + save: "倉曎を保存", + saving: "保存䞭...", + settingsUpdated: "蚭定が正垞に曎新されたした", + errorSavingSettings: "蚭定の保存䞭に゚ラヌが発生したした", + errorFetchingSettings: "蚭定の読み蟌み䞭に゚ラヌが発生したした", + testConnection: "接続テスト", + testingConnection: "接続テスト䞭...", + connectionSuccess: "接続成功", + connectionFailed: "接続倱敗" +}; \ No newline at end of file diff --git a/application/src/translations/ja/ssl.ts b/application/src/translations/ja/ssl.ts new file mode 100644 index 0000000..0dbf247 --- /dev/null +++ b/application/src/translations/ja/ssl.ts @@ -0,0 +1,106 @@ +import { SSLTranslations } from '../types/ssl'; + +export const sslTranslations: SSLTranslations = { + // ペヌゞずセクションタむトル + sslDomainManagement: "SSL・ドメむン管理", + monitorSSLCertificates: "ドメむンのSSL蚌明曞を監芖・管理", + addSSLCertificate: "SSL蚌明曞を远加", + editSSLCertificate: "SSL蚌明曞を線集", + deleteSSLCertificate: "SSL蚌明曞を削陀", + sslCertificateDetails: "SSL蚌明曞詳现", + detailedInfo: "詳现情報:", + + // ステヌタス関連 + valid: "有効", + expiringSoon: "期限切れ間近", + expired: "期限切れ", + pending: "保留䞭", + + // 統蚈ずカヌド + validCertificates: "有効な蚌明曞", + expiringSoonCertificates: "期限切れ間近", + expiredCertificates: "期限切れ蚌明曞", + + // フォヌムフィヌルド + domain: "ドメむン", + domainName: "ドメむン名", + domainCannotChange: "ドメむンは䜜成埌倉曎できたせん", + warningThreshold: "譊告閟倀", + warningThresholdDays: "譊告閟倀日", + expiryThreshold: "期限切れ閟倀", + expiryThresholdDays: "期限切れ閟倀日", + notificationChannel: "通知チャンネル", + chooseChannel: "通知チャンネルを遞択", + whereToSend: "通知の送信先", + daysBeforeExpiration: "期限切れ前の譊告を受信する日数", + daysBeforeCritical: "期限切れ前の重芁アラヌトを受信する日数", + getNotifiedExpiration: "蚌明曞の期限切れが近い時に通知を受信", + getNotifiedCritical: "蚌明曞の期限切れが非垞に近い時に通知を受信", + + // テヌブルヘッダヌずフィヌルド + issuer: "発行者", + expirationDate: "有効期限", + daysLeft: "残り日数", + status: "ステヌタス", + lastNotified: "最終通知", + actions: "アクション", + validFrom: "有効開始日", + validUntil: "有効終了日", + validityDays: "有効期間", + organization: "組織", + commonName: "コモンネヌム", + serialNumber: "シリアル番号", + algorithm: "アルゎリズム", + subjectAltNames: "サブゞェクト代替名", + + // ボタンずアクション + addDomain: "ドメむンを远加", + refreshAll: "党お曎新", + cancel: "キャンセル", + addCertificate: "蚌明曞を远加", + check: "チェック", + view: "衚瀺", + edit: "線集", + delete: "削陀", + close: "閉じる", + saveChanges: "倉曎を保存", + updating: "曎新䞭", + + // 詳现ビュヌのセクション + basicInformation: "基本情報", + validity: "有効性", + issuerInfo: "発行者情報", + technicalDetails: "技術的詳现", + monitoringConfig: "監芖蚭定", + recordInfo: "レコヌド情報", + + // 通知ずメッセヌゞ + sslCertificateAdded: "SSL蚌明曞が正垞に远加されたした", + sslCertificateUpdated: "SSL蚌明曞が正垞に曎新されたした", + sslCertificateDeleted: "SSL蚌明曞が正垞に削陀されたした", + sslCertificateRefreshed: "{domain}のSSL蚌明曞が正垞に曎新されたした", + allCertificatesRefreshed: "å…š{count}件の蚌明曞が正垞に曎新されたした", + someCertificatesFailed: "{success}件の蚌明曞が曎新され、{failed}件が倱敗したした", + failedToAddCertificate: "SSL蚌明曞の远加に倱敗したした", + failedToLoadCertificates: "SSL蚌明曞の読み蟌みに倱敗したした", + failedToUpdateCertificate: "SSL蚌明曞の曎新に倱敗したした", + failedToDeleteCertificate: "SSL蚌明曞の削陀に倱敗したした", + failedToCheckCertificate: "SSL蚌明曞のチェックに倱敗したした", + noCertificatesToRefresh: "曎新する蚌明曞がありたせん", + startingRefreshAll: "{count}件の蚌明曞の曎新を開始しおいたす", + checkingSSLCertificate: "SSL蚌明曞をチェック䞭...", + deleteConfirmation: "以䞋の蚌明曞を削陀しおもよろしいですか", + deleteWarning: "この操䜜は元に戻せたせん。蚌明曞が完党に削陀されたす。", + + // その他 + unknown: "䞍明", + never: "なし", + none: "なし", + loadingChannels: "チャンネル読み蟌み䞭...", + noChannelsFound: "通知チャンネルが芋぀かりたせん", + noSSLCertificates: "SSL蚌明曞が芋぀かりたせん", + created: "䜜成日", + lastUpdated: "最終曎新", + lastNotification: "最終通知", + collectionId: "コレクションID" +}; \ No newline at end of file From 09412508672ec99614751dc63ba26d5bcbdfba16 Mon Sep 17 00:00:00 2001 From: Tola Leng Date: Sun, 13 Jul 2025 18:32:45 +0700 Subject: [PATCH 11/11] Refactor Split README and CONTRIBUTING into smaller components with support for multi languages --- CONTRIBUTING.md | 33 ++++ README.md | 33 ++++ CONTRIBUTING_ja.md => docs/CONTRIBUTING_ja.md | 34 ++++ docs/CONTRIBUTING_km.md | 181 +++++++++++++++++ README_ja.md => docs/README_ja.md | 33 ++++ docs/README_km.md | 182 ++++++++++++++++++ 6 files changed, 496 insertions(+) rename CONTRIBUTING_ja.md => docs/CONTRIBUTING_ja.md (85%) create mode 100644 docs/CONTRIBUTING_km.md rename README_ja.md => docs/README_ja.md (89%) create mode 100644 docs/README_km.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b8d2c3..f809209 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,36 @@ +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ + +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

# 🛠 Contributing to CheckCle diff --git a/README.md b/README.md index 2d5c9bd..2bdff25 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

+ ![CheckCle Platform](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/server-detail-page.png) # 🚀 What is CheckCle? diff --git a/CONTRIBUTING_ja.md b/docs/CONTRIBUTING_ja.md similarity index 85% rename from CONTRIBUTING_ja.md rename to docs/CONTRIBUTING_ja.md index 82a5133..80461f7 100644 --- a/CONTRIBUTING_ja.md +++ b/docs/CONTRIBUTING_ja.md @@ -1,3 +1,37 @@ +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ + +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

+ # 🛠 CheckCleぞの貢献 **CheckCle**ぞの貢献にご興味をお持ちいただき、ありがずうございたす — リアルタむムフルスタック監芖のための究極のオヌプン゜ヌスプラットフォヌムです。バグの報告、機胜の提案、ドキュメントの改善、たたはコヌドの提出など、どのような圢でのご貢献でも歓迎いたしたす diff --git a/docs/CONTRIBUTING_km.md b/docs/CONTRIBUTING_km.md new file mode 100644 index 0000000..78efbbb --- /dev/null +++ b/docs/CONTRIBUTING_km.md @@ -0,0 +1,181 @@ + +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

+ +# 🛠 Contributing to CheckCle + +Thank you for your interest in contributing to **CheckCle** — the ultimate open-source platform for real-time full-stack monitoring. Whether you're here to report bugs, suggest features, improve documentation, or submit code, your contribution matters! + +We welcome all kinds of contributions, big or small. This guide will help you get started. + +--- + +## 📌 Table of Contents +- [Code of Conduct](#-code-of-conduct) +- [Ways to Contribute](#-ways-to-contribute) +- [Development Setup](#-development-setup) +- [Pull Request Process](#-pull-request-process) +- [Reporting Bugs & Issues](#-reporting-bugs--issues) +- [Feature Requests](#-feature-requests) +- [Community & Support](#-community--support) +- [License](#-license) + +--- + +## 📜 Code of Conduct + +We follow a [Code of Conduct](https://opensource.guide/code-of-conduct/) to foster an open and welcoming community. By participating, you agree to uphold these standards. + +--- + +## 🀝 Ways to Contribute + +Here are some ways you can help improve CheckCle: + +- 🐞 **Report Bugs** – Found a glitch? Let us know by opening a [GitHub Issue](https://github.com/operacle/checkcle/issues). +- 🌟 **Suggest Features** – Have an idea? Start a [Discussion](https://github.com/operacle/checkcle/discussions) or open a Feature Request issue. +- 🛠 **Submit Pull Requests** – Improve the code, fix bugs, add features, or enhance the docs. +- 📝 **Improve Documentation** – Even a typo fix helps! +- 🌍 **Spread the Word** – Star ⭐ the repo, share it on socials, and invite others to contribute! + +--- + +## 🧰 Development Setup + +Before contributing code, set up the project locally: + +### 1. Fork the Repository +Click "Fork" on [GitHub](https://github.com/operacle/checkcle) to create your own copy. + +### 2. Clone Your Fork +```bash +git clone --branch develop https://github.com/operacle/checkcle.git +cd checkcle +``` + +### 3. Install Dependencies +Follow the instructions in the README or project docs to install required packages and run the local development server. + +### 4. Start Local Development +```bash +#Web Application +cd application/ +npm install && npm run dev + +#Server Backend +cd server +./pocketbase serve --dir pb_data + +If you're not using localhost, please run with this (./pocketbase serve --http=0.0.0.0:8090 --dir pb_data) +``` + +### 4. Start Service Check Operation + +```bash +#Server Backend +Start Service Operation (Check Service for PING, HTTP, TCP, DNS) + +cd server/service-operation + +go run main.go (you do not need to change the .env while it's the localhost connection) +``` + +### 5. Start Distributed Regional Agent +```bash +#### 1. Fork the Repository +Click "Fork" on [GitHub](https://github.com/operacle/Distributed-Regional-Monitoring) to create your own copy. + +#### 2. Clone Your Fork +git clone --branch main https://github.com/operacle/Distributed-Regional-Monitoring.git +cd Distributed-Regional-Monitoring + +#### 3. Install Go Service (make sure you have installed the Go Service) + +Copy .env.example -> .env +Change regional agent configuration in .env file +and Run: go run main.go + +``` +--- + +## ✅ Pull Request Process + +1. Ensure your code follows the existing style and naming conventions. +2. Write clear, concise commit messages. +3. Push your branch and open a Pull Request (PR) on the `develop` branch. +4. Provide a meaningful PR description (what/why/how). +5. Link related issues if applicable (e.g. `Closes #12`). +6. Make sure all checks pass (e.g., linting, tests). + +We’ll review your PR, request changes if needed, and merge it once ready! + +--- + +## 🐛 Reporting Bugs & Issues + +Please include as much information as possible: +- A clear, descriptive title +- Steps to reproduce +- Expected vs actual behavior +- Environment info (OS, browser, device, etc.) +- Screenshots or logs if applicable + +Use the [Issue Tracker](https://github.com/operacle/checkcle/issues) to report. + +--- + +## 💡 Feature Requests + +We’d love to hear your ideas! Open a [Discussion](https://github.com/operacle/checkcle/discussions) or Feature Request issue. Make sure it’s not already listed in the [Roadmap](https://github.com/operacle/checkcle#development-roadmap). + +--- + +## 🌍 Community & Support + +Need help? Want to connect? + +- 💬 [Join our Discord](https://discord.gg/xs9gbubGwX) +- 🗣 Start or join a [GitHub Discussion](https://github.com/operacle/checkcle/discussions) +- 🐊 Follow us on [X (Twitter)](https://x.com/tl) + +--- + +## 📜 License + +By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE). + +--- + +## 🙏 Thank You + +We’re excited to build CheckCle together — a powerful monitoring platform **for the community, by the community**. Your support means the world! 💙 diff --git a/README_ja.md b/docs/README_ja.md similarity index 89% rename from README_ja.md rename to docs/README_ja.md index 8009ec1..f2c6938 100644 --- a/README_ja.md +++ b/docs/README_ja.md @@ -1,3 +1,36 @@ +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

+ ![CheckCle Platform](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/server-detail-page.png) # 🚀 CheckCleずは diff --git a/docs/README_km.md b/docs/README_km.md new file mode 100644 index 0000000..f605d66 --- /dev/null +++ b/docs/README_km.md @@ -0,0 +1,182 @@ +## 🌐 Select Language + + + + + + + +
+ + English +
English +
+
+ + Khmer +
ខ្មែរ +
+
+ + Japanese +
Japanese +
+
+ +

+ Thank you to all our contributors, users, and supporters for making this project thrive. +

+ +

+ 🚀 Stay tuned for more updates, features, and improvements. +

+ +![CheckCle Platform](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/server-detail-page.png) + +# 🚀 តសឆេកខលគឺជាអ្វឞ? + +ឆេកខល (CheckCle) គឺជាប្រពន័្ធប្រភពបសកចំហមវយដែលបសកអោយប្រសប្រាស់ទឌទាំងពឞភពលោកដោយឥតគិតថ្លៃ ដែលមានក្នុងមុខងារចំបងក្នុងការត្រវតពិនិត្យវ៉េបសាយ កម្មវិធឞបច្ចេកវិទ្យា​និងហេដ្ឋារចនាសម្ព័ន្ធនៃម៉ាសុឞនមេជាដសម។ វាផ្តល់ឱ្យអ្នកអភិវឌ្ឍន៍ អ្នកគ្រប់គ្រងប្រព័ន្ធ និងក្រុម DevOps នឌវការពត័ស៊ឞជម្រៅ និងទិន្នន័យនៃហេដ្ឋារចនាសម្ព័ន្ធ មិនថាជាម៉ាស៊ឞនមេ កម្មវិធឞ ឬសេវាកម្មនោះទេ។ ជាមវយ CheckCle អ្នកមសលឃសញជាក្រាប វិភាគ​ និងហេតុការផ្សេងៗ​ និងធានាបាននឌវការជឌនដំណសរការនៅហេតុការផ្សេងៗដែលបានកសតឡសង។ + +## 🎯 តេស្តសាកល្បងផ្ទាល់ +👉 **Try it now:** [CheckCle Live Demo](https://demo.checkcle.io) + +## 🌟 មុខងារចម្បង + +### ពិនិត្យប្រព័ន្ធវ៉េបសាយ និងការត្រវតពិនិត្យហេដ្ឋារចនាសម្ព័ន្ធនៃម៉ាស៊ឞនមេ +- ត្រវតពិនិត្យពិធឞកម្មវិធឞ HTTP, DNS, and Ping protocols +- ត្រវតពិនិត្យពិធឞកម្មវិធឞ TCP-based, API services (e.g., FTP, SMTP, HTTP) +- តាមដាននិងវិភាគលម្អិត, response times, and performance issues +- តាមដាននិងវិភាគលម្អិតពឞដំបន់ឬប្រទេសផ្សេងៗបាន +- ប្រវត្តិឧប្បត្តិហេតុ (UP/DOWN/WARNING/PAUSE) +- តាមដាន​ SSL & Domain (Domain, Issuer, Expiration Date, Days Left, Status, Last Notified) +- តាមដាននិងត្រវតពិនិត្យម៉ាស៊ឞនមេ, Supports Linux (🐧 Debian, Ubuntu, CentOS, Red Hat, etc.) and Windows (Beta). And Servers metrics like CPU, RAM, disk usage, and network activity) with an one-line installation angent script. +- រៀបចំកាលវិភាគ និងការគ្រប់គ្រងឧប្បត្តិហេតុ +- ទំព័រស្ថានភាពប្រតិបត្តិការ +- ការជឌនដំណឹងតាមរយៈ email, Telegram, Discord, and Slack +- របាយការណ៍ & វិភាគលម្អិត +- ផ្ទាំងការកំណត់ប្រព័ន្ធគ្រប់គ្រង (User Management, Data Retention, Multi-language, Themes (Dark & Light Mode), Notification and channels and alert templates). + +## #⃣ ការចាប់ផ្តសម + +### ដំណសរការលសស្ថាបត្យកម្មដឌចជា +* ✅ x86_64 PCs, laptops, servers (amd64) +* ✅ Modern Raspberry Pi 3/4/5 with (64-bit OS), Apple Silicon Macs (arm64) + +### អ្នកអាចដំឡសង CheckCle ដោយជ្រសសរសសជម្រសសមវយក្នុងចំណោមជម្រសសខាងក្រោម។ + + +1. CheckCle One-Click Installation - Just copy and run on terminal +```bash +curl -fsSL https://checkcle.io/install.sh | bash + +``` +2. Install with docker run. Just copy ready docker run command below +```bash +docker run -d \ + --name checkcle \ + --restart unless-stopped \ + -p 8090:8090 \ + -v /opt/pb_data:/mnt/pb_data \ + --ulimit nofile=4096:8192 \ + operacle/checkcle:latest + +``` +3. Install with Docker compose Configuration. +```bash + +version: '3.9' + +services: + checkcle: + image: operacle/checkcle:latest + container_name: checkcle + restart: unless-stopped + ports: + - "8090:8090" # Web Application + volumes: + - /opt/pb_data:/mnt/pb_data # Host directory mapped to container path + ulimits: + nofile: + soft: 4096 + hard: 8192 + +``` +3. ចឌលទៅកាន់ផ្ទាំងគ្រប់គ្រង + + Default URL: http://0.0.0.0:8090 + User: admin@example.com + Passwd: Admin123456 + +4. ឯកសារ​ និងរបៀបប្រសប្រាស់ផ្សេង at https://docs.checkcle.io + +### +![checkcle-collapse-black](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/uptime-monitoring.png) +![Service Detail Page](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/uptime-service-detail.png) +![checkcle-server-instance](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/instance-server-monitoring.png) +![Schedule Maintenance](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/checkcle-schedule-maintenance.png) +![SSL Monitoring](https://pub-4a4062303020445f8f289a2fee84f9e8.r2.dev/images/ssl-monitoring.png) + +## 📝 គម្រោងក្នុងការអភិវឌ្ឍន៍ប្រព័ន្ធគ្រប់គ្រង + +- ✅ Health check & uptime monitoring (HTTP) +- ✅ Dashboard UI with live stats +- ✅ Auth with Multi-users system (admin) +- ✅ Notifications (Telegram) +- ✅ Docker containerization +- ✅ CheckCle Website +- ✅ CheckCle Demo Server +- ✅ SSL & Domain Monitoring +- ✅ Schedule Maintenance +- ✅ Incident Management +- [ ] Infrastructure Server Monitoring +- ✅ Operational Status / Public Status Pages +- ✅ Uptime monitoring (HTTP, TCP, PING, DNS) Full functionality +- ✅ Distributed Regional Monitoring Agent [Support Operation](https://github.com/operacle/Distributed-Regional-Monitoring) +- ✅ System Setting Panel and Mail Settings +- ✅ User Permission Roles +- [ ] Notifications (Email/Slack/Discord/Signal) +- ✅ Data Retention & Automate Strink (Muti Options to Shrink Data & Database ) +- ✅ Open-source release with full documentation + +## 🌟 ឆេកខលសម្រាប់សហគមន៍ +- **Built with Passion**: Created by an open-source enthusiast for the community +- **Free & Open Source**: Completely free to use with no hidden costs +- **Collaborate & Connect**: Meet like-minded people passionate about Open Source + +--- + +## 🀝 របៀបក្នុងការចឌលរវមអភិវឌ្ឍន៍ប្រព័ន្ធកឌដបសកជំហ + +នេះគឺជាវិធឞមវយចំនវនដែលអ្នកអាចជវយកែលម្អ CheckCle: + +- 🐞 **រាយការណ៍កំហុស** - រកឃសញកំហុសថ្មឞ? អនុញ្ញាតឱ្យយសងដឹងដោយបសកផងដោយបង្កសត [GitHub Issue](https://github.com/operacle/checkcle/issues). +- 🌟 **ផ្តល់យោបល់** – មានគំនិតថ្មឞ?​ អនុញ្ញាតឱ្យយសងដឹងដោយបសកផងដោយបង្កសត [Discussion](https://github.com/operacle/checkcle/discussions) or open a Feature Request issue. +- 🛠 **បញ្ជឌនសំណសអភិវឌ្ឍន៍កឌដ** – កែលម្អកឌដ ជវសជុលកំហុស បន្ថែមមុខងារ ឬកែលម្អឯកសារ។ +- 📝 **ធ្វសអោយឯកសារប្រសសរឡសង** – សឌម្បឞតែការកែលម្អបន្តិចបន្តវចក៏អាចជវយបាន! +- 🌍 **ផ្សព្វផ្សាយ** – ដាក់ផ្កាយ ⭐ repo ចែករំលែកវានៅលសសង្គមហសយអញ្ជសញអ្នកផ្សេងទៀតឱ្យចឌលរវមអភិវឌ្ឍន៍! + +--- + +## 🌍 រក្សាទំនាក់ទំនង +- វ៉េបសាយ: [checkcle.io](https://checkcle.io) +- ឯកសារ: [docs.checkcle.io](https://docs.checkcle.io) +- ឃ្លាំងផ្ទុកកឌដ: ⭐ [CheckCle](https://github.com/operacle/checkcle.git) +- ទំនាក់ទំនងក្រុម: Engage via discussions and issues! +- បណ្តាញសង្គម: Join our community [@discord](https://discord.gg/xs9gbubGwX) +- X: [@tlengoss](https://x.com/tlengoss) + +## 📜 License + +CheckCle ត្រឌវបានចេញផ្សាយក្រោមអាជ្ញាប័ណ្ណ MIT ។ + +--- +## 👥 អ្នករវមចំណែក + +[![](https://contrib.rocks/image?repo=operacle/checkcle)](https://github.com/operacle/checkcle/graphs/contributors) + + +## ស្ថានភាពផ្តាយ + +[![Star History Chart](https://api.star-history.com/svg?repos=operacle/checkcle&type=Date)](https://www.star-history.com/#operacle/checkcle&Date) + +កុំភ្លេចប្រសប្រាស់ឆេកខលសម្រាប់ការងាររបស់អ្នក! 🌐