docs(uat): SHIPPED annotation for PR25 (yacht ft↔m round-trip)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -260,6 +260,7 @@ _Component refactors, multi-file edits, single-service tweaks, new validators._
|
||||
> - **Verify path:** (i) confirm the yacht detail page's `useQuery` cache key matches `['yachts', yachtId]` exactly — any mismatch (`['yacht']` singular, `['yacht-detail']` wrapper) makes the invalidation a no-op. (ii) Confirm `staleTime` / `refetchOnMount` allow refetch on cache bust. (iii) If the parent refetches but the field still doesn't visually update, force-re-render via `key={yacht.lengthM}` on the counterpart InlineEditableField.
|
||||
> - **Apply to sibling surfaces:** the same bidirectional save belongs on **berth detail OverviewTab** — berth schema has `lengthM`/`widthM`/`draftM` + `_unit` discriminators and likely shows the same dual ft/m sections (verify); copy the `saveDimension()` pattern. Use the shared `src/lib/utils/dimensions.ts` helper from the earlier Dimensions-column toggle finding so the conversion ratio is centralized.
|
||||
> - **Effort:** ~20-30 min for the yacht debug + visual-update fix, +30 min if a berth equivalent needs the same logic. Captured 2026-05-18 from UAT.
|
||||
> - **SHIPPED (round-trip lossless + dedup) in 8e9efe5:** three copies of the conversion logic existed (yacht-dimensions.ts canonical, yacht-form.tsx local, yacht-tabs.tsx local) — the form-side ones used 2dp precision so `1 ft → 0.30 m → 0.98 ft` lost data on the round-trip. Consolidated both surfaces onto `feetToMeters`/`metersToFeet` from yacht-dimensions.ts and bumped precision to 4dp. New `tests/unit/yacht-dimensions.test.ts` proves round-trip lossless on the canonical 12.5 ft ↔ 3.81 m UAT case + sweeps 1/5/12.5/25/50/120/250 ft and 0.5/1/3.81/7.62/15.24/36.58 m (29/29 ✓). UI cache-key + InlineEditableField re-render path are independent debug items — flag for separate verification.
|
||||
> - **Merge `/admin/invitations` into `/admin/users` — single "people with access" surface** — _src/app/(dashboard)/[portSlug]/admin/users/page.tsx_, _src/app/(dashboard)/[portSlug]/admin/invitations/page.tsx_ (to be removed), _src/components/admin/users/_, _src/components/admin/admin-sections-browser.tsx:90-95_ (drop the Invitations card from the Access section), _src/lib/services/_ (invitations service likely already separate — keep it) — active users and pending invitations are the same lifecycle (a person who has or should have port access). Splitting them across two admin pages forces admins to bounce between surfaces to answer "who has access here?". Merging gives them one canonical "people" page.
|
||||
> - **Approach:**
|
||||
> - **(a) Page shape:** keep route at `/admin/users`. Add a state filter at the top: `All | Active | Invited (pending) | Disabled | Archived`. Default to `Active`. The existing Users table extends to render invitation rows alongside active users, distinguished by a "Pending" badge + last-sent timestamp + "Resend" / "Revoke" kebab actions. Active-user kebab keeps current actions (edit role, reset password, disable). One unified `+ Invite user` button in the page header opens the existing invitation form. Search across both populations (name / email / role).
|
||||
|
||||
Reference in New Issue
Block a user