// src/api/ledgers.ts import { pb } from './pocketbase' import type { Ledger } from '@/types' interface CreateLedgerData { group: string type: string amount: number category: string description?: string relatedMembers?: string[] occurredAt: string } interface ListLedgersOptions { page?: number limit?: number type?: string category?: string month?: string } interface LedgerSummary { totalIncome: number totalExpense: number balance: number } export async function createLedger(data: CreateLedgerData): Promise { const user = pb.authStore.model const record = await pb.collection('ledgers').create({ ...data, creator: user?.id || '', relatedMembers: data.relatedMembers || [] }, { $autoCancel: false }) return record as unknown as Ledger } export async function listLedgers( groupId: string, options?: ListLedgersOptions ): Promise<{ items: Ledger[]; total: number }> { const { page = 1, limit = 30, type, category, month } = options || {} let filter = `group="${groupId}"` if (type) filter += ` && type="${type}"` if (category) filter += ` && category="${category}"` if (month) { const start = `${month}-01 00:00:00` const year = parseInt(month.slice(0, 4)) const mon = parseInt(month.slice(5, 7)) const nextMonth = mon === 12 ? `${year + 1}-01` : `${year}-${String(mon + 1).padStart(2, '0')}` const end = `${nextMonth}-01 00:00:00` filter += ` && occurredAt>="${start}" && occurredAt<"${end}"` } const result = await pb.collection('ledgers').getList(page, limit, { filter, sort: '-occurredAt', expand: 'creator,relatedMembers', $autoCancel: false }) return { items: result.items as unknown as Ledger[], total: result.totalItems } } export async function updateLedger( ledgerId: string, data: Partial ): Promise { const record = await pb.collection('ledgers').update(ledgerId, data, { $autoCancel: false }) return record as unknown as Ledger } export async function deleteLedger(ledgerId: string): Promise { await pb.collection('ledgers').delete(ledgerId, { $autoCancel: false }) } export async function getLedgerSummary( groupId: string, month?: string ): Promise { let totalIncome = 0 let totalExpense = 0 let page = 1 const batchSize = 500 let hasMore = true let filter = `group="${groupId}"` if (month) { const start = `${month}-01 00:00:00` const year = parseInt(month.slice(0, 4)) const mon = parseInt(month.slice(5, 7)) const nextMonth = mon === 12 ? `${year + 1}-01` : `${year}-${String(mon + 1).padStart(2, '0')}` const end = `${nextMonth}-01 00:00:00` filter += ` && occurredAt>="${start}" && occurredAt<"${end}"` } while (hasMore) { const result = await pb.collection('ledgers').getList(page, batchSize, { filter, fields: 'type,amount', $autoCancel: false }) for (const item of result.items as any[]) { if (item.type === 'income') { totalIncome += item.amount || 0 } else if (item.type === 'expense') { totalExpense += item.amount || 0 } } hasMore = result.items.length === batchSize && page * batchSize < result.totalItems page++ } return { totalIncome, totalExpense, balance: totalIncome - totalExpense } } export function subscribeLedgers( groupId: string, callback: (data: any) => void ) { return pb.collection('ledgers').subscribe('*', (data) => { if (data.record?.group === groupId) { callback(data) } }) }