Skip to content

fix(seed): guarantee every displayed month of Monthly Revenue is in-band#38

Merged
jeffgicharu merged 1 commit into
mainfrom
fix/dashboard-revenue-baseline
May 19, 2026
Merged

fix(seed): guarantee every displayed month of Monthly Revenue is in-band#38
jeffgicharu merged 1 commit into
mainfrom
fix/dashboard-revenue-baseline

Conversation

@jeffgicharu
Copy link
Copy Markdown
Owner

@jeffgicharu jeffgicharu commented May 19, 2026

Problem

The dashboard Monthly Revenue chart aggregates paid invoices by paid_at
month over the trailing 6 months (DashboardRepository.getMonthlyRevenue). The
seed's random invoice distribution is realistic for project-based billing but,
on some reseeds, left the oldest displayed month at $0 — its paid_at
spilling just outside the dashboard window. The chart then read as a ramp-up
from zero rather than an established business, and varied per reseed.

Live "before" (current production seed) — Dec starts at ~$0, May trails to ~$0:

Month Dec Jan Feb Mar Apr May
Old seed (reseed sample) $0–$15k ~$58k ~$30k ~$32k low ~$0

Fix

Deterministically plant a paid-invoice baseline in each of the 6 displayed
months, layered on top of the existing random invoices. Each month's baseline
paid_at is pinned to the 15th at noon UTC (clamped into the past) so it
always lands in that month's date_trunc('month') bucket and inside the
dashboard window. The baseline amounts are fixed (no RNG), so the floor is
guaranteed on every reseed.

Determinism approach (one sentence): the seed plants two fixed-amount paid
invoices per displayed month, dated to mid-month in the past, before the random
invoices are layered on — so every month's total is deterministically above the
floor regardless of the random draw.

Chosen band (documented in seed.ts):

After (4 consecutive reseeds, all 6 months in-band):

Reseed Dec Jan Feb Mar Apr May
1 81,556 61,211 84,036 67,983 122,774 54,400
2 103,121 71,297 125,961 59,300 120,280 70,246
3 111,883 95,210 105,539 96,062 89,424 64,526
4 80,816 118,877 78,245 87,048 103,116 55,795

Test

New Postgres-backed regression test dashboard-revenue.int-spec.ts runs the
demo seed against a fresh database, calls the exact dashboard aggregation, and
asserts every month in the 6-month window is > 0 and within [40k, 200k].
Verified it fails on the pre-baseline seed (3/3 runs, a month at
~$12k–$31k) and passes after (4/4 runs).

The chart component is unchanged; no months are hidden — data is guaranteed,
not its absence masked.

Scope

Touches only the invoice seed for the displayed revenue window and the new
test. No other settled data (compliance, audit, W-9, currency, names,
classification, risk weights) is modified.

The dashboard Monthly Revenue chart aggregates paid invoices by paid_at
month over the trailing 6 months. The random invoice distribution alone
could leave the oldest displayed month at $0 on some reseeds (its paid_at
spilling just outside the window), so the chart sometimes read as a
ramp-up from zero rather than an established business.

Deterministically plant a paid-invoice baseline in each of the 6
displayed months on top of the random invoices. Each month's baseline
paid_at is pinned to the 15th at noon UTC (clamped into the past) so it
always lands in that month's date_trunc bucket and inside the dashboard
window. Documented band: $40,000 floor, $200,000 ceiling per month;
observed reseed totals land ~$54k–$126k with the current month never a
spike.

Add a Postgres-backed regression test that runs the seed and asserts
every month in the 6-month window is within the band. Verified it fails
on the pre-baseline seed and passes after.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a deterministic revenue baseline within the demoSeed function to ensure the dashboard's monthly revenue chart consistently displays data for the trailing six months. It also includes a new integration test to verify that the seeded revenue remains within the expected $40,000 to $200,000 range. Feedback was provided regarding an inefficient UPDATE query in the seeding logic that could lead to NULL values for total_amount if tax_amount is not set, potentially defeating the purpose of the baseline fix. A more robust and optimized query was suggested.

Comment on lines +408 to +414
`UPDATE invoices SET
subtotal = (SELECT COALESCE(SUM(amount),0) FROM invoice_line_items WHERE invoice_id = $1),
total_amount = (SELECT COALESCE(SUM(amount),0) FROM invoice_line_items WHERE invoice_id = $1) + tax_amount
WHERE id = $1`,
[invId],
);
const history: Array<[string, string, string]> = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The UPDATE query is inefficient as it executes the same subquery twice for every baseline invoice. More importantly, if tax_amount is NULL in the database (which is likely since it is not specified in the preceding INSERT statement), the total_amount calculation (subtotal + tax_amount) will result in NULL. This would cause the dashboard revenue aggregation to return 0 for that month, defeating the purpose of this baseline fix. Since we know the subtotal for these specific baseline invoices is exactly perInvoice, we can optimize the query and use COALESCE to ensure the total is correctly calculated.

          await pool.query(
            `UPDATE invoices SET
              subtotal = $2,
              total_amount = $2 + COALESCE(tax_amount, 0)
             WHERE id = $1`,
            [invId, perInvoice],
          );

@jeffgicharu jeffgicharu merged commit 6af085c into main May 19, 2026
19 checks passed
@jeffgicharu jeffgicharu deleted the fix/dashboard-revenue-baseline branch May 19, 2026 06:33
@jeffgicharu
Copy link
Copy Markdown
Owner Author

Live verification complete. Backed up the production DB to /var/backups/contractoros-pre-chart-lockdown-20260519-063959.sql, reseeded production, and read the live dashboard. The Monthly Revenue chart now shows six nonzero, bumpy months sitting steady in the ~$90k–$120k range (Mar $107,576) — no zero start at Dec, no collapse at May, Y-axis tops at $120k well under the $200k ceiling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant