Task: Add the report result rows table

Table of Contents

This page documents a task in the Prove the report grid run end to end — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

A run's figures are rows a query reads: one row per subject, measure and currency at the run's priced date, in a hypertable the tenant and the party each see only their own part of.

2. Status

Field Value
State DONE
Parent story Prove the report grid run end to end — the remaining work
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-30

3. Acceptance

  • The table holds one row per tenant, party, run, priced date, subject, measure and currency, with the figure and the file it came from, and the counterparty when the engine stated one.
  • The table is a TimescaleDB hypertable on as_of, in 30-day chunks.
  • Tenant isolation and party isolation are policies on the table rather than checks in the service.
  • A natural key index and an as_of index serve the run read and a subject's history.
  • The DDL is generated from ores.reporting.report_result_row, and projects/ores.sql/create/reporting/reporting_create.sql includes it, so a database built from nothing has the table.
  • The table declares no retention interval; that is recorded as an open capture rather than claimed here.

4. Plan

The table is modelled in projects/ores.reporting/modeling/ores.reporting.report_result_row.org on the readonly-timeseries profile, so codegen emits the entity, the mapper, the repository, the service, the handler and the DDL, and the hypertable is applied by the generated SQL.

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
The table is a hypertable ores_reporting_report_result_rows_tbl, one dimension on as_of compass sql -- -c "select hypertable_name, num_dimensions from timescaledb_information.hypertables where hypertable_name like '%result%'" 55e53d5c56
The chunk interval 30 days on as_of compass sql -- -c "select hypertable_name, column_name, time_interval from timescaledb_information.dimensions where hypertable_name = 'ores_reporting_report_result_rows_tbl'" 55e53d5c56
Isolation is two policies report_result_rows_tbl_tenant_isolation_policy and report_result_rows_tbl_party_isolation_policy compass sql -- -c "select polname from pg_policy where polrelid = 'ores_reporting_report_result_rows_tbl'::regclass" 55e53d5c56
The indexes the primary key on (id, as_of), the natural key unique index and ..._as_of_idx compass sql -- -c "select indexname from pg_indexes where tablename = 'ores_reporting_report_result_rows_tbl'" 55e53d5c56
The retention none, and no Timescale retention job exists on any table in this environment compass sql -- -c "select job_id, hypertable_name, proc_name from timescaledb_information.jobs where hypertable_name is not null" 55e53d5c56

6. Notes

  • The table, the node's projection and the post-processing step all landed inside #3916, and the PR was recorded on Post-process a run's results into rows alone. This task is closed with the record it was missing.
  • The description asks for the retention the market data ticks use. The tick model declares :hypertable_retention_interval: 7 days, and this table declares none. Filed as Declare the retention the result rows keep.
  • The primary key is (id, as_of), which is what the hypertable needs and what a point read of one figure uses.

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
Run a report through the grid and read every result PENDING The scenario reads the result rows table and checks that it is a hypertable.

8. PRs

PR Title
#3916 [reporting] Post-process a run's results into rows

9. Review

Comment summary File Decision Notes
       

10. Result

The result rows table exists and is a hypertable on as_of, in 30-day chunks. It holds one row per tenant, party, run, priced date, subject, measure and currency, with the figure, its currency, the counterparty the engine stated and the file the row came from. Two policies confine a reader to its tenant and its party, so the service applies no rule of its own. The natural key index and the as_of index serve the run read and a subject's history.

The model emits the create and drop scripts and the reporting schema includes them, so a database built from nothing has the table. The table keeps its rows indefinitely: it declares no retention interval, and this environment runs no Timescale retention job.

Emacs 29.3 (Org mode 9.6.15)