refactor(services): update service creation logic and enhance service group schema
Build and Push CFDM Docker Image / build-and-push (push) Successful in 2m2s
Build and Push CFDM Docker Image / create-release (push) Skipped
Build and Push CFDM Docker Image / update-wiki (push) Successful in 6s

- Changed service creation to default `enabled` to true in the database schema.
- Updated service group schema to set default values for `icon`, `domain`, and health check parameters.
- Refactored service routes to use `await` for fetching service views, ensuring proper asynchronous handling.
- Improved error handling in service groups query to provide clearer feedback on response validation.

This commit enhances the overall service management experience by ensuring services are enabled by default and improving the robustness of the service group schema.
This commit is contained in:
Denozordec
2026-08-07 13:18:47 +07:00
parent 3fb8480f8a
commit ce8393e0c3
12 changed files with 346 additions and 186 deletions
+51 -51
View File
@@ -304,8 +304,8 @@ declare const serviceGroupSchema: z.ZodObject<{
bgp: "bgp";
custom: "custom";
}>>;
icon: z.ZodNullable<z.ZodString>;
domain: z.ZodNullable<z.ZodString>;
icon: z.ZodDefault<z.ZodNullable<z.ZodString>>;
domain: z.ZodDefault<z.ZodNullable<z.ZodString>>;
enabled: z.ZodCoercedBoolean<unknown>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -319,9 +319,9 @@ declare const serviceGroupSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
@@ -353,8 +353,8 @@ declare const serviceDomainBindingSchema: z.ZodPipe<z.ZodObject<{
}>>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip: z.ZodOptional<z.ZodNullable<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_cname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -368,13 +368,13 @@ declare const serviceDomainBindingSchema: z.ZodPipe<z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>, z.ZodTransform<{
target_ips: string[];
target_ip_weights: Record<string, number>;
@@ -445,8 +445,8 @@ declare const serviceViewSchema: z.ZodObject<{
}>>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip: z.ZodOptional<z.ZodNullable<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_cname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -460,13 +460,13 @@ declare const serviceViewSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>, z.ZodTransform<{
target_ips: string[];
target_ip_weights: Record<string, number>;
@@ -530,8 +530,8 @@ declare const serviceGroupViewSchema: z.ZodObject<{
bgp: "bgp";
custom: "custom";
}>>;
icon: z.ZodNullable<z.ZodString>;
domain: z.ZodNullable<z.ZodString>;
icon: z.ZodDefault<z.ZodNullable<z.ZodString>>;
domain: z.ZodDefault<z.ZodNullable<z.ZodString>>;
enabled: z.ZodCoercedBoolean<unknown>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -545,9 +545,9 @@ declare const serviceGroupViewSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
@@ -578,8 +578,8 @@ declare const serviceGroupViewSchema: z.ZodObject<{
}>>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip: z.ZodOptional<z.ZodNullable<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_cname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -593,13 +593,13 @@ declare const serviceGroupViewSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>, z.ZodTransform<{
target_ips: string[];
target_ip_weights: Record<string, number>;
@@ -672,8 +672,8 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
bgp: "bgp";
custom: "custom";
}>>;
icon: z.ZodNullable<z.ZodString>;
domain: z.ZodNullable<z.ZodString>;
icon: z.ZodDefault<z.ZodNullable<z.ZodString>>;
domain: z.ZodDefault<z.ZodNullable<z.ZodString>>;
enabled: z.ZodCoercedBoolean<unknown>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -687,9 +687,9 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
@@ -720,8 +720,8 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
}>>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip: z.ZodOptional<z.ZodNullable<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_cname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -735,13 +735,13 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>, z.ZodTransform<{
target_ips: string[];
target_ip_weights: Record<string, number>;
@@ -828,8 +828,8 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
}>>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip: z.ZodOptional<z.ZodNullable<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_cname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
@@ -843,13 +843,13 @@ declare const serviceGroupsResponseSchema: z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
}, z.core.$strip>, z.ZodTransform<{
target_ips: string[];
target_ip_weights: Record<string, number>;
@@ -967,8 +967,8 @@ declare const serviceBindingSchema: z.ZodPipe<z.ZodObject<{
service_slug: z.ZodString;
target_ip: z.ZodNullable<z.ZodString>;
target_ips: z.ZodOptional<z.ZodArray<z.ZodString>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
target_ip_weights: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
target_ip_priorities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedNumber<unknown>>>;
lb_mode: z.ZodCatch<z.ZodEnum<{
round_robin: "round_robin";
failover: "failover";
@@ -981,13 +981,13 @@ declare const serviceBindingSchema: z.ZodPipe<z.ZodObject<{
ping: "ping";
dns: "dns";
}>>;
health_check_port: z.ZodNullable<z.ZodNumber>;
health_check_path: z.ZodNullable<z.ZodString>;
health_check_expected_status: z.ZodNullable<z.ZodNumber>;
health_check_port: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_path: z.ZodDefault<z.ZodNullable<z.ZodString>>;
health_check_expected_status: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
health_check_interval_sec: z.ZodDefault<z.ZodNumber>;
health_check_timeout_ms: z.ZodDefault<z.ZodNumber>;
health_check_verify_tls: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
sync_status: z.ZodNullable<z.ZodString>;
sync_status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
created_at: z.ZodString;
updated_at: z.ZodString;
}, z.core.$strip>, z.ZodTransform<{
+17 -17
View File
@@ -203,15 +203,15 @@ var serviceGroupSchema = z.object({
id: z.number(),
name: z.string(),
type: serviceGroupTypeSchema.catch("custom"),
icon: z.string().nullable(),
domain: z.string().nullable(),
icon: z.string().nullable().default(null),
domain: z.string().nullable().default(null),
enabled: z.coerce.boolean(),
lb_mode: lbModeSchema.catch("round_robin"),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch("tcp"),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3e3),
health_check_verify_tls: z.coerce.boolean().default(false),
@@ -240,19 +240,19 @@ var serviceDomainBindingSchema = z.object({
record_type: z.enum(["A", "CNAME"]).default("A"),
target_ips: z.array(z.string()).optional(),
target_ip: z.string().nullable().optional(),
target_ip_weights: z.record(z.string(), z.number()).optional(),
target_ip_priorities: z.record(z.string(), z.number()).optional(),
target_ip_weights: z.record(z.string(), z.coerce.number()).optional(),
target_ip_priorities: z.record(z.string(), z.coerce.number()).optional(),
target_cname: z.string().nullable().optional(),
lb_mode: lbModeSchema.catch("round_robin"),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch("tcp"),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3e3),
health_check_verify_tls: z.coerce.boolean().default(false),
sync_status: z.string().nullable()
sync_status: z.string().nullable().default(null)
}).transform((binding) => ({
...binding,
target_ips: binding.target_ips && binding.target_ips.length > 0 ? binding.target_ips : binding.target_ip ? [binding.target_ip] : [],
@@ -310,18 +310,18 @@ var serviceBindingSchema = z.object({
service_slug: z.string(),
target_ip: z.string().nullable(),
target_ips: z.array(z.string()).optional(),
target_ip_weights: z.record(z.string(), z.number()).optional(),
target_ip_priorities: z.record(z.string(), z.number()).optional(),
target_ip_weights: z.record(z.string(), z.coerce.number()).optional(),
target_ip_priorities: z.record(z.string(), z.coerce.number()).optional(),
lb_mode: lbModeSchema.catch("round_robin"),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch("tcp"),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3e3),
health_check_verify_tls: z.coerce.boolean().default(false),
sync_status: z.string().nullable(),
sync_status: z.string().nullable().default(null),
created_at: z.string(),
updated_at: z.string()
}).transform((binding) => ({
+17 -17
View File
@@ -59,15 +59,15 @@ export const serviceGroupSchema = z.object({
id: z.number(),
name: z.string(),
type: serviceGroupTypeSchema.catch('custom'),
icon: z.string().nullable(),
domain: z.string().nullable(),
icon: z.string().nullable().default(null),
domain: z.string().nullable().default(null),
enabled: z.coerce.boolean(),
lb_mode: lbModeSchema.catch('round_robin'),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch('tcp'),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3000),
health_check_verify_tls: z.coerce.boolean().default(false),
@@ -99,19 +99,19 @@ export const serviceDomainBindingSchema = z
record_type: z.enum(['A', 'CNAME']).default('A'),
target_ips: z.array(z.string()).optional(),
target_ip: z.string().nullable().optional(),
target_ip_weights: z.record(z.string(), z.number()).optional(),
target_ip_priorities: z.record(z.string(), z.number()).optional(),
target_ip_weights: z.record(z.string(), z.coerce.number()).optional(),
target_ip_priorities: z.record(z.string(), z.coerce.number()).optional(),
target_cname: z.string().nullable().optional(),
lb_mode: lbModeSchema.catch('round_robin'),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch('tcp'),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3000),
health_check_verify_tls: z.coerce.boolean().default(false),
sync_status: z.string().nullable(),
sync_status: z.string().nullable().default(null),
})
.transform((binding) => ({
...binding,
@@ -184,18 +184,18 @@ export const serviceBindingSchema = z
service_slug: z.string(),
target_ip: z.string().nullable(),
target_ips: z.array(z.string()).optional(),
target_ip_weights: z.record(z.string(), z.number()).optional(),
target_ip_priorities: z.record(z.string(), z.number()).optional(),
target_ip_weights: z.record(z.string(), z.coerce.number()).optional(),
target_ip_priorities: z.record(z.string(), z.coerce.number()).optional(),
lb_mode: lbModeSchema.catch('round_robin'),
health_check_enabled: z.coerce.boolean().default(false),
health_check_type: healthCheckTypeSchema.catch('tcp'),
health_check_port: z.number().nullable(),
health_check_path: z.string().nullable(),
health_check_expected_status: z.number().nullable(),
health_check_port: z.number().nullable().default(null),
health_check_path: z.string().nullable().default(null),
health_check_expected_status: z.number().nullable().default(null),
health_check_interval_sec: z.number().default(30),
health_check_timeout_ms: z.number().default(3000),
health_check_verify_tls: z.coerce.boolean().default(false),
sync_status: z.string().nullable(),
sync_status: z.string().nullable().default(null),
created_at: z.string(),
updated_at: z.string(),
})