ads: /ads/earnings — spend & earnings dashboard + PDF report - #104
Merged
Merged
Conversation
A unified money page for the account (a single user is both advertiser and publisher): total earned, total spend, net, available to withdraw; a spend-vs-earnings chart; per-site earnings and per-campaign spend tables; and payout history. Plus a downloadable PDF report for an accountant/exec. - migration: ad_slot_daily_series(days) RPC — publisher earnings by day (mirror of ad_campaign_daily_series; server-side aggregate, RLS-scoped) - lib/ads/series.ts: getSlotDailySeries + mergeMoneySeries - lib/ads/earnings-data.ts: loadEarnings() — one RLS-scoped money model shared by the page and the PDF route (spend from ad_campaigns/stats, earnings from ad_ledger publisher_accrual + ad_slot_stats, payouts, merged daily series) - app/(app)/ads/earnings/page.tsx: tiles, recharts chart (dynamic), tables - components/ads/money-trend.tsx: recharts spend-vs-earnings line chart - lib/ads/earnings-report.ts: self-contained print HTML (inline-SVG chart) - app/api/ads/earnings/pdf/route.ts: renders the report via the worker /pdf - worker/index.ts: /pdf gains an `html` branch (render raw HTML as-is) - components/ads/earnings-pdf-button.tsx + nav links from /ads and /ads/slots No new deps (recharts already present; PDF via the existing worker pipeline). Migration must be applied to prod by hand (psql over pooler) per the divergence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
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.
What
A new
/ads/earningspage: a unified money view for the account (a single user is both an advertiser and a publisher), plus a downloadable PDF report to hand an accountant / marketing / exec.Shows:
Linked from Earnings & reports buttons on
/adsand/ads/slots.How
ad_slot_daily_series(days)— publisher earnings by day, a server-side aggregate mirroring the existingad_campaign_daily_series(RLS-scoped, avoids PostgREST's 1000-row cap).lib/ads/series.ts—getSlotDailySeries+mergeMoneySeries(account-wide spend/earn axis).lib/ads/earnings-data.ts—loadEarnings(): one RLS-scoped money model shared by the page and the PDF route. Spend =ad_campaigns.total_spent_cents+ stats; earnings =ad_ledgerpublisher_accrual(authoritative) +ad_slot_stats; payouts; available = earned − non-failed payouts./pdfendpoint — it just gained anhtmlbranch that renders a complete HTML document as-is. No new PDF dependency; recharts was already a dep.Prod migration history has diverged — apply
supabase/migrations/20260717150000_ad_slot_daily_series_rpc.sqlviapsqlover the pooler after merge, or the earnings chart falls back to zero-filled (page still renders; the RPC error is swallowed).Verified
tsc(app + worker) clean ·next buildcompiles/ads/earnings+/api/ads/earnings/pdf.$amounts correct, inline SVG chart, no undefined/NaN (6.2 KB doc).Note
The PDF route 500s if
WORKER_URLisn't set in the environment (same as the existing audit PDF route) — it's set in prod.🤖 Generated with Claude Code