# Dashboard

## Layout

The dashboard uses a side-by-side column layout (Bootstrap `col-md-6`). Stacks to full-width on mobile automatically.

```mermaid
flowchart TB
    subgraph Dashboard["Dashboard (/)"]
        direction TB
        
        Net["Net Position: Personal Balance + Business Net"]
        
        subgraph Columns["Side-by-Side Columns"]
            direction LR
            Personal["Personal Column (col-md-6)"]
            Business["Business Column (col-md-6)"]
        end
        
        subgraph Charts["Charts Section"]
            CatDoughnut["Category Doughnut"]
            BudgetPie["Budget Pie"]
        end
        
        subgraph Panels["Module Summary Panels"]
            direction LR
            InvPanel["Investments"]
            GoalPanel["Goals"]
            DebtPanel["Debts"]
            ProjPanel["Projects"]
        end
        
        RecordList["Record List + Pagination"]
    end
    
    Net --> Columns
    Columns --> Charts
    Charts --> Panels
    Panels --> RecordList
```

## Net Position

A single number above both columns:

```
Net Position = (Personal Revenue - |Personal Expense|) + (Business Revenue - |Business Expense|)
```

This answers: "What's my total position across both ledgers?"

## Personal Column

```mermaid
flowchart TB
    subgraph Personal["Personal Column"]
        direction TB
        Summary["Summary Row"]
        MustPay["Must-Pay vs Discretionary"]
        Link["View All Records Link"]
    end
    
    Summary --> MP["Expenses"]
    Summary --> MR["Revenue"]
    Summary --> MB["Balance"]
    
    MustPay --> MPV["Must-Pay Total"]
    MustPay --> DCV["Discretionary Total"]
```

| Metric | Source | Display |
|---|---|---|
| Expenses | `personalExpense` (negative) | `$X,XXX` |
| Revenue | `personalRevenue` (positive) | `$X,XXX` |
| Balance | `personalRevenue - |personalExpense|` | `$X,XXX` |
| Must-Pay | Records where `mustPay = true` | `$X,XXX` |
| Discretionary | Records where `mustPay = false` | `$X,XXX` |

## Business Column

```mermaid
flowchart TB
    subgraph Business["Business Column"]
        direction TB
        Summary["Summary Row"]
        Link["View All Records Link"]
    end
    
    Summary --> BC["Costs"]
    Summary --> BR["Revenue"]
    Summary --> BN["Net"]
```

| Metric | Source | Display |
|---|---|---|
| Costs | `businessExpense` (negative) | `$X,XXX` |
| Revenue | `businessRevenue` (positive) | `$X,XXX` |
| Net | `businessRevenue - |businessExpense|` | `$X,XXX` |

## Charts

### Category Doughnut

Shows expense breakdown by category for the selected ledger. Uses the same `categoryAmount` and `categoryName` data from the aggregation pipeline.

### Budget Pie

Shows spent vs. remaining for the monthly budget. Only appears when a specific month is selected (not "All Months").

```
Spent = -totalExpense (flipped to positive)
Remaining = budget + totalExpense
```

## Module Summary Panels

Four panels below the charts, each linking to its full list page.

### Investments Panel

```mermaid
flowchart LR
    Inv["Investments Panel"]
    Inv --> I1["Freezer — $15,000 — Recouping"]
    Inv --> I2["Breeding Pair — $25,000 — Break Even"]
```

- Shows all investments with cost and status badge
- Status badges: Profitable (green), BreakEven (blue), Recouping (yellow)

### Goals Panel

```mermaid
flowchart LR
    Goal["Goals Panel"]
    Goal --> G1["Emergency Fund — 40% — Red"]
    Goal --> G2["New Laptop — 27% — Blue"]
    Goal --> G3["Vacation — 17% — Gray"]
```

- Groups by tier: MustFund (red), ActivelySaving (blue), Someday (gray)
- Progress bar: `savedAmount / targetAmount × 100`

### Debts Panel

```mermaid
flowchart LR
    Debt["Debts Panel"]
    Debt --> D1["HELB — $85,000 remaining"]
```

- Quiet display — no red/warning styling
- Shows remaining balance only

### Projects Panel

```mermaid
flowchart LR
    Proj["Projects Panel"]
    Proj --> P1["Portfolio Site — Paused — 2023-08-01"]
    Proj --> P2["Dog Business — Maintenance — 2023-11-20"]
    Proj --> P3["Expense Tracker — Active — 2024-01-15"]
```

- Sorted by `lastTouched` ascending (stalest first)
- Status badges: Active (green), Maintenance (blue), Paused (yellow), Archived (gray)

## Data Aggregation Pipeline

The dashboard loads all data in parallel:

```mermaid
sequenceDiagram
    participant C as Controller
    participant DB as MongoDB

    par Records Aggregation
        C->>DB: Record.aggregate([ $addFields, $match, $lookup, $unwind, $facet ])
        DB-->>C: metadata, data, data2 (by type+ledger), data3 (by category), data4 (mustPay)
    and Module Summaries
        C->>DB: Debt.find({ userId })
        C->>DB: Goal.find({ userId })
        C->>DB: Project.find({ userId }).sort({ lastTouched: 1 })
        C->>DB: Investment.find({ userId })
    end

    C->>C: Compute split totals
    C->>C: Compute mustPay/discretionary
    C->>C: Compute netPosition
    C->>C: Compute businessNet
    C->>C: Group goals by tier
    C->>C: Compute remainingBalance for debts
    C->>C: Render index.hbs with all data
```

## Ledger Toggle

The dashboard includes a Personal/Business toggle that passes `?ledger=Personal` or `?ledger=Business` as a query parameter. This:

1. Filters the category dropdown to show only matching categories
2. Passes `ledger` to the aggregation pipeline
3. Preserves the ledger selection across filter changes (date, category)

## Sidebar

The sidebar (visible on XL screens) shows:
- "Expenses by Category" header
- Category doughnut chart (when viewing "All Months")
- Category list with amounts

The category list is filtered by the selected ledger, so Personal shows Personal categories and Business shows Business categories.
