On-demand cost allocation reports. The page uses the same five-dimension tables as the Cost Allocation section on a contractor's monthly invoice — see Monthly invoices.
| Requirement | Details |
|---|---|
| Login | GitHub account via Supabase Auth. |
| Membership | Listed in team-members.json. Users not in the list receive 403 Team member access required. |
| Role | Team members see only their own cost breakdown (date range only; no contributor filter). Billing managers (billingManager: true) can filter by any contributor or run whole-team reports. isManager does not grant billing access on its own. |
Team members who pass a contributor query param for another username receive
403 You can only view your own cost breakdown.
The page reloads with search params and shows the cost allocation tables:
/stats/costs?start-date=2026-05-01&end-date=2026-05-31
/stats/costs?start-date=2026-05-01&end-date=2026-05-31&contributor=alice
Use New report to return to the form.
Five tables, in order:
| Table | Buckets from |
|---|---|
| By org | GitHub organisation |
| By repo | Repository name |
| By type | PR title prefix (feat, fix, chore, …) |
| By scope | Scope in type(scope): when present; (unscoped) otherwise |
| By type(scope) | Combined type(scope) or bare type for unscoped PRs |
Each table lists non-empty buckets with hours and amount (hours × rate), plus a subtotal row.
PR titles must match type: description or type(scope): description.
Titles that do not match bucket as (unparsed) in type, scope, and
type(scope); org and repo always come from the repository.
[!IMPORTANT] Table hours are gross submitted hours from merged PRs. They do not subtract bug attributions or add dispute credits / paid leave.
When the report is for a single contributor and the range sits in one calendar month, the page also shows a Net hours summary:
| Field | Meaning |
|---|---|
| Gross submitted | Sum of merged-PR hours in the range (same as the table subtotals) |
| Net hours | approved − bug hours + dispute credits + paid leave (same formula as monthly billing) |
| Cap | max_cap from the agreement (only when set) |
| Remaining | Cap minus billed net hours (min(net, cap)); bug hours free up headroom you can re-earn |
Carry-forward bug hours from the prior month are always included for
single-month reports. If max_cap is set and the range does not start on
the 1st, remaining cap only covers the selected dates — start from the 1st
for a month-to-date view.
The net hours summary is omitted for multi-month ranges and whole-team reports — pick a single contributor and a date range within one calendar month to see it. The monthly invoice remains the authoritative billed figure after month end.
| Report type | Rate used per merged PR |
|---|---|
| Single contributor | That contributor's profile.yaml rate for the PR's merge month |
| Whole team | Each contributor's own rate for the PR's merge month |
Whole-team reports sum hours × rate into each bucket — two developers'
feat(ui) work at different rates both contribute their respective amounts
to the same bucket.
Amounts appear only when at least one line item has a positive rate. If no rates can be resolved, hours are still shown without dollar columns.
Reports are capped at 10,000 merged PR submissions per query. If the selected range exceeds that limit, the page shows a truncation notice and only the first 10,000 submissions (by merge date) are included.
To see a complete breakdown, narrow the date range or filter to one contributor.
Each contractor's monthly invoice includes these same tables when they had merged PRs that billing month. See that section for what contractors see on the PDF; differences from this page:
| Invoice | Cost breakdown | |
|---|---|---|
| Scope | One person, billing month only | Custom date range; billing managers can optionally filter by contributor or whole team; team members see only their own data |
| Rate | Single rate for the billing month | Per contributor, per PR merge month |
| Hours | Net after QA, disputes, leave; cap applied when max_cap is set |
Tables: gross submitted. Net hours panel (single contributor, one month): net; cap + remaining when max_cap is set |
Billing managers can open any contractor's signed invoice link to see cost allocation for a given month, or use Cost breakdown for custom ranges and team-wide reports. Team members can use Cost breakdown for custom date ranges on their own merged PRs.
rates in each member's profile.yaml, resolved per merge
month (same rules as invoice generation).billingManager fieldrates and effective_from