docs(audit-followups): record 11 decisions from 2026-05-09 review

Replace the open-questions section with a Decisions log capturing the
chosen direction for vocabularies admin, notification prefs, name
fields, public-feed parity, website cutover, status-change prospect
link, trip-label UX, documents folders, and the berth Documents tab
split. Quick-status snapshot updated to reflect that Waves 4-10 are
now ready to start.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 18:34:59 +02:00
parent ee2da8f67e
commit 7804e9bb17

View File

@@ -13,22 +13,22 @@ message order where possible.
--- ---
## Quick status snapshot — 2026-05-08 23:00 ## Quick status snapshot — 2026-05-09 (decisions locked)
| Wave | Topic | Status | | Wave | Topic | Status |
| --------- | ------------------------------------------ | -------------------------------------------------------------------------- | | --------- | ------------------------------------------ | -------------------------------------------------------------------------- |
| 1 | Small confident fixes | ✅ Done | | 1 | Small confident fixes | ✅ Done |
| 2 | Country dropdown unification + cmdk scroll | ✅ Done (country/nationality split deferred) | | 2 | Country dropdown unification + cmdk scroll | ✅ Done (country/nationality split deferred) |
| 3 | Berth field overhaul (NocoDB enums) | ✅ Done | | 3 | Berth field overhaul (NocoDB enums) | ✅ Done |
| 4 | Currency platform-wide | 🔴 Not started | | 4 | Currency platform-wide | 🟡 Ready — design locked; start with `<CurrencyInput>` |
| 5 | Configurable enums (admin Vocabularies) | 🔴 Not started | | 5 | Configurable enums (admin Vocabularies) | 🟡 Ready — `/admin/vocabularies`, admin-only |
| 6 | Notes unification (aggregate-on-read) | 🔴 Not started | | 6 | Notes unification (aggregate-on-read) | 🟡 Ready — extend pattern to yachts/companies/residential |
| 7 | Clients / yachts / companies misc | 🟡 Partial (small bits done; large items deferred) | | 7 | Clients / yachts / companies misc | 🟡 Partial (status-link flow ready; client form expansion still large) |
| 8 | Expenses revisit | 🔴 Not started | | 8 | Expenses revisit | 🟡 Ready — combobox trip label (free text → autocomplete) |
| 9 | Interests + notifications | ✅ Done | | 9 | Interests + notifications | ✅ Done |
| 10 | Settings polish | ✅ Done (small bits) — schema-blocked items deferred | | 10 | Settings polish | 🟡 Ready — first/last name + collapse notif prefs |
| 11 | DEFERRED — group-discussion items | 🟣 Awaiting alignment | | 11 | DEFERRED — group-discussion items | 🟡 Most items now decided; client-form expansion + reports still large |
| **Bonus** | **Public berth feed (website map)** | ✅ Map data backfilled (117 rows). Field-parity gaps remain — see § Bonus. | | **Bonus** | **Public berth feed (website map)** | 🟡 Add parity fields (no Price); double-write cutover plan |
Test status: `pnpm exec vitest run`**1185/1185 pass**. Test status: `pnpm exec vitest run`**1185/1185 pass**.
TS check: `pnpm exec tsc --noEmit`**clean**. TS check: `pnpm exec tsc --noEmit`**clean**.
@@ -496,66 +496,64 @@ overrides remains.
--- ---
## ❓ Open questions for the user ## ✅ Decisions log — 2026-05-09
These are the questions to address in the next session before further All 11 open questions answered. Implementation implications inline.
implementation. They're ordered by what unblocks the most work.
1. **Vocabularies admin layout (Wave 5)** — single new 1. **Vocabularies admin layout (Wave 5)** → **New `/admin/vocabularies`
`/admin/vocabularies` page or nested under existing admin tabs? page, grouped by domain, admin-only.** User considered exposing to
**Recommendation: one new page, grouped by domain.** Easier to non-admins (since reps use them daily) but settled on admin-only as
discover, cleaner schema for the editor. the safer default for now. Implementation: new top-level admin
2. **Notification preferences placement (Wave 10)** — keep both the route + page, reuse `system_settings` `(key, port_id)` composite
user-settings notifications panel _and_ `/notifications/preferences`, PK. Each vocabulary key gets its own card section (interest temps,
or collapse to one? **Recommendation: collapse to user-settings status-change reasons, tenure types, expense categories, document
only**, since that's where every other personal preference lives. types, etc.).
Keep the dedicated route as a redirect for back-compat links. 2. **Notification preferences placement (Wave 10)** → **Collapse to
3. **Display vs first / last name (Wave 10)** — worth the migration, user-settings only.** Keep `/notifications/preferences` as a
or keep single-field display name? **Recommendation: keep single server-side redirect to the user-settings notifications panel for
display name unless you'll be using first/last for invoicing, back-compat links.
greetings, or DocSign field-merging.** A migration is reversible 3. **Display name vs first/last (Wave 10)** → **Add `first_name` and
but never free. `last_name` columns.** Don't worry about migrations during dev (we
4. **Public-feed `Price` exposure (Bonus)** — should `Price` be in the can iterate freely), but write the migration carefully so it
public website feed? NocoDB exposed it. **Recommendation: yes if applies cleanly when we eventually deploy. Keep `display_name` as
it's already shown publicly today; no if the website redacts it.** a derived/optional override.
Easiest tell: open the public `/berths` page on the marketing site 4. **Public-feed `Price` exposure (Bonus)** → **No — keep Price
and look for the price. internal.** Don't add to PublicBerth payload.
5. **Public-feed remaining fields (Bonus)** — add `Berth Approved`, 5. **Public-feed remaining fields (Bonus)** → **Yes, add all.** Add
`Water Depth`, `Width Is Minimum`, `Water Depth Is Minimum`, and Berth Approved, Water Depth, Width Is Minimum, Water Depth Is
metric variants to the PublicBerth payload? **Recommendation: yes Minimum, all four metric variants, plus CreatedAt/UpdatedAt to
to all** for verbatim NocoDB parity. Trivial code change once PublicBerth + mapper + tests. User noted "not sure if we'll use
confirmed. all of them but best to keep them in" — verbatim NocoDB parity.
6. **Website cutover plan (Bonus)** — is the website already pointed 6. **Website cutover plan (Bonus)** → **Double-write transition
at CRM `/api/public/berths`, or still hitting NocoDB? Need a window.** Keep both feeds live, write to both for the transition
coordinated DNS-style cutover (env var `CRM_PUBLIC_URL` per period, then decommission NocoDB. Coordinate with website repo
`CLAUDE.md`). After cutover, do we (a) decommission the NocoDB (`CRM_PUBLIC_URL`).
Berths table, (b) keep it read-only as a cold backup, or (c) 7. **Status-change modal → prospect link (Wave 7)** → **Force
double-write for a transition window? **Recommendation: (b) for interest pick + auto-create primary `interest_berths` row.**
30 days, then (a).** When status moves to `under_offer` or `sold`, the modal surfaces
7. **Status change reason → prospect link flow (Wave 7)** — confirm an interest selector below the reason dropdown. Picking an
the desired shape. Does picking "Sold to existing prospect" force interest creates an `interest_berths` row with `is_primary=true`
the user to pick an interest from the list, and does it auto- if one doesn't already exist for that pair. Depends on Wave 5
create an `interest_berths.is_primary=true` row if the chosen `berth_status_change_reasons` vocabulary.
interest isn't already linked to that berth? 8. **Trip label on expenses (Wave 8)** → **Combobox: free-text on
8. **Trip label on expenses (Wave 8)** — define-events flow vs free first entry, dropdown of existing labels on subsequent entries.**
text with matched-receipts-on-PDF heuristic? Either is fine; pick No new entity. Source the dropdown from
based on how reps actually batch trips. `SELECT DISTINCT trip_label FROM expenses WHERE port_id=?`
9. **Documents folders (Wave 11.B)** — nest depth limit? Per-port ordered by recency. UI is a `<Combobox>` with "Create
folders, or global per company? **Recommendation: per-port, '<typed value>'" affordance.
nested up to 3 levels** (matches typical document-management 9. **Documents folders (Wave 11.B)** → **Per-port, unlimited
depth and keeps the tree UI sane). nesting depth — but render carefully.** User wants flexibility;
10. **Berth Documents tab function (Wave 1 carryover)** — confirm we owe a UI design that handles deep trees gracefully (likely
the explainer paragraph is the right framing, or do you want a collapsed-by-default with a breadcrumb header inside the folder
"Linked deal documents" section that aggregates EOIs / contracts view rather than always-expanded sidebar tree).
/ etc. from interests on this berth? **Recommendation: keep 10. **Berth Documents tab (Wave 1 carryover)** → **Split into two
current scope** (versioned spec PDF only). Aggregating deal docs tabs: "Spec" (versioned spec PDF) and "Deal Documents"
is a bigger feature with permission concerns. (aggregated EOIs/contracts from interests on this berth).**
11. **Mooring type re-import** — added `BERTH_MOORING_TYPES` to the Permission scoping: deal docs only show entries the viewer can
UI. The seed JSON snapshot may not have included Mooring Type for already see via the linked interest.
every berth (NocoDB does). Confirmation that the live import we 11. **Mooring type re-import** → ✅ **Verified.** All 117 records
ran today populated mooring_type for all 117 records. (Spot- have `mooring_type` populated post-import (e.g. "Side Pier / Med
checked: yes — the SQL traces show `mooring_type = "Side Pier / Mooring"). No action needed.
Med Mooring"` etc.)
--- ---