Customer feature requests: admin presence, invoice filters, lots edit, paddle tally#9
Open
curiousdaniel wants to merge 2 commits into
Open
Customer feature requests: admin presence, invoice filters, lots edit, paddle tally#9curiousdaniel wants to merge 2 commits into
curiousdaniel wants to merge 2 commits into
Conversation
Submit-lock guards prevent double-submits across bidder add, sale form, and payment modal. Bidder adds immediately flush a single-event cloud snapshot so background pulls can't wipe local-only bidders. Sticky consignor: stop clearing consignor between lots in clerking; add an opt-out preference (default on). Lot autofill still overrides when a different consignor is loaded. Invoices stop scroll-jumping: list sorts by invoice number instead of generatedAt; recalc skips the row update and generatedAt bump when nothing actually changed; allocate + recalc now run in one Dexie transaction so totals update once instead of flickering. Paid invoices stop reverting to unpaid: PaymentModal bumps generatedAt and uses enqueueInvoicePatch instead of full invoice.put. applyRemoteOp and snapshotMerge preserve local paid status when an incoming row says unpaid. Auto-allocate sale to the bidder's open invoice on every successful clerk write, so items can no longer go missing from invoices. Inside-tx duplicate-sale guard catches multi-device races. One-shot repair pass detaches legacy duplicate sale rows attached to the same lot on one invoice (gated by a localStorage flag). InvoiceDetail does display-side dedupe by lotId as a belt-and-suspenders. Tests cover paid-status protection, no-op recalc, sticky consignor pref, and the duplicate-line repair pass. All 162 tests pass; tsc and next lint clean. Co-authored-by: Cursor <cursoragent@cursor.com>
Bug fixes for the recent auction shipped in #8; this round adds the features customers asked for after using ClerkPad live: Lots tab — full sale visibility from any historical lot - Search by lot #, description, paddle, buyer name, consignor, or notes. - Sortable columns and a status filter. - Expandable rows show buyer, hammer, paddle, clerk, qty, consignor, recorded-at, and invoice allocation state. - Edit and Void actions on every row (not just the most recent 20) via the existing SaleCorrectionModal and a new shared `voidSale` helper extracted from RecentSales. Invoices — sortable, searchable table - Click any column header to sort (invoice #, name, paddle, hammer, buyer's premium, tax, total, status). - Inline search across invoice #, buyer name, paddle, and total so cashiers can find an invoice without scrolling. - Status filter and result count moved into the same filter bar. PaddleTally — live winning-bids panel - New PaddleTally component shows running totals (hammer + projected BP + tax) and a list of every won lot for a paddle, before the invoice is generated. - Added to the Clerking sidebar and as a collapsible widget on the Invoices page so the cashier can confirm what's on a paddle pre- invoice. Backed by `buildPaddleTally` in `lib/services/paddleTally.ts` with unit tests covering allocated/unallocated/mixed cases. New invoice after paid bidder bids again — UX surface - `upsertInvoiceForBidder` now reports `supplementalAfterPaid` when it opens a fresh invoice for a bidder whose prior invoices are all paid. - SaleForm shows a follow-up toast so the clerk knows a new invoice was opened (the auto-allocate logic already created the invoice; this just makes it visible). Admin dashboard — live presence + 24h activity + extended metrics - Heartbeat-based activity tracking via two new tables (`user_activity_pings` ledger + `user_activity_summary` rolling counter) added in `db/migrate_user_activity.sql` and reflected in `db/schema.sql`. Both reads and writes degrade gracefully if the migration hasn't been run yet. - New `HeartbeatProvider` pings `/api/admin/heartbeat` every 60s while the tab is visible; admin SQL joins the summary so each row shows a green dot when seen within 90s and the rolling 24h ping count. - Summary cards above the user table: Online now, Active in last 24h, total synced events, total sales, total invoice $. - Per-row columns now include consignor count, invoice count, and a rolled-up invoice total ($) computed from cloud snapshot payloads. - `isOnlineNow` extracted as a pure helper with unit tests. Tests - 5 new tests for invoice column comparator. - 4 new tests for `buildPaddleTally`. - 6 new tests for `isOnlineNow` boundary behavior. - 26 test files, 177 tests passing. `next build`, `tsc --noEmit`, and `next lint` all pass (only the two pre-existing exhaustive-deps warnings in InvoiceDetail remain). Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #8. With the bug fixes deployed, this PR ships the feature requests from the customer feedback.
Summary
SaleCorrectionModaland a new sharedvoidSalehelper extracted fromRecentSales.buildPaddleTallywith unit tests.upsertInvoiceForBiddernow reportssupplementalAfterPaidwhen it opens a new invoice for a bidder whose prior invoices are all paid. SaleForm shows a follow-up toast so the clerk knows a fresh invoice was opened.user_activity_pings+user_activity_summary), a heartbeat API (/api/admin/heartbeat), aHeartbeatProviderthat pings every 60 s while the tab is visible, summary cards (Online now, Active in last 24h, totals), green-dot per-row presence, and new columns for consignors, invoices, and rolled-up invoice totals ($). All migration-aware: reads and writes degrade gracefully if the new tables aren't yet present.next build,tsc --noEmit, andnext lintall clean (only the two pre-existingexhaustive-depswarnings inInvoiceDetailremain).Required deploy step
Run the new migration once before this ships to production:
```
psql "$DATABASE_URL" -f db/migrate_user_activity.sql
```
Until the migration runs, the heartbeat endpoint and admin reads silently no-op, so you can safely deploy in either order.
Test plan
npm run test(vitest) — should report 26 files / 177 tests passing.npm run build(next build) — should succeed.Made with Cursor