Skip to content

fix(dashboard): skip null-value portfolio points instead of plotting 0#694

Merged
TaprootFreak merged 1 commit into
stagingfrom
feature/portfolio-chart-skip-null-values
Jun 5, 2026
Merged

fix(dashboard): skip null-value portfolio points instead of plotting 0#694
TaprootFreak merged 1 commit into
stagingfrom
feature/portfolio-chart-skip-null-values

Conversation

@TaprootFreak
Copy link
Copy Markdown
Contributor

Problem

When the REALU quote is temporarily unavailable, the dashboard showed a corrupt portfolio chart: the line crashed to 0 at the most recent point and the performance box reported -921.27 CHF | -100.00%, even though the header correctly rendered the total as --.--.

Root cause: the API returns valueChf / valueEur as null for points it cannot price. RealUnitAccountService.getPortfolioHistory mapped that null to 0 (value ?? 0). The latest history point (balance still held, price null) was therefore plotted as a zero-value point, dragging the chart to the x-axis and making the last - first performance calc read -100%.

Fix

  • Skip history points whose value is null in the selected currency instead of mapping them to 0. The chart now ends at the last known value and the change is computed against it; the header keeps showing --.-- (already handled).
  • A genuine 0.0 value (balance held but worth zero) is preserved and stays distinct from null (unknown).

Single change at the API boundary — no chart/cubit/widget changes needed, since the false 0 originated in the service mapping.

Tests

  • Rewrote the obsolete treats a null value as 0 test → skips a point whose value is null (point is dropped).
  • Added keeps a genuine 0.0 value (distinct from null).
  • Added drops a trailing null point but keeps earlier valued points.
  • flutter analyze clean; dashboard + dfx service suites green (516 tests).

Test plan

  • Wallet with holdings while the quote endpoint returns null for the latest point → chart stays at last known value, header --.--, no -100%.
  • Normal case with all values present → unchanged.
  • Holding genuinely worth 0 → still renders 0, not dropped.

A historical balance point with a null value in the selected currency means
the API could not price it (e.g. quote currently unavailable), not that the
holding is worth 0. Mapping null to 0 made the chart line crash to zero and
the performance box show a false -921 CHF / -100% drop while the header
correctly rendered "--.--".

Skip points whose value is null so the chart ends at the last known value and
the change is computed against it. A genuine 0.0 value (balance held but worth
zero) is preserved and remains distinct from null.
@TaprootFreak TaprootFreak marked this pull request as ready for review June 4, 2026 21:44
TaprootFreak added a commit that referenced this pull request Jun 5, 2026
… price chart (#695)

## Problem

The public price view ("RealUnit Aktienkurs") shows an **empty chart**
and `CHF --.--` whenever the RealUnit quote is temporarily unavailable.

Confirmed against the live API:
- `GET /v1/realunit/price` → `{"timestamp":"2026-06-04T22:28:16.539Z"}`
— **no `chf`/`eur`**.
- `GET /v1/realunit/price/history?timeFrame=ALL` → **1514 points, 1513
valid**, only the latest (2026-06-04) has no `chf`/`eur`.

`DFXPriceService.getPriceChart` did `BigInt.from(entry['chf'] * 100)`
for every entry, so the single null point threw (`null * 100`), the
whole method threw, and `priceChart` stayed `[]` → the entire history
(1513 valid points) was discarded and the chart rendered empty.
`getPriceOfAsset` threw on the same null.

This is the same defect class as the portfolio-chart fix in #694, but in
the **price** code path (`dfx_price_service.dart`), which #694 does not
touch. It is more visible because it affects the wallet-less public
price view.

## Fix

- `getPriceChart`: skip entries whose selected-currency price is `null`
instead of throwing — the chart renders the full history minus the
unpriced tail point.
- `getPriceOfAsset`: return `BigInt.zero` when the price is missing, so
the UI renders `--.--` instead of throwing.
- `getChfToEurRate`: treat a missing `chf`/`eur` as `0` (already guards
`chf > 0`).

## Tests

- `getPriceChart` skips a trailing null point and keeps earlier valued
points.
- `getPriceOfAsset` returns zero on a missing price.
- `getChfToEurRate` returns `0.0` on a missing price.
- `flutter analyze` clean; price-service + price-chart-cubit suites
green (22 tests).

## Test plan

- [ ] Open the app with no wallet while the quote endpoint omits
`chf`/`eur` → price chart renders full history, header `--.--`, no empty
chart.
- [ ] Normal case (all prices present) → unchanged.
- [ ] Current price endpoint without `chf`/`eur` → header `--.--`, no
crash.

## Related

- Sibling fix for the portfolio chart: #694 (same null-handling defect,
account endpoint).
@TaprootFreak TaprootFreak merged commit d7fbfd2 into staging Jun 5, 2026
10 checks passed
@TaprootFreak TaprootFreak deleted the feature/portfolio-chart-skip-null-values branch June 5, 2026 07:25
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.

1 participant