A report no longer carries a day older than the day-to-week compaction
threshold minus one day: 179 days by default. No weekly row can be
inside that window, so the backfill no longer needs to find the newest
weekly row. getDailyDataStart() is removed. The first owed day now
comes from the existing getEarliestDataDate(). The limit replaces the
730-day cap.
The day of margin covers Postgres, which dates the compaction
threshold in the session's time zone rather than in UTC.
getEarliestDataDate() now parses the SQLite datetime string as UTC.
Before, it read it as local time, so the insights settings could show
the day before the first data on a server outside UTC.
LOCAL_VERIFICATION.md no longer says that the report reads insights as
the instance owner.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
getDailyDataStart() now returns one day: the oldest hourly or daily
row's day, but never before the Monday after the newest weekly row.
Without hourly or daily rows, it returns that Monday. Before, it
returned two bounds, and the gap after a delivered report used the
weekly bound alone.
A gap after a delivered report now also starts no earlier than the
first insights data. Days without executions before that data are
left out instead of sent as 0. No execution count is lost.
RETRIES.md also states that insights never stores a 0, so a day
without executions and a day without collected data look the same.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
getDailyExecutionTotals() was only run through the instance
reporting integration test, which seeds success rows only. The new
test checks that the method adds succeeded and failed executions of
workflows in different projects, leaves other insight types out, and
puts hourly rows on their own UTC day.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- README: Say that days before the first insights data are not sent,
and that a day without data inside the sent range is 0. Limit the
"insights disabled" note to days after the first data.
- LOCAL_VERIFICATION: Give the real bounds of the first report: the
oldest hourly or daily row, the Monday after the newest weekly row,
and the 730-day cap.
- RETRIES: Do not claim that a 413 is impossible. Say what happens
when the receiver rejects a report for its size. State that the
backfill does not apply the license's insights history limit.
The first commit on this branch also removed a link to a spec file
that does not exist.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
getDailyDataStart() no longer limits the weekly lookup to rows older
than the oldest hourly or daily row. That bound assumed that
compaction always leaves every weekly row older than every daily
row. An hourly row older than a weekly row hid that weekly row, so
the backfill read days whose totals sit in a weekly row.
The two reads no longer depend on each other, so they now run in
parallel.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Instance reports now read their daily totals with a new
InsightsService.getDailyExecutionTotals() method. It always buckets
by UTC day, for any range length.
Before, the backfill read insights in chunks of 30 days through
getInsightsByTime(). That method picks the bucket size from the range
length in the server's local time zone. A 30-day chunk that crossed a
DST change was bucketed by week, which put a whole week's total on one
day. Each chunk also read one extra day.
The read is instance-wide, so the owner lookup and OwnershipService
are no longer needed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The first report now carries every day with exact insights data,
not only yesterday. Skipped reports no longer lose days, and gaps
longer than 30 days are recovered. Insights is read in 30-day chunks
so that every day keeps its own value.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>