Saltar al contenido principal

Why analytics figures read zero

Analytics writes almost nothing. Thirty-three of its thirty-six actions are reads, and the three writes are all funder records. Everything else it reports was produced somewhere else in PTRS and kept in a table.

That makes it the surface where the rest of the product's gaps become countable. Four tables this module depends on have no writer that runs, and each one turns a specific figure on a specific screen into a zero. This page traces each chain, so that a reader who finds a zero can tell whether it means nothing happened, or nothing can ever be recorded.

The general shape

A zero on an analytics screen has three possible causes, and they all look identical.

The honest kind means nothing happened in the window. The structural kind means the underlying table has no writer, so it is empty in every installed copy of PTRS, permanently. The third kind means the data genuinely exists and the screen simply cannot read it, because of a mismatch between the words the reply uses and the words the screen expects.

The structural and mismatch kinds are the ones traced below. Nothing on the screen distinguishes either from an honest zero, which is why this page exists.

Chain 1: the daily attendance summary has no writer

This is the largest of the four chains, because six separate figures depend on it.

PTRS keeps a per-location, per-day summary of attendance: total check-ins, peak headcount, unique members, average duration. Nothing anywhere in PTRS ever writes a row to it: not a save, not a scheduled check, not an import path. The table exists, is indexed, and receives nothing.

Nine different reads across four parts of PTRS depend on it, including the AI assistant's own context and its longer written answers, the Attendance Heatmap, the dashboard's attendance history, and five reads inside this module.

FigureScreen
Avg Daily Attendance tileThe analytics dashboard
Attendance Trends chartThe analytics dashboard
Avg Daily Attendance, organisation and per-locationThe executive report
Daily, Weekly and Monthly AttendanceThe operational reports
Total Attendance on every funder reportThe funder reporting screen, and its document
The attendance half of the statistical report's Year listThe MSR screen

The last two matter most in practice.

On the funder report, the zero is not simply shown: it is written into the stored report the moment it is generated, so it stays in the record, reappears in the history list, and prints in the document under Impact Metrics as "Total Attendance (period)". Fixing the underlying table later would not correct a report already generated.

On the statistical report, the Year list is built from the years this attendance summary has data in, and the years an incident was recorded, plus the current year. Since the summary is always empty, the years a club can actually select are the years it recorded an incident, plus this one. A club with three years of real attendance and no incidents can only ever run the statistical report for the current year.

The statistical report is the exception

The statistical report and the Attendance Heatmap both read the raw check-in record directly, not the summary table above. Real check-ins write to it on every check-in, whether taken on the spot or synced later from an offline device.

So PTRS keeps two different attendance sources, and this module reads both. On the same dashboard, the Attendance Trends chart is flat because it reads the summary, while the heatmap beside it queries live check-in records. The two panels are not measuring the same thing badly. They are reading different tables, and only one of them is ever populated.

That the heatmap still shows zeroes anyway is a separate fault, traced in chain 4.

Chain 2: no compliance snapshot can be written

A compliance snapshot has exactly two possible writers. One only runs under a development setup and is never present in a real installed copy of PTRS. The other is the compliance scoring engine itself, and its write can never be reached: partway through building the score, it groups several rules under the same category label and then tries to use that label as a unique key, which fails the moment two rules share one. Every statement after that point, including the write this module depends on, never runs. The full chain is set out in how the compliance score is calculated.

FigureScreen
Compliance Score tileThe analytics dashboard
Compliance Trend chartThe analytics dashboard
Overall compliance score, organisation and per-locationThe executive report
Compliance score columnThe Compliance Summary operational report

A development copy of PTRS is given one sample snapshot when it is first created, so these figures can show a number there. In any real, installed copy they read zero, which is the reverse of the usual pattern and worth stating plainly: a demonstration of PTRS can show a compliance score that no real installed copy of it can ever produce.

Chain 3: no compliance alert can be written

A compliance alert has two possible writers, and both are unreachable. One sits inside the same engine described above, past the point that never runs. The other is a once-a-day check that was never finished being connected into PTRS, so it fails every time it is scheduled to run.

So no alert can be written by any path in the product. Inside this module the consequence is narrow: the active-alerts column on the Compliance Summary operational report reads zero for every location. Outside it, the main dashboard's Urgent Actions strip reads the same table and is permanently empty, covered in full in Health & Safety.

Chain 4: the heatmap reads fields the reply does not send

This one is different. The data exists, the request succeeds, and the panel still prints zeroes.

The Attendance Heatmap asks for check-in counts by date and location, and the reply genuinely contains a date, a location and a count for each. The panel that renders it was written expecting different names for two of those three fields, and nothing in PTRS's own toolchain catches the mismatch, because the panel forces its own shape onto the reply without checking it actually matches.

The consequence cascades. Every cell the grid looks for comes up empty, because it searches by a field that was never actually sent. Each miss paints the cell grey and prints a zero. The panel's own scale for how dark a cell should be also breaks in the same way, so every cell's colour intensity is undefined rather than proportionate. And because the reply is not literally empty, the panel's own "no data" message never appears either, so a fully drawn, entirely wrong grid renders instead.

The result is a five-row grid of zeroes under a caption describing weekday averages, with each cell's own explanation claiming a specific site had no children on a specific weekday, over a table that holds the check-ins to prove otherwise.

This is worse than an empty state: an empty panel says nothing, while this one actively states that no child attended any site on any weekday for thirty days.

There is a second layer beneath the field mismatch. What PTRS actually sends is grouped by date and expressed as a count, not grouped by weekday and expressed as an average. Even with the field names corrected, the panel would still be summing daily counts into weekday buckets and labelling the result an average.

The one empty table that costs nothing

One more table in this module has no writer, and it is the exception that proves the rest are not inevitable. A stored snapshot behind the enrolment trend chart is read first, and when it finds nothing, PTRS falls back to counting real enrolment records directly instead.

That fallback is the only path that has ever run, and it works correctly. This is the same defect shape as the three chains above, a table with a reader and no writer, and the only one of the four built with a working alternative behind it. It earns a place on this page because the contrast is the point: none of the other three chains had to be built without one.

How to tell which zero you are looking at

If you seeIt is
Avg Daily Attendance or Compliance Score reading zero on the dashboardStructural. Always zero, in every installed copy of PTRS
A flat Attendance Trends chartStructural
A populated Attendance Heatmap grid of zeroesThe field mismatch. Real data sits behind it
A message saying there is no heatmap dataHonest. The window genuinely had no check-ins
A Compliance Trend chart with points on itA development setup, given a sample snapshot when it was first created
Total Attendance reading zero on a funder reportStructural, and already written into the stored report
An empty operational attendance reportStructural
An empty Incident Log or Enrollment Roster reportHonest. Both read live tables

The reliable rule: if a figure is about attendance summaries or compliance scores, a zero tells you nothing about your organisation. Every other figure in the module reads a table that something genuinely writes to.

Checked against PTRS on 7 September 2026.