Repository navigation
feat: ingest idempotency key and content dedup (#15) - #43
Conversation
Honor Idempotency-Key on POST /v1/ingestions so retries reuse the original job, and upsert log rows on (scope, source_ref, original_line_hash, timestamp) so re-reads do not inflate clusters. Closes #15 Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Code review — PR #43 (issue #15)CI is green. Checked against issue #15 / G6: must-fixNone should-fix
nice-to-have
Verdictmust-fix count: 0 |
Always merge principal scope onto ingest payloads so dedup is per-key even without callback_url. Replay tests assign a fresh UUID per WorkerJob and compare the two responses. Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
Code review — PR #43 (issue #15), round 2Follow-up Previous should-fix status
must-fixNone should-fixNone nice-to-haveNone Verdictmust-fix count: 0 |
Closes #15.
Two layers so retries do not double-count clusters:
Request idempotency
Idempotency-KeyonPOST /v1/ingestionsand the unversioned alias (batch enqueue and tail create). A repeat withinINGEST_IDEMPOTENCY_TTL_SECONDS(default 86400) returns the original 202 and the same job id. Empty or oversized keys → 400. Expired keys start a new job.Content dedup
Each new log row stores
original_line_hash(SHA-256 of the raw line, distinct from the fingerprint) andscope(API key scope, else"default"). Missingsource_refis stored as"". Partial unique indexux_log_entries_dedupon(scope, source_ref, original_line_hash, timestamp). Persist usesINSERT … ON CONFLICT DO NOTHING; duplicates are skipped, not errors. Embeddings are written only for inserted rows.Applies to file ingest, adapter ingest (including tail ticks), and push lines.
Schema
Alembic
0007_ingest_idempotency. Applied 0001–0006 are untouched. Query isolation by scope remains G8.Tests
Unit tests cover hashing, ON CONFLICT flush, Idempotency-Key replay/expiry, and OpenAPI header docs. A skip-gated integration test asserts re-ingest of identical lines keeps row count at 1 when Postgres is available.