/** * Organization data transformation utilities * Handles business logic for transforming and validating organization data * Separated from API services to maintain clean separation of concerns */ import { z } from 'zod'; import type { BackendOrganization } from '@/schemas/backend/organization'; /** * Fallback schema for handling legacy/malformed organization data * Used when strict validation fails */ const fallbackOrganizationSchema = z .object({ ID: z.string().optional(), id: z.string().optional(), Name: z.string().optional(), name: z.string().optional(), Sector: z.string().optional(), sector: z.string().optional(), Description: z.string().optional(), description: z.string().optional(), LogoURL: z.string().optional(), logoURL: z.string().optional(), logoUrl: z.string().optional(), Website: z.string().optional(), website: z.string().optional(), Address: z.string().optional(), address: z.string().optional(), Verified: z.boolean().optional(), verified: z.boolean().optional(), Subtype: z.string().optional(), subtype: z.string().optional(), Latitude: z.number().optional(), latitude: z.number().optional(), Longitude: z.number().optional(), longitude: z.number().optional(), CreatedAt: z.string().optional(), createdAt: z.string().optional(), UpdatedAt: z.string().optional(), updatedAt: z.string().optional(), }) .transform((org) => ({ ID: org.ID || org.id || '', Name: org.Name || org.name || '', Sector: org.Sector || org.sector || '', Description: org.Description || org.description || '', LogoURL: org.LogoURL || org.logoURL || org.logoUrl, Website: org.Website || org.website, Address: org.Address || org.address, Verified: org.Verified ?? org.verified ?? false, Subtype: org.Subtype || org.subtype, Latitude: org.Latitude ?? org.latitude, Longitude: org.Longitude ?? org.longitude, CreatedAt: org.CreatedAt || org.createdAt, UpdatedAt: org.UpdatedAt || org.updatedAt, })); /** * Transform raw organization data with fallback logic * Handles both strict validation and legacy data formats */ export function transformOrganizationData(data: unknown): BackendOrganization { // First try strict validation const strictSchema = z.object({ ID: z.string(), Name: z.string(), Sector: z.string(), Description: z.string().optional(), LogoURL: z.string().optional(), Website: z.string().optional(), Address: z.string().optional(), Verified: z.boolean(), Subtype: z.string().optional(), Latitude: z.number().optional(), Longitude: z.number().optional(), CreatedAt: z.string().optional(), UpdatedAt: z.string().optional(), }); const strictResult = strictSchema.safeParse(data); if (strictResult.success) { return strictResult.data as BackendOrganization; } // Fall back to flexible transformation const fallbackResult = fallbackOrganizationSchema.safeParse(data); if (fallbackResult.success) { return fallbackResult.data as BackendOrganization; } throw new Error('Unable to transform organization data'); } /** * Transform array of organization data with filtering * Removes organizations with invalid IDs and applies transformations */ export function transformOrganizationsList(data: unknown[]): BackendOrganization[] { if (!Array.isArray(data)) { throw new Error('Expected array of organizations'); } return data.map(transformOrganizationData).filter((org) => org.ID && org.ID.trim() !== ''); }