feat(notes): aggregate-on-read for yachts, companies, residential clients

Extends the listForClientAggregated pattern to three new symmetric
helpers in notes.service so the Notes tab on yacht / company /
residential-client detail pages surfaces the full timeline (own notes
+ related-entity notes) instead of just rows on the entity itself.

  - listForYachtAggregated: yacht own + owner client (when ownership
    is polymorphic 'client') + linked interest notes.
  - listForCompanyAggregated: company own + company-owned yacht notes
    + interests linked to those yachts.
  - listForResidentialClientAggregated: own + residential interests.

Generalises NotesList so aggregate=true works for all four entity
types via SELF_SOURCE / AGGREGATABLE / SOURCE_BADGE_CLASS / SOURCE_LABEL
maps; cross-source notes render with a coloured chip and are read-only
(rep edits on the source entity's page so the right timeline records
the change).

Wires ?aggregate=true into the yacht / company / residential-client
notes routes; the yacht / company / residential-client tabs now pass
aggregate. Drops the legacy single-textarea spots on the companies
overview tab and the residential-interest "Initial brief" row in
favour of the threaded feed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 18:36:05 +02:00
parent 43191659e6
commit 20ee2c1dcf
9 changed files with 456 additions and 59 deletions

View File

@@ -343,7 +343,9 @@ export function getYachtTabs({ yachtId, currentUserId, yacht }: YachtTabsOptions
{
id: 'notes',
label: 'Notes',
content: <NotesList entityType="yachts" entityId={yachtId} currentUserId={currentUserId} />,
content: (
<NotesList entityType="yachts" entityId={yachtId} currentUserId={currentUserId} aggregate />
),
},
{
id: 'activity',