Skip to content

v3.1.0 — Responsive Workspace & Security Hardening

Choose a tag to compare

@programmishka programmishka released this 06 Sep 20:31
· 11 commits to main since this release

Version 3.1.0 significantly improves the Watchlist as a day-to-day financial workspace.

The release focuses on three areas: more efficient portfolio presentation, responsive interaction across screen sizes, and systematic hardening of all application input boundaries.

Data-First Watchlist Workspace

The Watchlist UI has been redesigned to give financial data priority over management controls.

The workspace now uses available screen space much more efficiently:

  • wider desktop layout with less unused space;
  • compact Watchlist, stock, filter, and allocation controls;
  • removal of redundant active-Watchlist headings;
  • Watchlist creation integrated directly into the navigation area;
  • compact Watchlist and stock removal actions;
  • Invested renamed to the more accurate Allocated savings;
  • Target Price inputs and other controls sized according to their actual content.

On sufficiently wide screens, the complete stock table fits without unnecessary horizontal scrolling.

Improved Table Presentation

The stock table received several financial presentation improvements:

  • default sorting by Company Name ascending whenever a Watchlist becomes active;
  • clearer Market Cap (USD bn) label;
  • Dividend Yield instead of the abbreviated Div;
  • Actions instead of Delete;
  • Currency positioned directly after Price;
  • financial values consistently displayed with two decimal places;
  • signed Target Price distances such as -15.20%, 0.00%, and +15.20%;
  • stocks below their Target Price receive a favorable green Distance presentation;
  • stocks above their Target Price receive an unfavorable red presentation;
  • clearer Total and Filtered stock counts.

Sorting continues to use the underlying numeric values rather than formatted display strings.

Responsive Watchlist Navigation

Horizontal scrolling through Watchlist tabs has been eliminated.

Navigation now uses direct tabs plus a responsive overflow menu:

  • the active Watchlist is always directly visible;
  • additional inactive Watchlists move into More / Watchlists;
  • selecting an overflowed Watchlist brings it into the directly visible navigation;
  • newly created Watchlists remain immediately visible even with many existing Watchlists;
  • mobile layouts show the active Watchlist prominently instead of a horizontally scrolling tab strip;
  • Watchlist creation remains directly accessible;
  • long and duplicate Watchlist names remain supported.

Responsive Stock Cards

The 10-column financial table is retained where it works best: on larger displays.

Below the empirically determined 1120 px breakpoint, the application now switches to responsive Stock Cards instead of requiring horizontal table scrolling.

Cards preserve the complete Watchlist functionality:

  • Symbol and Company Name;
  • Price and Currency;
  • editable Target Price;
  • favorable/unfavorable Distance to Target;
  • Market Cap;
  • Dividend Yield;
  • Savings Amount;
  • stock removal;
  • filtering;
  • sorting;
  • allocation results.

Card layouts adapt further from two columns to one column as space becomes constrained.

Table and Card views use the same underlying filtered and sorted stock state, so resizing the application does not reset state or trigger additional API requests.

Input Boundary Hardening

Version 3.1.0 introduces systematic bounds for externally controlled application data.

Server-side validation is authoritative; browser limits mirror the same rules for immediate UX feedback.

The application now enforces:

  • Watchlist names: maximum 50 characters;
  • Stock Symbols: maximum 20 characters plus the existing syntax rules;
  • Target Prices: finite values greater than 0 and no greater than 1,000,000;
  • Total Savings: safe integers from 0 through 10,000,000;
  • Watchlist IDs: maximum 64 characters;
  • company-name filters: maximum 100 characters;
  • Watchlists: maximum 1,000 stocks.

The 1,000-stock capacity is enforced before market-data resolution, avoiding unnecessary external requests when a Watchlist is already full.

Consistent Symbol Boundaries

Stock Symbol normalization is now consistently applied to Target Price operations as well.

For example:

aapl
→ AAPL

This closes an edge case where different casing could previously create separate Target Price persistence identities.

Malformed and oversized symbols are rejected before reaching the market-data provider.

Request Body Protection

All JSON API endpoints now enforce a 4 KiB application-level request-body limit before JSON parsing.

The protection:

  • rejects oversized requests with 413 PAYLOAD_TOO_LARGE;
  • uses Content-Length for immediate rejection when possible;
  • does not trust Content-Length as the sole protection;
  • incrementally counts actual request bytes;
  • also protects streamed/chunked requests without Content-Length;
  • stops processing oversized payloads before application services, persistence, or external providers are reached.

This complements the field-level validation rather than replacing it.

Quality and Verification

The release extends permanent unit and Playwright coverage across the new responsive layouts, navigation behavior, validation boundaries, resource limits, and API protections.

Responsive behavior was verified across mobile, tablet, and desktop widths, including the Table/Card breakpoint. Request-body protection was additionally verified against the real local Cloudflare workerd runtime, including an oversized chunked request without a Content-Length header.

No financial allocation formulas, authentication model, or persistence architecture were changed in this release.