feat(uat-batch): M43 follow-up — yacht detail field history
Some checks failed
Build & Push Docker Images / lint (push) Failing after 1m35s
Build & Push Docker Images / build-and-push (push) Has been skipped

Extends Phase 3 from the M43 commit to yacht detail:
- New /api/v1/yachts/[id]/field-history endpoint joins through
  interests.yachtId (no schema migration needed) and filters to
  'yacht.%' paths so client-scoped overrides on the same interest
  don't bleed into the yacht surface.
- FieldHistoryScope.type accepts 'yacht'; provider URL routing
  generalised to /api/v1/<type>s/<id>/field-history.
- yacht-tabs OverviewTab wrapped in the provider; Name + the three
  ft-dimension rows get historyPath wired (m-dimension rows skipped —
  they're a unit-converted view of the same source value, and the
  supplemental writer only ever stores ft).

Addresses tab on Client detail intentionally left unwired — would
need AddressesEditor (a shared component) to surface icons per row,
which is more than the 5-min scope.

1454/1454 vitest, tsc clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 12:57:47 +02:00
parent f6cb733424
commit 52493801e0
3 changed files with 169 additions and 105 deletions

View File

@@ -33,7 +33,7 @@ import { getBindableField } from '@/lib/templates/bindable-fields';
import { cn } from '@/lib/utils';
export interface FieldHistoryScope {
type: 'interest' | 'client';
type: 'interest' | 'client' | 'yacht';
id: string;
}
@@ -67,10 +67,7 @@ export function FieldHistoryProvider({ scope, children }: ProviderProps) {
queryKey: ['field-history', scope?.type, scope?.id],
queryFn: async () => {
if (!scope) return [] as FieldHistoryRow[];
const url =
scope.type === 'interest'
? `/api/v1/interests/${scope.id}/field-history`
: `/api/v1/clients/${scope.id}/field-history`;
const url = `/api/v1/${scope.type}s/${scope.id}/field-history`;
const res = await apiFetch<{ data: FieldHistoryRow[] }>(url);
return res.data;
},