Documentation
What the Reports page totals
The four totals on the Reports page, the window and dates it does not carry, the single market signal it narrates, and the columns in the purchasing export.
Last reviewed against the product on .
The Reports page is four totals, one narrative and one download. Each total comes from its own query, and none of them is combined with any other. This page says what each one counts, and where the page is less careful than the rest of the product.
What the four cards count
| Card | Counted from | Scope |
|---|---|---|
| Purchase spend | Every purchase record your organization holds | Grouped by currency, never converted |
| Market signals | Comparable market observation groups | Your organization's country only |
| Average review | Every imported review rating | One mean across all sources |
| Open actions | Action records not marked completed | Your organization only |
Measured from app/app/reports/page.tsx.
Purchase spend is the only figure that keeps currencies apart on the face of the card. Each currency is totalled separately and the totals are printed side by side. Rows imported without a currency are not dropped; they are gathered into a bucket of their own and labelled as unspecified, so a total you cannot name a currency for is still visible rather than silently folded into one you can.
There is no window and no date
The dashboard carries a separate freshness date for each half of what it shows. Reports carries none at all. Purchase spend counts every row ever accepted, with no start and no end, so it is not the same quantity as the dashboard's weekly figure and the two are expected to disagree.
- Dates printed on the page
- None
- no measurement date, no window, no last import
- Purchase spend window
- All records
- every accepted row, oldest to newest
- Decimal places
- 2
- no thousands separator and no currency symbol
- Market signals shown
- 1
- only the highest priority group is narrated
Measured from app/app/reports/page.tsx.
The average review crosses a line the rest of the product holds
The priority narrative
Below the cards, the page prints the single highest-priority market signal and the explanation lines built with it. The inputs are the same ones behind the dashboard watchlist, so the reasoning is set out in reading the dashboard rather than repeated here.
- Observations read
- 2,000
- most recent first, restricted to your country
- Purchases read for spend weighting
- 10,000
- most recent first
- Observations needed for a signal
- 2
- in one strict comparison group
Measured from src/lib/analytics/queries.ts.
The purchasing download
| Column | Taken from |
|---|---|
| Supplier | The normalised supplier the row was matched to |
| Item | The item name as imported, not the reduced form |
| Purchase date | The purchase date, as a plain calendar date |
| Quantity | The quantity, where one was imported |
| Unit | The unit as imported |
| Unit price | The unit price, where one was imported |
| Total price | The total price, which is always present |
| Currency | The currency as imported |
Measured from app/api/reports/purchases/route.ts.
The export has no date filter and no page size. It is every purchase row your organization holds, oldest first. Any cell beginning with an equals, plus, minus or at sign is prefixed with an apostrophe, so a spreadsheet treats it as text rather than running it as a formula.
Because one request can carry a complete book of supplier prices, the download is limited twice: a burst limit by address, and a durable quota counted per organization that survives a restart.
- Downloads per hour
- 20
- per organization, counted in the database
- Requests per minute
- 60
- per address, held in memory only
Measured from src/lib/security/api-rate-limit.ts and src/lib/shared/rate-limit.ts.
What the page will not tell you
For what a single market signal means, see reading the analytics evidence table. For the boundary between market observations and your own prices, see market data against your own costs.