* feat(invoices): add column sorting and row-level status styling to invoice list Client-side sorting on number, customer, due date, amount and status with Swedish collation, null-last ordering and stable date/id tie-breaks. Status chips move to the shared RowStatus descriptor so normal states stay muted and exceptions carry semantic color. Invoice fetch now pages past the PostgREST 1000-row cap via fetchAllRows so sorting covers the full list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(invoices): make rounded-amount sort assertions non-degenerate Distinct rounded totals now prove the comparator orders by displayed value; the rounded tie case is kept as an explicit tie-breaker test since integer rounding is monotonic and can only create ties, never reorder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
19 lines
666 B
TypeScript
19 lines
666 B
TypeScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const source = fs.readFileSync(
|
|
path.resolve(__dirname, '../../../app/(dashboard)/invoices/page.tsx'),
|
|
'utf8',
|
|
)
|
|
|
|
describe('invoice list query shape', () => {
|
|
it('paginates beyond the PostgREST row cap with a stable total order', () => {
|
|
expect(source).toContain('fetchAllRows<Invoice>')
|
|
expect(source).toContain(".order('invoice_date', { ascending: false })")
|
|
expect(source).toContain(".order('id', { ascending: false })")
|
|
expect(source).toContain('.range(from, to)')
|
|
expect(source).toContain('dedupeBy: (invoice) => invoice.id')
|
|
})
|
|
})
|