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
+2 -2
View File
@@ -29,7 +29,7 @@ var services = sqliteTable("services", {
{ onDelete: "set null" }
),
subdomain: text("subdomain"),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(false),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
sort_order: integer("sort_order").notNull().default(0),
lb_weight: integer("lb_weight").notNull().default(1),
lb_priority: integer("lb_priority").notNull().default(1),
@@ -932,7 +932,7 @@ function getService(db, id) {
}
function createService(db, name, slug) {
const sortOrder = maxSortOrderInGroup(db, null) + 1;
const id = db.insert(services).values({ name, slug, subdomain: slug, sort_order: sortOrder }).returning({ id: services.id }).get().id;
const id = db.insert(services).values({ name, slug, subdomain: slug, sort_order: sortOrder, enabled: true }).returning({ id: services.id }).get().id;
return getService(db, id);
}
function updateService(db, id, name, slug) {
+1 -1
View File
@@ -649,7 +649,7 @@ export function createService(db: Db, name: string, slug: string): Service {
const sortOrder = maxSortOrderInGroup(db, null) + 1;
const id = db
.insert(services)
.values({ name, slug, subdomain: slug, sort_order: sortOrder })
.values({ name, slug, subdomain: slug, sort_order: sortOrder, enabled: true })
.returning({ id: services.id })
.get()!.id;
return getService(db, id);
+1 -1
View File
@@ -28,7 +28,7 @@ export const services = sqliteTable("services", {
{ onDelete: "set null" },
),
subdomain: text("subdomain"),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(false),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
sort_order: integer("sort_order").notNull().default(0),
lb_weight: integer("lb_weight").notNull().default(1),
lb_priority: integer("lb_priority").notNull().default(1),
+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(),
})