settingsFormSchema: ZodObject<
    {
        clientId: ZodString;
        clientSecret: ZodString;
        redirectUri: ZodString;
        fileLogLevel: ZodEnum<
            {
                DEBUG: "DEBUG";
                INFO: "INFO";
                WARNING: "WARNING";
                ERROR: "ERROR";
                CRITICAL: "CRITICAL";
            },
        >;
        logLineCount: ZodCoercedNumber<unknown>;
        maxLogFiles: ZodCoercedNumber<unknown>;
        logRetentionDays: ZodCoercedNumber<unknown>;
        skipThreshold: ZodCoercedNumber<unknown>;
        timeframeInDays: ZodCoercedNumber<unknown>;
        autoStartMonitoring: ZodDefault<ZodBoolean>;
        autoUnlike: ZodDefault<ZodBoolean>;
        pollingInterval: ZodDefault<ZodCoercedNumber<unknown>>;
    },
    $strip,
> = ...

Settings Form Validation Schema

Comprehensive validation schema for all application settings with field-specific constraints, type coercion, and validation error messages. Defines the complete contract for application configuration.

Security considerations:

  • Ensures authentication credentials are properly formatted
  • Prevents unreasonable values for performance-critical settings
  • Maintains type safety through explicit validation

Performance boundaries:

  • Sets reasonable limits for resource-intensive features like logging
  • Constrains polling frequency to prevent API rate limit issues
  • Balances data retention with storage efficiency
export const settingsFormSchema = z.object({
// Spotify API credentials
clientId: z.string().min(1, { message: "Client ID is required" }),
clientSecret: z.string().min(1, { message: "Client Secret is required" }),
redirectUri: z.string().min(1, { message: "Redirect URI is required" }),

// App settings
fileLogLevel: z.enum(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]),
logLineCount: z.coerce.number().int().min(10).max(10000),
maxLogFiles: z.coerce.number().int().min(1).max(100),
logRetentionDays: z.coerce.number().int().min(1).max(365),
skipThreshold: z.coerce.number().int().min(1).max(10),
timeframeInDays: z.coerce.number().int().min(1).max(365),
autoStartMonitoring: z.boolean().default(true),
autoUnlike: z.boolean().default(true),
pollingInterval: z.coerce.number().int().min(500).max(10000).default(1000),
});