From eb4f8f7e53fbf6a78010117ac5345d186df5909f Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 15:38:18 +0200 Subject: [PATCH 1/6] chore: add .mcp.json and ignore .playwright-mcp/ Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + .mcp.json | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 .mcp.json diff --git a/.gitignore b/.gitignore index 0e23399..6d1f429 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ certs .obsidian .claude/ +.playwright-mcp/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..6623baa --- /dev/null +++ b/.mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "playwright": { + "command": "npx", + "args": [ + "@playwright/mcp@latest", + "--caps", + "devtools" + ] + } + } +} From 58f9fb692f47809f2e096aa72ce0437c039f7afa Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 16:06:20 +0200 Subject: [PATCH 2/6] feat(libra/balance): show lifetime income vs expenses breakdown Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/views/BalancePage.vue | 67 +++++++++++++++++++- src/modules/expenses/services/ExpensesAPI.ts | 4 ++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/accounting-app/views/BalancePage.vue b/src/accounting-app/views/BalancePage.vue index 0a27bf0..c44382c 100644 --- a/src/accounting-app/views/BalancePage.vue +++ b/src/accounting-app/views/BalancePage.vue @@ -6,7 +6,7 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { useToast } from '@/core/composables/useToast' import type { ExpensesAPI } from '@/modules/expenses/services/ExpensesAPI' import type { Transaction } from '@/modules/expenses/types' -import { ArrowDown, ArrowUp, Clock, Loader2, PieChart } from 'lucide-vue-next' +import { ArrowDown, ArrowUp, Clock, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' import { Badge } from '@/components/ui/badge' const { t } = useI18n() @@ -18,6 +18,10 @@ const expensesAPI = injectService(SERVICE_TOKENS.EXPENSES_API) const balance = ref(null) const balanceCurrency = ref('sats') const fiatBalances = ref>({}) +const totalExpensesSats = ref(0) +const totalExpensesFiat = ref>({}) +const totalIncomeSats = ref(0) +const totalIncomeFiat = ref>({}) const pendingTransactions = ref([]) const isLoading = ref(true) @@ -25,6 +29,18 @@ const fiatBalanceEntries = computed(() => Object.entries(fiatBalances.value).filter(([, amount]) => Math.abs(amount) > 0.005) ) +const expensesFiatEntries = computed(() => + Object.entries(totalExpensesFiat.value).filter(([, amount]) => Math.abs(amount) > 0.005) +) + +const incomeFiatEntries = computed(() => + Object.entries(totalIncomeFiat.value).filter(([, amount]) => Math.abs(amount) > 0.005) +) + +const hasBreakdown = computed(() => + totalExpensesSats.value > 0 || totalIncomeSats.value > 0 +) + const walletKey = computed(() => user.value?.wallets?.[0]?.inkey) const budgetsEnabled = computed(() => import.meta.env.VITE_LIBRA_BUDGETS_ENABLED === 'true') @@ -61,6 +77,10 @@ async function loadData() { balance.value = balanceData.balance balanceCurrency.value = balanceData.currency || 'sats' fiatBalances.value = balanceData.fiat_balances || {} + totalExpensesSats.value = balanceData.total_expenses_sats || 0 + totalExpensesFiat.value = balanceData.total_expenses_fiat || {} + totalIncomeSats.value = balanceData.total_income_sats || 0 + totalIncomeFiat.value = balanceData.total_income_fiat || {} // Filter for pending transactions (flag = '!') pendingTransactions.value = txData.entries.filter(tx => tx.flag === '!') @@ -137,6 +157,51 @@ function formatFiat(amount: number, currency: string): string { + +
+ +
+
+ +

Income

+
+

+ {{ formatAmount(totalIncomeSats) }} + sats +

+
+

+ {{ formatFiat(amount, currency) }} +

+
+
+ + +
+
+ +

Expenses

+
+

+ {{ formatAmount(totalExpensesSats) }} + sats +

+
+

+ {{ formatFiat(amount, currency) }} +

+
+
+
+
diff --git a/src/modules/expenses/services/ExpensesAPI.ts b/src/modules/expenses/services/ExpensesAPI.ts index 8cfee1a..625fbd2 100644 --- a/src/modules/expenses/services/ExpensesAPI.ts +++ b/src/modules/expenses/services/ExpensesAPI.ts @@ -249,6 +249,10 @@ export class ExpensesAPI extends BaseService { balance: number currency: string fiat_balances?: Record + total_expenses_sats?: number + total_expenses_fiat?: Record + total_income_sats?: number + total_income_fiat?: Record }> { try { const response = await fetch(`${this.baseUrl}/libra/api/v1/balance`, { From 80d3e32c9280cebb961ae2906cfd098f78e97715 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 16:11:57 +0200 Subject: [PATCH 3/6] feat(libra/balance): clarify income/expenses cards with info captions Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/views/BalancePage.vue | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/accounting-app/views/BalancePage.vue b/src/accounting-app/views/BalancePage.vue index c44382c..93ce27f 100644 --- a/src/accounting-app/views/BalancePage.vue +++ b/src/accounting-app/views/BalancePage.vue @@ -6,7 +6,7 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { useToast } from '@/core/composables/useToast' import type { ExpensesAPI } from '@/modules/expenses/services/ExpensesAPI' import type { Transaction } from '@/modules/expenses/types' -import { ArrowDown, ArrowUp, Clock, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' +import { ArrowDown, ArrowUp, Clock, Info, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' import { Badge } from '@/components/ui/badge' const { t } = useI18n() @@ -162,7 +162,7 @@ function formatFiat(amount: number, currency: string): string {
- +

Income

@@ -178,12 +178,18 @@ function formatFiat(amount: number, currency: string): string { {{ formatFiat(amount, currency) }}

+
+ +

+ Collected on behalf of the organization — you owe this back. +

+
- +

Expenses

@@ -199,6 +205,12 @@ function formatFiat(amount: number, currency: string): string { {{ formatFiat(amount, currency) }}

+
+ +

+ Paid on the organization's behalf — owed back to you. +

+
From 8d9768aeff15a56f775566f0a7fda92376ed15df Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 16:06:20 +0200 Subject: [PATCH 4/6] feat(libra/balance): show lifetime income vs expenses breakdown Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/views/BalancePage.vue | 67 +++++++++++++++++++- src/modules/expenses/services/ExpensesAPI.ts | 4 ++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/accounting-app/views/BalancePage.vue b/src/accounting-app/views/BalancePage.vue index 0a27bf0..c44382c 100644 --- a/src/accounting-app/views/BalancePage.vue +++ b/src/accounting-app/views/BalancePage.vue @@ -6,7 +6,7 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { useToast } from '@/core/composables/useToast' import type { ExpensesAPI } from '@/modules/expenses/services/ExpensesAPI' import type { Transaction } from '@/modules/expenses/types' -import { ArrowDown, ArrowUp, Clock, Loader2, PieChart } from 'lucide-vue-next' +import { ArrowDown, ArrowUp, Clock, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' import { Badge } from '@/components/ui/badge' const { t } = useI18n() @@ -18,6 +18,10 @@ const expensesAPI = injectService(SERVICE_TOKENS.EXPENSES_API) const balance = ref(null) const balanceCurrency = ref('sats') const fiatBalances = ref>({}) +const totalExpensesSats = ref(0) +const totalExpensesFiat = ref>({}) +const totalIncomeSats = ref(0) +const totalIncomeFiat = ref>({}) const pendingTransactions = ref([]) const isLoading = ref(true) @@ -25,6 +29,18 @@ const fiatBalanceEntries = computed(() => Object.entries(fiatBalances.value).filter(([, amount]) => Math.abs(amount) > 0.005) ) +const expensesFiatEntries = computed(() => + Object.entries(totalExpensesFiat.value).filter(([, amount]) => Math.abs(amount) > 0.005) +) + +const incomeFiatEntries = computed(() => + Object.entries(totalIncomeFiat.value).filter(([, amount]) => Math.abs(amount) > 0.005) +) + +const hasBreakdown = computed(() => + totalExpensesSats.value > 0 || totalIncomeSats.value > 0 +) + const walletKey = computed(() => user.value?.wallets?.[0]?.inkey) const budgetsEnabled = computed(() => import.meta.env.VITE_LIBRA_BUDGETS_ENABLED === 'true') @@ -61,6 +77,10 @@ async function loadData() { balance.value = balanceData.balance balanceCurrency.value = balanceData.currency || 'sats' fiatBalances.value = balanceData.fiat_balances || {} + totalExpensesSats.value = balanceData.total_expenses_sats || 0 + totalExpensesFiat.value = balanceData.total_expenses_fiat || {} + totalIncomeSats.value = balanceData.total_income_sats || 0 + totalIncomeFiat.value = balanceData.total_income_fiat || {} // Filter for pending transactions (flag = '!') pendingTransactions.value = txData.entries.filter(tx => tx.flag === '!') @@ -137,6 +157,51 @@ function formatFiat(amount: number, currency: string): string { + +
+ +
+
+ +

Income

+
+

+ {{ formatAmount(totalIncomeSats) }} + sats +

+
+

+ {{ formatFiat(amount, currency) }} +

+
+
+ + +
+
+ +

Expenses

+
+

+ {{ formatAmount(totalExpensesSats) }} + sats +

+
+

+ {{ formatFiat(amount, currency) }} +

+
+
+
+
diff --git a/src/modules/expenses/services/ExpensesAPI.ts b/src/modules/expenses/services/ExpensesAPI.ts index 8cfee1a..625fbd2 100644 --- a/src/modules/expenses/services/ExpensesAPI.ts +++ b/src/modules/expenses/services/ExpensesAPI.ts @@ -249,6 +249,10 @@ export class ExpensesAPI extends BaseService { balance: number currency: string fiat_balances?: Record + total_expenses_sats?: number + total_expenses_fiat?: Record + total_income_sats?: number + total_income_fiat?: Record }> { try { const response = await fetch(`${this.baseUrl}/libra/api/v1/balance`, { From 94b8ea5f4867a18f6ae0b28a121662fa494f3321 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 16:11:57 +0200 Subject: [PATCH 5/6] feat(libra/balance): clarify income/expenses cards with info captions Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/views/BalancePage.vue | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/accounting-app/views/BalancePage.vue b/src/accounting-app/views/BalancePage.vue index c44382c..93ce27f 100644 --- a/src/accounting-app/views/BalancePage.vue +++ b/src/accounting-app/views/BalancePage.vue @@ -6,7 +6,7 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { useToast } from '@/core/composables/useToast' import type { ExpensesAPI } from '@/modules/expenses/services/ExpensesAPI' import type { Transaction } from '@/modules/expenses/types' -import { ArrowDown, ArrowUp, Clock, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' +import { ArrowDown, ArrowUp, Clock, Info, Loader2, PieChart, TrendingUp, TrendingDown } from 'lucide-vue-next' import { Badge } from '@/components/ui/badge' const { t } = useI18n() @@ -162,7 +162,7 @@ function formatFiat(amount: number, currency: string): string {
- +

Income

@@ -178,12 +178,18 @@ function formatFiat(amount: number, currency: string): string { {{ formatFiat(amount, currency) }}

+
+ +

+ Collected on behalf of the organization — you owe this back. +

+
- +

Expenses

@@ -199,6 +205,12 @@ function formatFiat(amount: number, currency: string): string { {{ formatFiat(amount, currency) }}

+
+ +

+ Paid on the organization's behalf — owed back to you. +

+
From c2e8fca6136b3e08125516b5032fcab5d67426f5 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sun, 17 May 2026 15:38:18 +0200 Subject: [PATCH 6/6] chore: add .mcp.json and ignore .playwright-mcp/ Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + .mcp.json | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 .mcp.json diff --git a/.gitignore b/.gitignore index 0e23399..6d1f429 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ certs .obsidian .claude/ +.playwright-mcp/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..6623baa --- /dev/null +++ b/.mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "playwright": { + "command": "npx", + "args": [ + "@playwright/mcp@latest", + "--caps", + "devtools" + ] + } + } +}