1e91c126ff
The Transaktioner inbox lists unbooked skattekonto rows next to unbooked bank rows, but the sidebar badge and the Hem "Att göra" list counted bank rows only, so a migrated tax account waited in the inbox unseen. - lib/worklist: new category book_skattekonto with the inbox's own predicate (status = 'booked', no verifikat, not ignored); aggregate includes it in counts and total. - Hem: a "Bokföra skattekontohändelser" row under Bokför, deep-linking to /transactions?source=skatteverket. - Sidebar badge hook: the same third head-count query, summed into the /transactions badge. - DashboardNav subscribes to skattekonto_transactions realtime changes; migration adds the table to the supabase_realtime publication so a booked or ignored row drops the badge without a manual refresh. Closes #2180 Claude-Session: https://claude.ai/code/session_01QPQLwHNEiQfiCNLSMzXMiQ Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
import type { SupabaseClient } from '@supabase/supabase-js'
|
|
import type { SuggestedMatch } from './types'
|
|
import type { WorklistCounts } from './types'
|
|
import {
|
|
countDeadlinesNeedingAction,
|
|
countInboxDocuments,
|
|
countOverdueInvoices,
|
|
countPendingOperations,
|
|
countReconciliationDue,
|
|
countSuggestedMatches,
|
|
countSupplierInvoicesAwaitingApproval,
|
|
countUnbookedSkattekontoRows,
|
|
countUnbookedTransactions,
|
|
countVerifikatMissingDocument,
|
|
} from './categories'
|
|
|
|
/**
|
|
* All worklist counts in one round-trip burst. Each count is a bounded query
|
|
* (mostly head-only; suggested_match revalidates its candidates, see
|
|
* categories.ts) and individually soft-fails to 0, so this is safe to call
|
|
* from layouts and server components on every render.
|
|
*
|
|
* `total` is the number of distinct actionable items: suggested_match is a
|
|
* fast path over transactions already counted in book_transaction, so it is
|
|
* excluded to avoid double-counting (see lib/worklist/types.ts).
|
|
*/
|
|
export interface GetWorklistCountsOptions {
|
|
/**
|
|
* Suggested matches the caller is already fetching (Hem renders them in
|
|
* the Att göra pane): the count is taken from this list instead of a
|
|
* second scan of the same rows. A promise is accepted so it can run in
|
|
* parallel with the other counts.
|
|
*/
|
|
suggestedMatches?: SuggestedMatch[] | Promise<SuggestedMatch[]>
|
|
}
|
|
|
|
export async function getWorklistCounts(
|
|
supabase: SupabaseClient,
|
|
companyId: string,
|
|
options: GetWorklistCountsOptions = {},
|
|
): Promise<WorklistCounts> {
|
|
const [
|
|
bookTransaction,
|
|
bookSkattekonto,
|
|
inboxDocument,
|
|
suggestedMatch,
|
|
supplierInvoiceApproval,
|
|
verifikatMissingDocument,
|
|
overdueInvoice,
|
|
deadlineAction,
|
|
pendingOperations,
|
|
reconciliationDue,
|
|
] = await Promise.all([
|
|
countUnbookedTransactions(supabase, companyId),
|
|
countUnbookedSkattekontoRows(supabase, companyId),
|
|
countInboxDocuments(supabase, companyId),
|
|
options.suggestedMatches
|
|
? Promise.resolve(options.suggestedMatches).then((m) => m.length)
|
|
: countSuggestedMatches(supabase, companyId),
|
|
countSupplierInvoicesAwaitingApproval(supabase, companyId),
|
|
countVerifikatMissingDocument(supabase, companyId),
|
|
countOverdueInvoices(supabase, companyId),
|
|
countDeadlinesNeedingAction(supabase, companyId),
|
|
countPendingOperations(supabase, companyId),
|
|
countReconciliationDue(supabase, companyId),
|
|
])
|
|
|
|
return {
|
|
counts: {
|
|
book_transaction: bookTransaction,
|
|
book_skattekonto: bookSkattekonto,
|
|
inbox_document: inboxDocument,
|
|
suggested_match: suggestedMatch,
|
|
supplier_invoice_approval: supplierInvoiceApproval,
|
|
verifikat_missing_document: verifikatMissingDocument,
|
|
overdue_invoice: overdueInvoice,
|
|
deadline_action: deadlineAction,
|
|
pending_operations: pendingOperations,
|
|
reconciliation_due: reconciliationDue,
|
|
},
|
|
total:
|
|
bookTransaction +
|
|
bookSkattekonto +
|
|
inboxDocument +
|
|
supplierInvoiceApproval +
|
|
verifikatMissingDocument +
|
|
overdueInvoice +
|
|
deadlineAction +
|
|
pendingOperations +
|
|
reconciliationDue,
|
|
}
|
|
}
|