Private
Public Access
1
0

Add budget, loan, payee, and scheduled transaction tools to AI chat

Integrate 6 new tool chains into the chat service: get_budget,
get_budget_summary, get_loan_details, calculate_loan_payoff,
list_payees, and get_scheduled_transactions. Also raises the
search_transactions page_size cap from 25 to 50 and the upcoming
bills display from 5 to 10.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-10 08:28:31 -05:00
parent 26fb3dc1e1
commit 6552a97036
2 changed files with 434 additions and 4 deletions
@@ -158,6 +158,160 @@
Deleted {{ data.type }} category "{{ data.name }}"
</v-alert>
</div>
<!-- Budget -->
<div v-else-if="type === 'budget' && data?.items">
<div class="text-subtitle-2 mb-1">
Budget for {{ data.year }}-{{ String(data.month).padStart(2, '0') }}
</div>
<v-table density="compact" class="text-caption rounded-lg mb-2">
<thead>
<tr>
<th>Category</th>
<th class="text-right">Budgeted</th>
<th class="text-right">Actual</th>
<th class="text-right">Remaining</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data.items" :key="item.id">
<td>{{ item.categoryName }}</td>
<td class="text-right">{{ formatCurrency(item.budgetedAmount) }}</td>
<td class="text-right">{{ formatCurrency(item.actualAmount) }}</td>
<td class="text-right" :class="item.budgetedAmount - item.actualAmount >= 0 ? 'text-success' : 'text-error'">
{{ formatCurrency(item.budgetedAmount - item.actualAmount) }}
</td>
</tr>
</tbody>
</v-table>
</div>
<!-- Budget Summary -->
<div v-else-if="type === 'budget_summary'">
<v-card variant="tonal" density="compact" class="mb-2 pa-3">
<div class="text-subtitle-2 mb-2">
Budget Summary {{ data.year }}-{{ String(data.month).padStart(2, '0') }}
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Total Budgeted</span>
<span class="text-caption">{{ formatCurrency(data.totalBudgeted) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Total Spent</span>
<span class="text-caption">{{ formatCurrency(data.totalActual) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Remaining</span>
<span class="text-caption" :class="data.remaining >= 0 ? 'text-success' : 'text-error'">
{{ formatCurrency(data.remaining) }}
</span>
</div>
<div class="d-flex justify-space-between">
<span class="text-caption text-medium-emphasis">Over Budget</span>
<span class="text-caption" :class="data.overBudgetCount > 0 ? 'text-error' : 'text-success'">
{{ data.overBudgetCount }} categories
</span>
</div>
</v-card>
</div>
<!-- Loan Details -->
<div v-else-if="type === 'loan_details'">
<v-card variant="tonal" density="compact" class="mb-2 pa-3">
<div class="text-subtitle-2 mb-2">{{ data.accountName }}</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Original Balance</span>
<span class="text-caption">{{ formatCurrency(data.originalBalance) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Current Balance</span>
<span class="text-caption text-error">{{ formatCurrency(data.currentBalance) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Interest Rate</span>
<span class="text-caption">{{ data.interestRate?.toFixed(2) }}%</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Monthly Payment</span>
<span class="text-caption">{{ formatCurrency(data.monthlyPayment) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Maturity Date</span>
<span class="text-caption">{{ formatDate(data.maturityDate) }}</span>
</div>
<div v-if="data.escrowAmount" class="d-flex justify-space-between">
<span class="text-caption text-medium-emphasis">Escrow</span>
<span class="text-caption">{{ formatCurrency(data.escrowAmount) }}</span>
</div>
</v-card>
</div>
<!-- Loan Payoff Scenario -->
<div v-else-if="type === 'loan_payoff'">
<v-card variant="tonal" density="compact" class="mb-2 pa-3">
<div class="text-subtitle-2 mb-2">Payoff Scenario</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Original Payoff</span>
<span class="text-caption">{{ formatDate(data.originalPayoffDate) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">New Payoff</span>
<span class="text-caption text-success">{{ formatDate(data.newPayoffDate) }}</span>
</div>
<div class="d-flex justify-space-between mb-1">
<span class="text-caption text-medium-emphasis">Interest Saved</span>
<span class="text-caption text-success">{{ formatCurrency(data.interestSaved) }}</span>
</div>
<div class="d-flex justify-space-between">
<span class="text-caption text-medium-emphasis">Months Saved</span>
<span class="text-caption text-success">{{ data.monthsSaved }}</span>
</div>
</v-card>
</div>
<!-- Payees -->
<div v-else-if="type === 'payees' && Array.isArray(data)">
<v-table density="compact" class="text-caption rounded-lg mb-2">
<thead>
<tr>
<th>Name</th>
<th>Default Category</th>
</tr>
</thead>
<tbody>
<tr v-for="payee in data" :key="payee.id">
<td>{{ payee.name }}</td>
<td class="text-medium-emphasis">{{ payee.defaultCategoryName || '-' }}</td>
</tr>
</tbody>
</v-table>
</div>
<!-- Scheduled Transactions -->
<div v-else-if="type === 'scheduled_transactions' && Array.isArray(data)">
<v-table density="compact" class="text-caption rounded-lg mb-2">
<thead>
<tr>
<th>Payee</th>
<th class="text-right">Amount</th>
<th>Frequency</th>
<th>Next Due</th>
<th>Account</th>
</tr>
</thead>
<tbody>
<tr v-for="txn in data" :key="txn.id">
<td>{{ txn.payeeName || 'Unknown' }}</td>
<td class="text-right text-no-wrap" :class="txn.amount >= 0 ? 'text-success' : 'text-error'">
{{ formatCurrency(txn.amount) }}
</td>
<td>{{ txn.frequency }}</td>
<td class="text-no-wrap">{{ formatDate(txn.nextDueDate) }}</td>
<td>{{ txn.accountName }}</td>
</tr>
</tbody>
</v-table>
</div>
</template>
<script setup lang="ts">