feat(#36): receitas recorrentes com confirmação de salário até dia 5

- Migration 009: coluna `type` em recurring_expenses + tabela recurring_late
- API Go: tipo income/expense em CRUD; endpoints POST /confirm e /late
- Dashboard: campo pending_income_recurrings na resposta
- Frontend: RecurringView com seções RECEITAS e DESPESAS separadas
- HomeView: widget de confirmação (dia 1-5) e badge SALÁRIO PENDENTE (pós dia 5)
- Testes unitários: 4 novos casos (income covered, late, confirm, reject expense)

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
2026-05-27 15:00:28 -03:00
co-authored by Claude Sonnet 4.6
parent 1931271b76
commit 79f4a62a1b
16 changed files with 725 additions and 77 deletions
+28 -2
View File
@@ -1,7 +1,6 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { api } from '@/services/api'
import type { Category } from './categories'
export interface RecurringExpense {
id: number
@@ -9,6 +8,7 @@ export interface RecurringExpense {
expected_amount: number
day_of_month: number
category_id: number | null
type: 'income' | 'expense'
active: boolean
created_at: string
updated_at: string
@@ -17,6 +17,7 @@ export interface RecurringExpense {
export interface RecurringStatus extends RecurringExpense {
covered: boolean
ignored: boolean
late: boolean
reason?: string
}
@@ -74,8 +75,33 @@ export const useRecurringStore = defineStore('recurring', () => {
await fetchMonthlyStatus(month)
}
async function confirmIncome(id: number, month: string) {
await api.post(`/recurring/${id}/confirm`, { month })
await fetchMonthlyStatus(month)
}
async function markLate(id: number, month: string) {
await api.post(`/recurring/${id}/late`, { month })
await fetchMonthlyStatus(month)
}
const pendingCount = (month: string) =>
monthlyStatus.value.filter((s) => !s.covered).length
return { items, monthlyStatus, loading, error, fetchAll, fetchMonthlyStatus, create, update, remove, ignore, unignore, pendingCount }
return {
items,
monthlyStatus,
loading,
error,
fetchAll,
fetchMonthlyStatus,
create,
update,
remove,
ignore,
unignore,
confirmIncome,
markLate,
pendingCount,
}
})