Skip to content

feat(dashboard): add RealUnit KPI/funnel section to /realunit#1118

Open
TaprootFreak wants to merge 2 commits into
developfrom
feat/realunit-kpi-dashboard
Open

feat(dashboard): add RealUnit KPI/funnel section to /realunit#1118
TaprootFreak wants to merge 2 commits into
developfrom
feat/realunit-kpi-dashboard

Conversation

@TaprootFreak

Copy link
Copy Markdown
Collaborator

New Kennzahlen (Key Figures) section at the top of the RealUnit dashboard (/realunit).

What

  • Summary cards: new accounts (30d), completed registrations, KYC conversion rate (completed IDENT / reached CONTACT_DATA), buy+sell trading volume CHF (30d)
  • KYC funnel bar chart (ApexCharts, DFX blue palette) — new component KpiFunnelChart
  • New getStats() hook method + fetchStats() context callback, consuming GET /v1/realunit/admin/stats
  • RealunitStats* TypeScript interfaces mirroring the api DTO field names exactly
  • German i18n overrides for the new labels and funnel step names

Tests

  • Unit tests for getStats(), context fetchStats, the KpiFunnelChart component (100% coverage), and the screen section
  • Self-contained Playwright visual spec (e2e/realunit-kpi.spec.ts) with mocked stats endpoint + session JWT; generated -chromium-darwin baseline committed

Local checks green: lint, test (297 passing), build:dev.

Companion api PR in DFXswiss/api.

Add a new "Key Figures" section at the top of the RealUnit dashboard,
fed by GET /v1/realunit/admin/stats.

- dto: RealunitStats* interfaces mirroring the api DTO
- hook: getStats() via useApi().call()
- context: stats state + fetchStats() callback
- screen: Key Figures section (summary cards + KYC funnel chart) as the
  first section, triggered in the existing data-loading effect
- component: KpiFunnelChart (ApexCharts bar chart, DFX blue palette)
- i18n: German overrides for the new labels and funnel step names
- tests: unit tests for getStats, fetchStats, the chart and the section
  (100% coverage of the new chart component)
- e2e: self-contained Playwright visual spec with mocked stats endpoint
  and session JWT, plus generated chromium-darwin baseline

Companion api PR in DFXswiss/api.
@TaprootFreak TaprootFreak marked this pull request as ready for review June 4, 2026 15:14
@TaprootFreak TaprootFreak requested a review from davidleomay as a code owner June 4, 2026 15:14
davidleomay

This comment was marked as duplicate.

@davidleomay davidleomay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small findings, both non-blocking:


monochrome + fill.colors dead code

In src/components/realunit/kpi-funnel-chart.tsx (the chart options, ~line 50-54):

When monochrome.enabled is true, ApexCharts ignores fill.colors — it generates monochrome shades from theme.monochrome.color (#092f62). The fill.colors: ["#5A81BB"] line has no effect.

  • If the intent is #5A81BB bars: switch off monochrome and keep fill.colors, or change the monochrome color to #5A81BB.
  • If the intent is #092f62 bars: the fill.colors line is dead and can be removed.

kycConversionRate recomputed every render

In src/screens/realunit.screen.tsx (~line 64-70):

kycConversionRate() is defined as a plain function called directly in JSX, so it runs two .find() scans on every render of the section. A useMemo would be a bit cleaner and more consistent with how other derived values in the codebase are handled:

const kycConversionRate = useMemo(() => {
  if (!stats) return "-";
  const reachedContactData = stats.kycFunnel.find(e => e.step === "ContactData")?.reached.total ?? 0;
  const completedIdent = stats.kycFunnel.find(e => e.step === "Ident")?.completed.total ?? 0;
  if (!reachedContactData) return "-";
  return `${((completedIdent / reachedContactData) * 100).toFixed(1)}%`;
}, [stats]);

Low impact given the tiny array — fine to defer if you would rather keep it simple.


Everything else LGTM — clean separation of concerns, good test coverage, and the i18n is comprehensive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants