UNPKG

@codervisor/devlog-core

Version:

Core devlog management functionality

120 lines (119 loc) 4.15 kB
/** * Project validation schemas using Zod * * This module provides runtime validation for project-related data at the business logic layer. * It ensures data integrity and business rule compliance across all entry points. */ import { z } from 'zod'; /** * Project Settings validation schema */ export const ProjectSettingsSchema = z.object({ defaultPriority: z.enum(['low', 'medium', 'high', 'critical']).optional(), theme: z.string().optional(), autoArchiveDays: z.number().min(1).max(365).optional(), availableTags: z.array(z.string()).optional(), customSettings: z.record(z.any()).optional(), }); /** * Project creation request schema (excludes auto-generated fields) */ export const CreateProjectRequestSchema = z.object({ name: z.string() .min(1, 'Project name is required') .max(100, 'Project name must be less than 100 characters') .regex(/^[a-zA-Z0-9\s\-_]+$/, 'Project name can only contain letters, numbers, spaces, hyphens, and underscores'), description: z.string() .max(500, 'Description must be less than 500 characters') .optional(), repositoryUrl: z.string() .url('Repository URL must be a valid URL') .optional() .or(z.literal('')), // Allow empty string settings: ProjectSettingsSchema.optional(), }); /** * Project update request schema (all fields optional) */ export const UpdateProjectRequestSchema = z.object({ name: z.string() .min(1, 'Project name is required') .max(100, 'Project name must be less than 100 characters') .regex(/^[a-zA-Z0-9\s\-_]+$/, 'Project name can only contain letters, numbers, spaces, hyphens, and underscores') .optional(), description: z.string() .max(500, 'Description must be less than 500 characters') .optional() .or(z.literal('')), // Allow empty string to clear description repositoryUrl: z.string() .url('Repository URL must be a valid URL') .optional() .or(z.literal('')), // Allow empty string to clear URL settings: ProjectSettingsSchema.optional(), }); /** * Project ID parameter schema */ export const ProjectIdSchema = z.object({ id: z.number().int().positive('Project ID must be a positive integer'), }); /** * Validation functions for business logic layer */ export class ProjectValidator { /** * Validate project creation data */ static validateCreateRequest(data) { const result = CreateProjectRequestSchema.safeParse(data); if (result.success) { return { success: true, data: result.data }; } return { success: false, errors: result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`), }; } /** * Validate project update data */ static validateUpdateRequest(data) { const result = UpdateProjectRequestSchema.safeParse(data); if (result.success) { return { success: true, data: result.data }; } return { success: false, errors: result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`), }; } /** * Validate project ID */ static validateProjectId(id) { const result = ProjectIdSchema.safeParse({ id }); if (result.success) { return { success: true, data: result.data.id }; } return { success: false, errors: result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`), }; } /** * Business rule validation - check for duplicate project names */ static async validateUniqueProjectName(name, excludeId, checkFunction) { if (!checkFunction) { return { success: true }; // Skip if no check function provided } const isDuplicate = await checkFunction(name, excludeId); if (isDuplicate) { return { success: false, error: `Project with name "${name}" already exists` }; } return { success: true }; } }