feat(proxies): CM-9 backend — polymorphic point-of-contact + resolver
- 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>
This commit is contained in:
17
src/lib/validators/proxies.ts
Normal file
17
src/lib/validators/proxies.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
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>;
|
||||
Reference in New Issue
Block a user