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