feat(berths): link prospect on status change + reason chips from vocabulary

When status moves to under_offer or sold, the dialog now surfaces an
interest selector below the reason textarea. Picking an interest
passes interestId on the PATCH, which the service uses to call
setPrimaryBerth — auto-creates a primary interest_berths row if not
present, demoting any prior primary in the same transaction so the
unique partial index never fires. Cross-port leakage is blocked inside
the existing interest-berths helper.

Reasons are now offered as quick-pick chips above the textarea,
sourced from the new berth_status_change_reasons vocabulary
(Wave 5). Clicking a chip fills the textarea so reps stay on the
keyboard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 18:37:04 +02:00
parent da7ce16344
commit b93fdadb59
3 changed files with 86 additions and 2 deletions

View File

@@ -69,6 +69,13 @@ export type UpdateBerthInput = z.infer<typeof updateBerthSchema>;
export const updateBerthStatusSchema = z.object({
status: z.enum(BERTH_STATUSES),
reason: z.string().min(1, 'Reason is required'),
/**
* Optional: when status moves to under_offer or sold, the rep can pin
* the interest that triggered the change. We auto-create a primary
* interest_berths link for the chosen interest so the timeline +
* heat scorer attribute the deal correctly.
*/
interestId: z.string().min(1).optional(),
});
export type UpdateBerthStatusInput = z.infer<typeof updateBerthStatusSchema>;