PR: #703: fix(record): simplify document row actions [Chore-2758] by @ankitmaheshwari-com
View PR →
Story-2726 · Record register + Blake drawer

Blake's quick analysis, and Blake's name on every record

Two founder-UAT refinements. Blake gets his own face as the way into his quick analysis, and the clean legal name he generates becomes the record's primary name — the messy upload kept, never lost.

Part A — Blake's quick analysis (rename + hover face)

His own face, always there

Blake's avatar sits on every row at low opacity — ambient proof he has read it — and comes to full strength under the cursor. It replaces the old generic scan glyph.

Hover opens it

Dwell ~320ms (or click) and Blake's panel slides in. A cursor merely crossing the column never trips it.

Renamed heading

The panel eyebrow reads Blake's quick analysis (was the grammatically-off "Blake read this").

Panels stay separate

Blake's analysis and the document Details remain two distinct drawers — no merge.

Part B — Blake's name is the record name

Primary name

The Record cell shows Blake's card name. Every surface that shows a document name (row, Details title, bundle labels, exports) routes through one displayName() chokepoint, so they can never disagree.

Full name on hover

Long names truncate in the fixed-width column; hovering the name shows a tooltip with the full, untruncated name.

Original file kept

A new hideable Original file column (hidden by default, toggled via ⚙ View → Fields) plus the Details panel both keep the file as uploaded.

Honest fallback

No card name yet → registrar name → the original filename. A row is never nameless while Blake is still reading.

Real data path

GET /app/matters/{matter_id}/record/bootstrap → DocumentListItem.card.name.value → toRegisterDocument → displayName(). The card already rides the list payload (Story-2700), so no new request. DocumentListItem.filename feeds the Original-file column and Details.

Review path

SurfaceExpected proof
Record row · document nameClicking Blake's legal name opens the "Blake's quick analysis" panel.
Record register (live)Name column shows Blake's legal name; hover shows full name; ⚙ View → Fields reveals a toggleable "Original file" column carrying the raw upload.
Details drawerTitle = Blake's name; original filename mono underneath, unchanged otherwise.
display-name.test.tsCard name → registrar name → filename precedence, and blank card names treated as absent.

Files changed

48 file(s), +2479 / -186 lines

Path Role + -
openapi/app-api.jsonConfig+450-2
openapi/permission-map.jsonConfig+27-3
src/components/documents/register/register-blake-interaction.test.tsxComponent+38-28
src/components/documents/register/register-blake-trigger.stories.tsxComponent+0-57
src/components/documents/register/register-blake-trigger.tsxComponent+0-44
src/components/documents/register/register-document-cell.tsxComponent+0-2
src/components/documents/register/register-document-row.stories.tsxComponent+1-2
src/components/documents/register/register-document-row.tsxComponent+0-1
src/components/documents/register/register-document-title.tsxComponent+1-1
src/components/documents/register/register-row-quick-actions.stories.tsxComponent+7-10
src/components/documents/register/register-row-quick-actions.tsxComponent+14-15
src/components/documents/register/register-table.stories.tsxComponent+0-1
src/components/documents/register/register-table.tsxComponent+0-4
src/components/documents/register/register-view.tsxComponent+0-4
src/gen/client/appPreviewMemberDeactivation.tsGenerated contract+63-0
src/gen/client/appPreviewMemberFirmRoleChange.tsGenerated contract+66-0
src/gen/client/index.tsGenerated contract+2-0
src/gen/hooks/index.tsGenerated contract+16-0
src/gen/hooks/useAppPreviewMemberDeactivation.tsGenerated contract+131-0
src/gen/hooks/useAppPreviewMemberDeactivationSuspense.tsGenerated contract+133-0
src/gen/hooks/useAppPreviewMemberFirmRoleChange.tsGenerated contract+141-0
src/gen/hooks/useAppPreviewMemberFirmRoleChangeSuspense.tsGenerated contract+142-0
src/gen/index.tsGenerated contract+79-0
src/gen/schemas/firmMemberMutationResponse.jsonGenerated contract+188-0
src/gen/schemas/firmMemberTeamChangePreviewResponse.jsonGenerated contract+104-0
src/gen/schemas/firmMemberTeamConsequence.jsonGenerated contract+73-0
src/gen/schemas/firmMemberTeamConsequenceOutcome.jsonGenerated contract+7-0
src/gen/schemas/firmMemberTeamConsequenceUserRef.jsonGenerated contract+25-0
src/gen/types/AppDeactivateMember.tsGenerated contract+3-3
src/gen/types/AppPreviewMemberDeactivation.tsGenerated contract+71-0
src/gen/types/AppPreviewMemberFirmRoleChange.tsGenerated contract+76-0
src/gen/types/AppUpdateMemberFirmRole.tsGenerated contract+3-3
src/gen/types/FirmMemberMutationResponse.tsGenerated contract+63-0
src/gen/types/FirmMemberTeamChangePreviewResponse.tsGenerated contract+29-0
src/gen/types/FirmMemberTeamConsequence.tsGenerated contract+48-0
src/gen/types/FirmMemberTeamConsequenceOutcome.tsGenerated contract+17-0
src/gen/types/FirmMemberTeamConsequenceUserRef.tsGenerated contract+26-0
src/gen/types/index.tsGenerated contract+33-0
src/gen/zod/appDeactivateMemberSchema.tsGenerated contract+3-3
src/gen/zod/appPreviewMemberDeactivationSchema.tsGenerated contract+88-0
src/gen/zod/appPreviewMemberFirmRoleChangeSchema.tsGenerated contract+95-0
src/gen/zod/appUpdateMemberFirmRoleSchema.tsGenerated contract+3-3
src/gen/zod/firmMemberMutationResponseSchema.tsGenerated contract+67-0
src/gen/zod/firmMemberTeamChangePreviewResponseSchema.tsGenerated contract+32-0
src/gen/zod/firmMemberTeamConsequenceOutcomeSchema.tsGenerated contract+17-0
src/gen/zod/firmMemberTeamConsequenceSchema.tsGenerated contract+44-0
src/gen/zod/firmMemberTeamConsequenceUserRefSchema.tsGenerated contract+25-0
src/gen/zod/index.tsGenerated contract+28-0