fix(uat): batch — timeline overshoot, name-sync, reset-password, dashboard cleanup, queue/seed hygiene + alpha UAT findings doc

UAT findings landed across the last few Playwright + React Grab passes;
single grouped commit so the index doesn't fragment into 30 one-liners.

User & auth:
- `user-settings`: name now updates the avatar + topbar menu after save
  (was reading stale session).
- `me/password-reset`: 3 bugs (token validation, error response shape,
  redirect chain).
- Admin user permission-overrides route honours the same envelope as
  the rest of the admin surface.

Dashboard:
- Removed obsolete `revenue-breakdown-chart` + `dashboard-widgets-card`
  (replaced by the customisable widget grid).
- Strip `revenue_breakdown` from analytics route + use-analytics +
  service + integration test so nothing renders an empty card.
- Activity log timeline overshoot fix (`interest-timeline` +
  `entity-activity-feed`).
- Tightened tiles: active-deals, berth-heat-widget, pipeline-value, kpi-tile.
- `dev-mode-banner`: derive dismissed state synchronously instead of
  via an effect (set-state-in-effect lint rule).

Forms & lists (assorted polish):
- client / company / yacht / interest / reminder forms — validation +
  empty-state copy + tab transitions.
- companies/yachts list tweaks; berth recommender panel; qualification
  checklist; supplemental info request button.

Infra & misc:
- Queue workers (ai / email / notifications) — log shape +
  per-job timeout consistency.
- Auth / brochures / users schema small adjustments; seeds reflect
  permissions matrix changes.
- Scan shell + scanner manifest + AI admin page small fixes.
- `next.config.transpilePackages` adds `echarts`/`zrender`/`echarts-for-react`
  (recommended config from echarts-for-react inside Next).

Docs:
- `docs/superpowers/audits/alpha-uat-master.md` — single rolling
  cross-cutting UAT findings doc (per CLAUDE.md convention).
- `docs/BACKLOG.md`: dashboard stats cards (§I) + activity-log
  normalization (§J).
- 2026-05-18 audit log updated with this batch.
- `CLAUDE.md` — small manual UAT scaffold notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 15:56:11 +02:00
parent 8c669e2918
commit 449b9497ab
59 changed files with 1831 additions and 631 deletions

View File

@@ -48,10 +48,6 @@ const PipelineFunnelChart = dynamic(
() => import('./pipeline-funnel-chart').then((m) => ({ default: m.PipelineFunnelChart })),
{ loading: ChartFallback, ssr: false },
);
const RevenueBreakdownChart = dynamic(
() => import('./revenue-breakdown-chart').then((m) => ({ default: m.RevenueBreakdownChart })),
{ loading: ChartFallback, ssr: false },
);
const SourceConversionChart = dynamic(
() => import('./source-conversion-chart').then((m) => ({ default: m.SourceConversionChart })),
{ loading: ChartFallback, ssr: false },
@@ -123,12 +119,13 @@ export const DASHBOARD_WIDGETS: readonly DashboardWidget[] = [
{
id: 'kpi_pipeline_value',
label: 'Pipeline Value',
description: 'Total berth value of active deals, converted to the port default currency.',
description:
'Gross + weighted forecast, broken down by pipeline stage so leadership can see what is near-close vs speculative.',
render: () => <PipelineValueTile />,
group: 'rail',
// Flipped on by default 2026-05-14 — the dashboard wave prioritized
// investor-facing tiles, and this is the headline number leadership
// looks at first.
// Lives in the chart grid (not the narrow rail) so the per-stage
// breakdown rows have room to breathe alongside the headline numbers,
// and the rail stays reserved for reminders / alerts / glance tiles.
group: 'chart',
defaultVisible: true,
},
@@ -149,14 +146,6 @@ export const DASHBOARD_WIDGETS: readonly DashboardWidget[] = [
group: 'chart',
defaultVisible: true,
},
{
id: 'revenue_breakdown',
label: 'Revenue Breakdown',
description: 'Invoice totals grouped by status and currency.',
render: (range) => <RevenueBreakdownChart range={range} />,
group: 'chart',
defaultVisible: true,
},
{
id: 'lead_source',
label: 'Lead Source Attribution',
@@ -186,8 +175,9 @@ export const DASHBOARD_WIDGETS: readonly DashboardWidget[] = [
},
{
id: 'berth_heat',
label: 'Berth Heat',
description: 'Top 15 berths by active interest count. Investor-friendly demand pressure view.',
label: 'Berth Demand',
description:
'Ranks berths by active interest. Surfaces the leading mooring with its runners-up.',
render: () => <BerthHeatWidget />,
group: 'chart',
defaultVisible: true,
@@ -196,7 +186,7 @@ export const DASHBOARD_WIDGETS: readonly DashboardWidget[] = [
id: 'website_analytics',
label: 'Website Analytics',
description: 'Quick glance at marketing site traffic. Requires Umami.',
render: () => <WebsiteGlanceTile />,
render: (range) => <WebsiteGlanceTile range={range} />,
group: 'rail',
defaultVisible: true,
selfGates: true,