feat(notifications): include berth-range suffix in stage-change titles
Stage-change notification titles previously read "Acme Corp moved to
Reservation" with no context on which berths the deal covers. For
multi-berth deals the rep had to drill into the interest to see what
moved. With multiple deals in flight per client the bell tray became
ambiguous.
Switch the title-build path from `getPrimaryBerth` (single-row) to
`listBerthsForInterest` (full set) and append a compact suffix via
`formatBerthRange()`:
Acme Corp moved to Reservation [A1-A3, B5]
Falls back to plain "<subject> moved to <stage>" when the interest
has no linked berths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,10 +24,12 @@ import { logger } from '@/lib/logger';
|
||||
import {
|
||||
getPrimaryBerth,
|
||||
getPrimaryBerthsForInterests,
|
||||
listBerthsForInterest,
|
||||
removeInterestBerth,
|
||||
upsertInterestBerth,
|
||||
upsertInterestBerthTx,
|
||||
} from '@/lib/services/interest-berths.service';
|
||||
import { formatBerthRange } from '@/lib/templates/berth-range';
|
||||
import { buildListQuery } from '@/lib/db/query-builder';
|
||||
import { diffEntity } from '@/lib/entity-diff';
|
||||
import { softDelete, restore, withTransaction } from '@/lib/db/utils';
|
||||
@@ -1041,17 +1043,22 @@ export async function changeInterestStage(
|
||||
// canonical STAGE_LABELS dictionary so "deposit_10pct" reads as
|
||||
// "10% Deposit" everywhere.
|
||||
void (async () => {
|
||||
const [{ createNotification }, clientRow, primaryBerth] = await Promise.all([
|
||||
const [{ createNotification }, clientRow, allBerths] = await Promise.all([
|
||||
import('@/lib/services/notifications.service'),
|
||||
db.query.clients.findFirst({
|
||||
where: eq(clients.id, existing.clientId),
|
||||
columns: { fullName: true },
|
||||
}),
|
||||
getPrimaryBerth(id).catch(() => null),
|
||||
listBerthsForInterest(id).catch(
|
||||
() => [] as Awaited<ReturnType<typeof listBerthsForInterest>>,
|
||||
),
|
||||
]);
|
||||
const primaryBerth = allBerths[0] ?? null;
|
||||
const moorings = allBerths.map((b) => b.mooringNumber).filter((m): m is string => Boolean(m));
|
||||
const berthSuffix = moorings.length > 0 ? ` [${formatBerthRange(moorings)}]` : '';
|
||||
const subject =
|
||||
clientRow?.fullName ??
|
||||
(primaryBerth ? `Berth ${primaryBerth.mooringNumber}` : 'this interest');
|
||||
(primaryBerth?.mooringNumber ? `Berth ${primaryBerth.mooringNumber}` : 'this interest');
|
||||
const fromLabel = oldStage
|
||||
? (STAGE_LABELS[oldStage as PipelineStage] ?? oldStage.replace(/_/g, ' '))
|
||||
: 'unknown';
|
||||
@@ -1061,7 +1068,7 @@ export async function changeInterestStage(
|
||||
portId,
|
||||
userId: meta.userId,
|
||||
type: 'interest_stage_changed',
|
||||
title: `${subject} moved to ${toLabel}`,
|
||||
title: `${subject} moved to ${toLabel}${berthSuffix}`,
|
||||
description: `Stage changed from ${fromLabel} to ${toLabel}.`,
|
||||
link: `/interests/${id}`,
|
||||
entityType: 'interest',
|
||||
|
||||
Reference in New Issue
Block a user