Files
pn-new-crm/src/lib/validators/companies.ts
Matt Ciaccio 27cdbcc695 chore(i18n): drop legacy free-text country/nationality columns
Test-data only — no production migration needed (per earlier decision).
Schema is now ISO-only; readers convert ISO codes to localized names where
human-readable output is required (EOI documents, invoices, portal).

Migration 0016 drops:
  - clients.nationality
  - companies.incorporation_country
  - client_addresses.{state_province, country}
  - company_addresses.{state_province, country}

Code paths that previously read free-text values now read the ISO column
and pass through `getCountryName()` / `getSubdivisionName()` for rendering.
Document templates ({{client.nationality}}), portal client view, EOI/
reservation-agreement contexts, and invoice billing addresses all updated.

Public yacht-interest endpoint (/api/public/interests) drops the legacy
fields from its insert path and writes ISO codes only. The Zod validators
no longer accept the legacy fields — older website builds posting raw
'incorporationCountry' / 'country' / 'stateProvince' will get 400s.
Server-side phone normalization is unchanged.

Seed data updated to use ISO codes (GB/FR/ES/GR/SE/IT/GH/MC/PA), spread
across continents to keep test fixtures realistic.

Test assertions updated to match the new render shape (e.g.
'United States' not 'US', 'California' not 'CA').

Vitest: 741 -> 741 (unchanged count; assertions updated, no new tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 19:00:57 +02:00

31 lines
1.3 KiB
TypeScript

import { z } from 'zod';
import { baseListQuerySchema } from '@/lib/api/route-helpers';
import { optionalCountryIsoSchema, optionalSubdivisionIsoSchema } from '@/lib/validators/i18n';
export const createCompanySchema = z.object({
name: z.string().min(1).max(200),
legalName: z.string().optional(),
taxId: z.string().optional(),
registrationNumber: z.string().optional(),
/** ISO-3166-1 alpha-2 country of incorporation. */
incorporationCountryIso: optionalCountryIsoSchema.optional(),
/** ISO 3166-2 state/province of incorporation. */
incorporationSubdivisionIso: optionalSubdivisionIsoSchema.optional(),
incorporationDate: z.coerce.date().optional(),
status: z.enum(['active', 'dissolved']).optional().default('active'),
billingEmail: z.string().email().optional(),
notes: z.string().optional(),
tagIds: z.array(z.string()).optional().default([]),
});
export const updateCompanySchema = createCompanySchema.partial().omit({ tagIds: true });
export const listCompaniesSchema = baseListQuerySchema.extend({
status: z.enum(['active', 'dissolved']).optional(),
search: z.string().optional(),
});
export type CreateCompanyInput = z.infer<typeof createCompanySchema>;
export type UpdateCompanyInput = z.infer<typeof updateCompanySchema>;
export type ListCompaniesInput = z.infer<typeof listCompaniesSchema>;