- proxies table (migration 0095, port_id cascade), one per client/interest/yacht - service: get/set(upsert)/clear + resolveEffectiveProxy (yacht → interest → client precedence), port-scoped with entity-in-port guard - per-entity sub-resource routes (/clients|interests|yachts/[id]/proxy) reusing each entity's existing view/edit permission (no new permission resource) - 3 integration tests (CRUD/upsert, tenant guard, resolution precedence) Backend only — ProxyCard UI on the 3 detail pages to follow. tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18 lines
657 B
TypeScript
18 lines
657 B
TypeScript
import { z } from 'zod';
|
|
|
|
/** CM-9: proxy / point-of-contact. */
|
|
|
|
export const PROXY_ENTITY_TYPES = ['client', 'interest', 'yacht'] as const;
|
|
export type ProxyEntityType = (typeof PROXY_ENTITY_TYPES)[number];
|
|
|
|
export const setProxySchema = z.object({
|
|
name: z.string().trim().min(1, 'Name is required').max(200),
|
|
// Loose contact fields — empty strings are normalised to null in the service.
|
|
email: z.string().trim().max(320).nullish(),
|
|
phone: z.string().trim().max(50).nullish(),
|
|
relationship: z.string().trim().max(100).nullish(),
|
|
notes: z.string().trim().max(2000).nullish(),
|
|
});
|
|
|
|
export type SetProxyInput = z.infer<typeof setProxySchema>;
|