Skip to content

Finance JavaScript Architecture

System Overview

┌─────────────────────────────────────────────────────────────────┐
│                         finance.md                               │
│              (loads all scripts as ES6 modules)                  │
└─────────────────────────────────────────────────────────────────┘
         ┌───────────────────────┼───────────────────────┐
         │                       │                       │
         ▼                       ▼                       ▼
┌──────────────────┐   ┌──────────────────┐   ┌──────────────────┐
│ us_finances_     │   │ tw_finances_     │   │ credit_card_     │
│ renderer.js      │   │ renderer.js      │   │ age.js           │
├──────────────────┤   ├──────────────────┤   ├──────────────────┤
│ Imports:         │   │ Imports:         │   │ Imports:         │
│ • isTaiwan...()  │   │ • isTaiwan...()  │   │ • isTaiwan...()  │
│ • isIconEntry()  │   │ • isIconEntry()  │   │ • formatDur...() │
│ • calculateAge() │   │ • calculateAge() │   │ • formatDate()   │
│ • loadIcons()    │   │ • loadIcons()    │   │ • fetchFinance() │
│ • fetchFinance() │   │ • fetchFinance() │   │                  │
│ • MS_PER_DAY     │   │ • fallbackIcons  │   │ 200 lines        │
│ • SUBSCRIPTION_  │   │                  │   │                  │
│   PREFIX         │   │ 239 lines        │   │                  │
│                  │   │                  │   │                  │
│ 706 lines        │   │                  │   │                  │
└──────────────────┘   └──────────────────┘   └──────────────────┘
         │                       │                       │
         ▼                       ▼                       ▼
┌──────────────────┐   ┌──────────────────┐   ┌──────────────────┐
│ finances_        │   │ card_gallery.js  │   │ card_benefits_   │
│ charts.js        │   │                  │   │ renderer.js      │
├──────────────────┤   ├──────────────────┤   ├──────────────────┤
│ Imports:         │   │ Imports:         │   │ Imports:         │
│ • debounce()     │   │ • extractLast4() │   │ • isTaiwan...()  │
│ • fetchFinance() │   │ • fetchFinance() │   │ • isIconEntry()  │
│                  │   │                  │   │                  │
│ 536 lines        │   │ 165 lines        │   │ 330 lines        │
└──────────────────┘   └──────────────────┘   └──────────────────┘
         │                       │                       │
         └───────────────────────┼───────────────────────┘
                    ┌────────────▼────────────┐
                    │   ┌──────────────────┐  │
                    │   │ finance_utils.js │  │
                    │   ├──────────────────┤  │
                    │   │ Shared Utilities │  │
                    │   │                  │  │
                    │   │ Classification   │  │
                    │   │ • isTaiwan...()  │  │
                    │   │ • isIconEntry()  │  │
                    │   │                  │  │
                    │   │ Icons            │  │
                    │   │ • fallbackIcons  │  │
                    │   │ • loadIcons()    │  │
                    │   │                  │  │
                    │   │ Date/Age         │  │
                    │   │ • calculateAge() │  │
                    │   │ • formatDur...() │  │
                    │   │ • formatDate()   │  │
                    │   │                  │  │
                    │   │ Data Fetching    │  │
                    │   │ • fetchFinance() │  │
                    │   │                  │  │
                    │   │ UI Components    │  │
                    │   │ • showFinance... │  │
                    │   │   Modal()        │  │
                    │   │                  │  │
                    │   │ Utilities        │  │
                    │   │ • debounce()     │  │
                    │   │ • extractLast4() │  │
                    │   │                  │  │
                    │   │ Constants        │  │
                    │   │ • MS_PER_DAY     │  │
                    │   │ • SUBSCRIPTION_  │  │
                    │   │   PREFIX         │  │
                    │   │                  │  │
                    │   │ 200 lines        │  │
                    │   └──────────────────┘  │
                    └─────────────────────────┘
                    ┌─────────────────────────┐
                    │     finance.json        │
                    │   (data source)         │
                    └─────────────────────────┘

Data Flow

Centralized Data Fetching

                    ┌──> us_finances_renderer.js ────┐
                    │                                 │
                    ├──> tw_finances_renderer.js ────┤
                    │                                 │
finance.json ─────> ├──> credit_card_age.js ─────────┼──> finance_utils.js
                    │                                 │   fetchFinanceData()
                    ├──> card_gallery.js ────────────┤   loadIcons()
                    │                                 │
                    └──> card_benefits_renderer.js ──┘

✅ All files use the same fetch utility
✅ Consistent error handling
✅ Single point of maintenance

Module Import Pattern

Example: US Finances Renderer

// us_finances_renderer.js
import { 
    isTaiwanInstitution, 
    isIconEntry, 
    loadIcons, 
    calculateAge, 
    fetchFinanceData,
    showFinanceModal,
    MS_PER_DAY,
    SUBSCRIPTION_PREFIX
} from './finance_utils.js';

document.addEventListener('DOMContentLoaded', async function () {
    try {
        const data = await fetchFinanceData('./finance.json');
        const icons = await loadIcons(data);

        // Show modal on click
        element.addEventListener('click', () => {
            showFinanceModal(contentHtml, { maxWidth: '400px' });
        });

        // Feature-specific logic here
    } catch (error) {
        console.error('Error:', error);
    }
});

Adding New Features

Step 1: Import Required Utilities

import { fetchFinanceData, isTaiwanInstitution } from './finance_utils.js';

Step 2: Use Standard Pattern

document.addEventListener('DOMContentLoaded', async function () {
    const container = document.getElementById('my-feature');
    if (!container) return;

    try {
        const data = await fetchFinanceData('./finance.json');
        // Your feature logic
    } catch (error) {
        console.error('Error:', error);
        container.innerHTML = '<p style="color:red;">Error loading data.</p>';
    }
});

Step 3: Load as Module

<div id="my-feature"></div>
<script type="module" src="/javascripts/finance/my_feature.js"></script>

Debugging Guide

Common Issues

1. Module not found

Error: Cannot find module './finance_utils.js'
- Check script tag has type="module" - Verify import path is correct (./ for same directory)

2. Function not exported

Error: The requested module does not provide an export named 'X'
- Check function is exported in finance_utils.js - Verify function name spelling in import

3. Data fetch errors

Error: HTTP error! status: 404
- Verify finance.json path relative to HTML page - Check file exists and is accessible

Tracing Data Flow

  1. Check browser console for initial errors
  2. Verify fetch succeeds - look for "Icons loaded from JSON" message
  3. Check data filtering - add console.log after fetchFinanceData()
  4. Inspect DOM - verify container exists before rendering

Last Updated: Oct 6 2025