Skip to content

fix(sketch-db): POST /api/v1/db/backfill uses create_checked (§10.5) - #43

Merged
zzylol merged 1 commit into
mainfrom
fix/backfill-create-checked
Apr 20, 2026
Merged

zzylol merged 1 commit into
mainfrom
fix/backfill-create-checked

Conversation

@zzylol

@zzylol zzylol commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Summary

The HTTP endpoint POST /api/v1/db/backfill was calling BackfillRegistry::create() — the unchecked path. PR #40 added create_checked() as the authoritative entry point with three §10.5 invariants (known agg, time-disjoint, within-retention), but the HTTP surface kept routing through create(). So controllers could file jobs against unknown agg_ids or time ranges that overlap live ingest / fall outside the SimpleMapStore retention horizon, and the worker would either fail later or silently waste I/O on soon-to-be-evicted windows.

What's in this PR

  • handle_post_backfill_job now requires both the backfill registry and the schema registry (503 on either missing), calls create_checked(&schemas, ..., data_retention_ms), and maps CreateError to distinct HTTP statuses:
    • UnknownAgg404
    • Overlap / OutOfRetention409
    • success → 201 (unchanged)
    • malformed body / inverted range → 400 (unchanged)
  • HttpServer::with_data_retention_ms(u64) threads the SimpleMapStore data-retention horizon into AppState, so Method B can reject stale ranges at create time. main.rs wires it from --persistence-delete-older-than-secs when > 0 (unset → retention precheck skipped, remaining two invariants still enforced).
  • Test helper renamed setup_test_server_with_backfill_and_schemas, takes &[u64] of agg_ids to pre-register as Active. Four existing backfill tests updated.

Why

e2e on the precompute stack (the one that caught #42) showed that the HTTP endpoint accepted a job against a known agg with end_ms > created_at_ms — a clear §10.5 overlap — and returned 201 Created. With this PR it now returns 409 Conflict, matching the invariant the design doc already describes.

Test plan

  • cargo test -p query_engine_rust --lib725 pass (was 723; +2 new tests)
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • New tests:
    • test_backfill_post_unknown_agg_returns_404
    • test_backfill_post_overlap_with_live_ingest_returns_409

🤖 Generated with Claude Code

The HTTP handler was calling `BackfillRegistry::create()`, which
skips every invariant. PR #40 added `create_checked()` — the same
entry point the `BackfillService` uses — but the HTTP surface
kept the unchecked path, so controllers could file jobs against
unknown agg_ids or time ranges that overlap live ingest / fall
outside retention, and the worker would only discover the
mistake later (or silently waste I/O on soon-to-be-evicted
windows).

Changes:
- `handle_post_backfill_job` now requires both the backfill
  registry AND the schema registry (503 if either is absent),
  calls `create_checked(&schemas, ..., data_retention_ms)`, and
  maps `CreateError` to distinct HTTP statuses: 404 for
  `UnknownAgg`, 409 for `Overlap` / `OutOfRetention`, 201 on
  success. 400 on malformed body / inverted range is preserved.
- `HttpServer::with_data_retention_ms(u64)` threads the SimpleMapStore
  data-retention horizon into AppState so Method B rejects stale
  ranges at create time. `main.rs` wires it from
  `--persistence-delete-older-than-secs` when > 0.
- Test helper renamed `setup_test_server_with_backfill_and_schemas`
  and now takes an `&[u64]` of agg_ids to pre-register as Active.
  All four existing backfill tests updated.
- Two new tests exercise the new error paths:
  `test_backfill_post_unknown_agg_returns_404` and
  `test_backfill_post_overlap_with_live_ingest_returns_409`.

725 lib tests pass (was 723), clippy clean, fmt clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit 4590405 into main Apr 20, 2026
@zzylol
zzylol deleted the fix/backfill-create-checked branch April 20, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant