Skip to content

Add personal finance dashboard and loan portfolio analyzer#356

Open
Philip-omatsone wants to merge 28 commits intoanthropics:mainfrom
Philip-omatsone:claude/improve-test-coverage-umwuB
Open

Add personal finance dashboard and loan portfolio analyzer#356
Philip-omatsone wants to merge 28 commits intoanthropics:mainfrom
Philip-omatsone:claude/improve-test-coverage-umwuB

Conversation

@Philip-omatsone
Copy link
Copy Markdown

Description

This PR adds two new financial analysis tools:

  1. Personal Finance Dashboard - A comprehensive single-page application for tracking income and expenses with:

    • Real-time summary statistics (total income, expenses, and balance)
    • Interactive charts for visualizing spending patterns by category
    • Transaction management with add/edit/delete functionality
    • Category-based expense tracking
    • Responsive dark-themed UI with modern design
    • Local storage persistence for data
  2. Loan Portfolio Analyzer - A tool for analyzing and managing loan portfolios with features for loan tracking and financial analysis

Both applications are built as standalone HTML files with embedded CSS and JavaScript, using Chart.js for data visualization.

Quickstart

  • Financial Data Analyst

Type of Change

  • New feature

Testing

  • Tested manually
  • Verified in development environment

The applications are fully functional standalone HTML files that can be opened directly in a browser. Core features tested include:

  • Transaction creation and deletion
  • Chart rendering and updates
  • Data persistence via localStorage
  • Form validation and input handling
  • Responsive layout across different screen sizes

Additional Notes

Both applications use a consistent dark theme design system with CSS custom properties for easy customization. The Personal Finance Dashboard includes comprehensive transaction management capabilities with real-time balance calculations and category-based expense analysis.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY

Single-page app with income/expense input, running balance,
monthly spending chart (Chart.js), and transaction history.
Data persists in localStorage.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Single-page HTML app for analysing loan portfolios with:
- CSV/Excel file upload (Papa Parse + SheetJS)
- Dashboard: portfolio size, WAIR, WAM, default rate, top exposures
- Concentration analysis: sector/region pie charts, credit rating
  distribution, top 10 borrowers, maturity profile histogram
- Risk metrics: HHI, largest single exposure %, WAL, expected loss
- Built-in sample dataset generator (200 loans)
- Export to CSV

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Upload flow now shows a mapping modal where users can map any column
names to the standard template fields. Includes fuzzy auto-matching
against 100+ common aliases (e.g. obligor, counterparty, exposure,
coupon, etc.) with sample data preview. Required fields are enforced
before analysis can proceed.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Visual overhaul:
- Muted monochrome dark palette (slate grays, desaturated steel blues)
- Monospaced typography throughout (SF Mono/Consolas)
- Sharp 3px corners, tighter spacing, uppercase labels
- All chart colours replaced with institutional-grade muted tones
- Removed bright greens/reds/ambers in favour of desaturated equivalents

Domain-specific improvements for structured credit / CLO warehouse:
- Rebrand to "Tape Analyser — Enable Funding"
- Terminology: obligor, par, commitment, industry, coupon, facility
- Added WARF (Weighted Average Rating Factor) with full Moody's mapping
- Added Diversity Score (simplified Moody's industry-obligor method)
- Added IG/HY split bar with par amounts
- Overview: obligor count replaces avg loan size
- Formatting: $bn/$mm conventions

Sample data now reflects leveraged loan warehouse:
- BB/B-weighted rating distribution typical of BSL CLO
- Real obligor names from leveraged loan market
- Facility types: TLB, TLA, Revolver, Second Lien, DDTL, Unitranche
- SOFR + spread pricing model
- Realistic utilisation (revolvers drawn 10-50%, term loans 85-100%)

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Removed:
- Entire Risk & Credit tab (HHI, WARF, Diversity Score, Expected
  Loss, IG/HY split, WAL, assumptions panel)
- All CLO/structured credit terminology and Moody's rating mappings
- In-memory sample data loader (Load Sample Data button)

Added:
- Download Sample Tape button — generates a 150-row .xlsx in-browser
  using the XLSX library with deliberately non-standard column names
  (Facility_Ref, Counterparty, Geography, Facility_Limit, Current_Drawn,
  Final_Maturity, All_In_Rate, Risk_Grade, Product_Type, NPL_Flag) to
  exercise the column mapping flow
- UK date parser (DD/MM/YYYY default, handles Excel serial numbers)
- GBP formatting throughout (£mm, £bn)

UK-focused:
- Regions: London, South East, Midlands, North West, Scotland, etc.
- Sectors: UK mid-market (Manufacturing, Construction & Property, etc.)
- Borrower names: UK Ltd/Plc companies
- Internal risk grades (A through D) instead of S&P/Moody's
- Facility types: Term Loan, Revolving Credit, Capex, Working Capital,
  Asset-Based Lending
- Realistic UK direct lending pricing (3.5%-12% all-in)

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
- Switch from dark terminal theme to clean light UI with BBB navy/teal palette
- Replace full monospace with system sans-serif (mono for numbers only)
- Add persistent "New Tape" button in nav to return to upload screen
- Make sample tape download prominent with dedicated section on home page
- Ensure all formatting uses GBP (£) consistently throughout
- Dynamic nav buttons based on current view (home vs dashboard)
- Strip excessive colours to focus on content readability

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…etection

- Expand template from 11 to 24 fields with UK lease/securitisation columns
- Add 200+ aliases for auto-matching common lease tape column names
- Add Stratification tab with 16 prospectus-style breakdown tables
- Add Anomalies tab with 14 automated data quality checks (error/warning/info)
- Expand sample tape to 200 rows with 24 columns and deliberate anomalies
- Smart WA Remaining Term uses field data when available

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Both CSV and Excel parsers previously assumed the first row was always
the header row. Files with title rows, metadata, or blank rows above
the actual headers would only detect one column. Now scans the first
20 rows and picks the one with the most populated cells as the header.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
The file input is a child of the upload area div. When the upload
area's click handler calls fileInput.click(), the synthetic click
bubbles back up to the upload area, creating an infinite recursion
that prevents the file dialog from opening.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
The file input was a child of the upload-area div, so calling
fileInput.click() from the div's click handler caused the click
to bubble back up, creating an infinite loop. Moving the input
outside the div eliminates the propagation issue entirely.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Errors in the CSV/Excel parsing callbacks were silently swallowed,
making it appear as if clicking upload did nothing. Added try-catch
with alert messages, defensive Array.isArray checks, and a shared
processRawRows helper that reports empty files and missing data rows.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…ests

New features:
- Postcode field with UK postcode-to-region derivation (auto-populates
  region when only postcode is mapped)
- BBB Guarantee Programme field (GGS, RLS, None) with aliases, strat
  table, and sample data
- Settings modal with editable predefined options for all categorical
  fields (facility type, customer segment, payment frequency, etc.)
- Users can add entirely new field categories with custom options
- Facility type now has predefined options: Loan, Hire Purchase,
  Finance Lease, Operating Lease, Refinance
- Custom test builder in the Anomalies tab: define field + operator +
  value + severity tests that run alongside built-in checks
- Data table and CSV export include new fields
- Sample tape generator includes postcodes and BBB guarantee data

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…ee aggregation

New fields & capabilities:
- Equipment Type, Asset Category, Supplier/Vendor, Deposit Amount,
  Deposit %, VAT Deferral, Loan Status (Live/Repaid/Defaulted/etc.),
  Arrears Status, SIC Code, NACE Code
- SIC code division mapping (UK SIC 2007) auto-derives sector from
  2-digit division codes when sector column is not mapped
- NACE Rev.2 section mapping for EU classification codes
- Facility Type label updated from "Type of Lease" to "Facility Type"

Top exposures fix:
- Now aggregates ALL loans per lessee (sum of outstanding balances)
  instead of just picking the single largest loan
- Shows loan count per lessee, combined sectors, all ratings
- Arrears column shows X/Y format (loans in arrears / total loans)
  with max arrears days, handling mixed arrears/current portfolios

Settings enhancements:
- Term unit toggle (months/years/days) in settings — dynamically
  converts all term displays across the dashboard
- Double-click inline editing of category options (no more prompts)
- Delete entire field categories
- Option count shown per field

CSV export:
- Row 1: internal field labels, Row 2: original tape column names
  so exported files show both the analyser field name and the source
  column name from the uploaded tape

Sample tape updated with all new fields (SIC codes, equipment types,
asset categories, suppliers, deposits, VAT deferral, loan status).

Stratification tables added for all new categorical fields.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…X export

- Replace static overview tab with dynamic, configurable widgets (portfolio
  health score, arrears snapshot, top exposures, facility mix chart, maturity
  profile). Users can toggle widgets on/off in Settings.
- Add multi-tape support: upload multiple tapes with series labels, toggle
  between individual series or aggregated "All" portfolio view via series
  pills bar.
- Add XLSX export that writes all tabs (Tape Data, Stratification, Anomalies,
  Summary) as separate sheets in a single workbook.
- Add tape management in Settings (rename series, remove tapes).
- Replace "New Tape" nav with "Add Tape" (additive) and "Reset" (clear all).

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Users can now map any source column to either a predefined field from the
dropdown OR create a custom field by selecting "+ Custom Field...". Custom
fields show an inline configuration panel directly in the mapping modal:

- Label: display name for the field
- Type: Categorical (strat by distinct values), Numeric (strat by user-
  defined bands), Text (data only, no strat), or Date (strat by year)
- For categorical: shows detected options, add/remove options, auto-detect
  from data
- For numeric: define custom bands (label + min/max), auto-detect bands
  from data range

Custom fields are fully integrated:
- Appear in stratification tables (categorical + banded numeric + date)
- Show in the dynamic data table (columns auto-adjust to show populated fields)
- Included in CSV and XLSX exports with proper labels
- Persist across multiple tape uploads in the same session
- Registered in fieldOptions for settings editor

Also made the data table fully dynamic — columns are now determined by which
fields have data rather than being hardcoded.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…mapping

- Add Broker and Originator as default template fields with aliases and
  stratification tables
- Add cut-off date input to the mapping modal, stored per tape and
  displayed as a banner on the dashboard overview tab
- Show "(in use)" labels on mapping dropdown options already claimed by
  another source column
- Include broker/originator in sample tape generator

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…lculations, trends, re-categorisation, and export improvements

- Fix mapping dropdown to re-render on every selection so "(in use)"
  labels update dynamically; current selection never shows as in-use
- Fix arrears bug: derive days_in_arrears from arrears_status text when
  the numeric field is not mapped (e.g. "31-60 days" → 45)
- Prompt for originator per tape on upload; display in series bar,
  cutoff banner, settings, and both CSV/XLSX exports
- Add WA Rate and WA Term columns to all stratification tables
  (weighted by outstanding balance)
- Add per-series strat toggle buttons to show/hide individual tables
- Add Historic Trends widget: comparison table + line charts for
  outstanding balance and WA rate across tapes sorted by cut-off date
- Add field re-categorisation: "Edit Fields" button in settings lets
  users rename categorical values on existing tapes post-upload
- Improve CSV export: summary header with originator, cut-off, key
  metrics before data rows
- Improve XLSX export: broker/originator strat tables, WA Rate column
  in strats, originator + cut-off in summary, tape comparison sheet

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…d sector chart

- Remove catch-all arrears derivation that set days_in_arrears=1 for unrecognised
  statuses; only match explicit arrears band patterns (1-30, 31-60, 61-90, 90+)
- Add excludeBlanks option to groupBy and apply to all chart calls so blank values
  don't dominate the All view when combining tapes with different fields
- Add REGION_ALIASES map and normaliseRegion() to standardise region names across
  tapes (e.g. "southeast"/"south-east" → "South East", merge East/West Midlands)
- Wire normaliseRegion into applyMapping for both explicit and postcode-derived regions
- Add capChartData() to limit pie/doughnut slices and group remainder into "Other"
- Replace sector doughnut chart with horizontal bar chart (handles high-cardinality
  fields better without exploding into unreadable slices)
- Sort (blank) entries to bottom in stratification tables

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
… X obligors

- Replace portfolio health score with Key Risk Metrics widget showing
  arrears %, default rate, top 5 concentration, and largest obligor %
- Add series comparison table for side-by-side metric comparison across
  tapes (outstanding, WA rate, arrears, defaults, concentration etc.)
- Add French amortisation profile chart projecting balance rundown using
  WA rate, remaining term, and current balance
- Add origination & maturity profile charts showing vintage by year
- Add key WA summary bar at top of stratification page (WA rate, WA
  original term, WA remaining term, WA seasoning, current factor, avg bal)
- Replace rating distribution chart with loan size distribution (more
  useful for granular SME portfolio analysis)
- Make top obligor count adjustable (5/10/15/20/25) across overview
  widget and concentration chart
- Remove payment frequency from default field options

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
- Rename 'Portfolio Size' to 'Original Amount' and 'Outstanding' to
  'Current Outstanding' with 'drawn' sub-label instead of '% of original'
- Add smart interest rate detection: auto-detect if rates are coded as
  decimals (0.05 = 5%) vs percentages (5 = 5%) by scanning sample data;
  also applies to deposit_pct and balloon_pct
- Add 'Interest Rate Format' setting (auto/percentage/decimal) with
  ability to re-apply mapping when changed
- Store raw data and reverse maps on tape objects to enable re-mapping
  when rate format is changed
- Fix WA strat header to only show metrics where data exists (skip WA
  Term/Seasoning when terms are 0)
- Fix WA Term in strat cards to use convertTerm() respecting display unit
- Raise high-rate anomaly threshold from >25% to >50% (valid for SME/
  specialist lending products)
- Update CSV/XLSX export labels to match (Original Amount, Current Factor)

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…icator

- Replace 'Current Factor' in strat header with Borrowers count
- Add value mapping/harmonisation system: when adding a second tape,
  automatically detect field values that don't match existing tapes
  (e.g. 'HP' vs 'Hire Purchase') and present a mapping UI with fuzzy
  match suggestions (abbreviation, case-insensitive, containment)
- Add dedicated Comparison tab (before Tape Data) with: key metrics
  side-by-side table, field value mismatch flags (Yes/No per series),
  and per-field strat comparison (% of outstanding by series)
- Comparison tab auto-shows when 2+ tapes loaded
- Add multi-file upload: file input accepts multiple files, processes
  them sequentially through the mapping modal one at a time
- Add loading overlay with spinner shown immediately when a file is
  selected/dropped, before CSV/XLSX parsing begins
- Fix _rawData bug where pendingRawData was nulled before being stored
  on the tape object (broke rate format re-mapping)
- Queue remaining files and auto-process after each mapping confirmation

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
- Add 'Advance' / 'Total Advance' aliases for loan_amount (original)
- Add 'Current Principal Outstanding' aliases for outstanding_balance
- Add 'Lessee Type' template field with aliases (entity_type, legal_form,
  company_type, borrower_type, etc.) and defaults (Limited Company, Sole
  Trader, Partnership, LLP, PLC, Charity, Individual)
- Fix fuzzy column matching to require >=50% coverage ratio between
  alias and column name, preventing false positives like 'Current
  Internal Risk Category' matching 'Currency'. Uses scoring system
  preferring longer alias matches with higher coverage
- Improve header row detection: score candidate rows by string ratio,
  uniqueness ratio, and presence of data rows below. Handles Excel
  files with title rows, filter rows, and merged decorative headers
- Rename Concentration tab to 'Key Concentrations'
- Move region chart to bottom row of concentrations (less prominent)
- Promote Top Lessee Exposures to top row alongside sector
- Replace customer_segment with lessee_type in stratification defaults
- Trim customer_segment aliases to avoid overlap with lessee_type

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
- Fix value mapping dropdown: use __keep__ sentinel so users can revert
  to original values after selecting a mapping
- Add bidirectional harmonisation: allow mapping values in both the new
  tape and existing tapes, not just new-to-existing
- Redesign comparison tab from mismatch-focused to key characteristics:
  balance size distribution, top sector breakdown, arrears profile,
  facility type mix, maturity profile, and interest rate distribution,
  each with side-by-side grouped/stacked charts
- Add delta column for 2-series comparisons
- Fix top lessee exposures: fixed top 10 table with cumulative Top 5/10/20
  concentration badges and Cum% column, no page refresh
- Add loan count alongside balance in facility mix widget
- Remove amortisation profile and historic trends from default widgets
- Improve stat cards: add Current Factor, WA Seasoning, clearer labels
- Comparison tab now updates after harmonisation via renderDashboard()

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
- Remove Key Concentrations tab; move sector, top exposures, loan size,
  original term, and region charts to the Overview tab
- Rename 'Maturity Profile' to 'Original Term' throughout
- Add '&' / 'and' normalisation in value matching (e.g. 'Sale &
  Leaseback' matches 'Sale and Leaseback')
- Default existing tape harmonisation to 'keep unchanged' instead of
  auto-selecting a match
- Fix originator display for 2+ originators: show comma-separated list
  of unique names instead of per-series breakdown
- Add facility type chart (horizontal grouped bar) to comparison tab
- Include current outstanding balance alongside % and count in
  comparison facility type table
- Add column mapping memory: remembers previous source column -> field
  mappings and auto-applies on subsequent tapes
- Add 'Back' button on harmonisation overlay to return to column
  mapping and adjust previous decisions
- Make harmonisation categories collapsible, minimised by default with
  expand/collapse toggle per field
- Improve CSV export: structured sections (summary, stratification,
  top 10 exposures, tape data), formatted numbers, BOM for Excel
  compatibility, series-specific filenames
- Improve XLSX summary sheet with additional metrics (WA Seasoning,
  Current Factor, WA Original Term)

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Field changes:
- Add: ONS Code, Average Life, Payment Method, Legal Form / Business
  Type (replaces Lessee Type), CCA Regulated, Prefunded Receivable,
  Refinancing Receivable, Other Schemes (replaces BBB Guarantee)
- Remove: Arrears Status, Postcode, VAT Deferral, NACE Code, Deposit
  Amount, Deposit %, Sector / SIC (renamed to Sector), Credit Rating,
  Asset Type from template fields and aliases

Stratification reorder:
- Remove asset type, arrears status, credit rating from strats
- Move Interest Rate Type, Amortisation Type, Payment Frequency,
  Origination Channel, Supplier/Vendor to bottom of strat list
- Add new fields (Legal Form, CCA, Prefunded, etc.) to strats

Top Lessee Exposures:
- Show which originator/tape each lessee belongs to when multiple
  tapes loaded (Originator column with fallback to tape series name)

Harmonised tape export:
- New "Export Tape" nav button exports harmonised loan data
- Choose individual tape or all tapes in one XLSX file
- Each tape gets its own sheet with only populated columns

CSV export updated to match new field taxonomy

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…fix chart axes

- Fix facility type chart y-axis to show category names instead of numbers
  (override scales for horizontal bar chart in overview)
- Enable smooth back-and-forth between calibration and harmonisation
  (save tape metadata, skip prompts on return, preserve column mappings)
- Add custom name option in harmonisation dropdowns (prompt for custom value)
- Add intra-tape harmonisation to merge duplicate values within same tape
  (new showTapeHarmonisation function with per-value count display)
- Add cross-tape harmonisation for already-loaded tapes via settings
  (Harmonise and Cross-Harmonise buttons per tape)
- Fix strats/comparison data flow: defer dashboard render until
  harmonisation is applied or skipped, ensure closeValueMapping
  triggers re-render
- Improve abbreviation matching in findBestValueMatch
  (HP -> Hire Purchase, FL -> Finance Lease)

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
…ape duplicate detection

- Trim all string values in applyMapping() to prevent invisible duplicate rows in strats
- Add NUTS region code mapping (UKI31 → London, etc.) with fallback from ons_code field
- Normalise string fields and regions in refreshLoansFromTapes() for already-loaded tapes
- Trim strat grouping keys as safety net for consistent aggregation
- Detect near-duplicate values in intra-tape harmonisation using normalizeValueStr()
- Auto-expand sections with detected duplicates, highlight with amber badges
- Pre-select suggested merge targets and auto-register them in pendingValueMaps

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
Users can now download their entire analysis session as a JSON file
via "Save Session" in the nav bar, and restore it later using
"Load Previous Session" on the home page. The session file captures
all tapes, loans, mappings, custom fields, custom tests, display
settings, and field options — allowing users to pick up exactly
where they left off.

https://claude.ai/code/session_01RRStEYByK45ndzBvXz4CzY
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