[PR #278] [MERGED] fix: dedupe download metrics hourly by user-or-ip identity #309

Closed
opened 2026-02-15 17:16:48 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/openclaw/clawhub/pull/278
Author: @steipete
Created: 2/13/2026
Status: Merged
Merged: 2/13/2026
Merged by: @steipete

Base: mainHead: fix/download-hourly-identity-dedupe


📝 Commits (1)

  • df472b3 fix: dedupe download metrics hourly by user-or-ip identity

📊 Changes

6 files changed (+182 additions, -32 deletions)

View changed files

📝 convex/downloads.test.ts (+38 -7)
📝 convex/downloads.ts (+34 -21)
convex/lib/apiTokenAuth.test.ts (+85 -0)
📝 convex/lib/apiTokenAuth.ts (+20 -0)
📝 convex/schema.ts (+4 -4)
📝 docs/http-api.md (+1 -0)

📄 Description

Summary

  • count download stats as unique identities per hour instead of per day
  • prefer API-token user identity for dedupe keys, then fall back to IP when anonymous
  • keep metric path best-effort and prune dedupe rows after 7 days
  • add regression tests for hourly bucket/identity selection and optional token-user lookup
  • document /api/v1/download counting semantics

Verification

  • bun run lint
  • bun run test
  • bun run build

Greptile Overview

Greptile Summary

This PR changes download metric deduplication from per-day/per-IP to per-hour using an identity key that prefers an authenticated API-token user and falls back to client IP for anonymous callers. It updates the downloadDedupes schema and pruning logic (7-day retention), adds unit tests for hour bucketing and identity selection, adds tests for optional API token user lookup, and documents the new /api/v1/download counting semantics.

The implementation fits into the existing Convex HTTP download flow by computing an identity (token user id or IP) in convex/downloads.ts, hashing it, and using an indexed downloadDedupes lookup to enforce uniqueness per hour before emitting a skillStatEvent.

Confidence Score: 4/5

  • This PR is largely safe to merge, but has a behavioral regression in API token usage tracking for download requests.
  • Core schema/index updates and dedupe logic look consistent, tests cover the new bucketing/identity behavior, and the metric path remains best-effort. The main issue is that optional token auth used for downloads does not update lastUsedAt, which is a real behavioral change compared to other token-authenticated endpoints.
  • convex/lib/apiTokenAuth.ts

Last reviewed commit: df472b3

Context used:

  • Context from dashboard - AGENTS.md (source)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/openclaw/clawhub/pull/278 **Author:** [@steipete](https://github.com/steipete) **Created:** 2/13/2026 **Status:** ✅ Merged **Merged:** 2/13/2026 **Merged by:** [@steipete](https://github.com/steipete) **Base:** `main` ← **Head:** `fix/download-hourly-identity-dedupe` --- ### 📝 Commits (1) - [`df472b3`](https://github.com/openclaw/clawhub/commit/df472b3fe4ed60a1b8d42144f8a8d919083c431b) fix: dedupe download metrics hourly by user-or-ip identity ### 📊 Changes **6 files changed** (+182 additions, -32 deletions) <details> <summary>View changed files</summary> 📝 `convex/downloads.test.ts` (+38 -7) 📝 `convex/downloads.ts` (+34 -21) ➕ `convex/lib/apiTokenAuth.test.ts` (+85 -0) 📝 `convex/lib/apiTokenAuth.ts` (+20 -0) 📝 `convex/schema.ts` (+4 -4) 📝 `docs/http-api.md` (+1 -0) </details> ### 📄 Description ## Summary - count download stats as unique identities per hour instead of per day - prefer API-token user identity for dedupe keys, then fall back to IP when anonymous - keep metric path best-effort and prune dedupe rows after 7 days - add regression tests for hourly bucket/identity selection and optional token-user lookup - document `/api/v1/download` counting semantics ## Verification - bun run lint - bun run test - bun run build <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR changes download metric deduplication from per-day/per-IP to per-hour using an identity key that prefers an authenticated API-token user and falls back to client IP for anonymous callers. It updates the `downloadDedupes` schema and pruning logic (7-day retention), adds unit tests for hour bucketing and identity selection, adds tests for optional API token user lookup, and documents the new `/api/v1/download` counting semantics. The implementation fits into the existing Convex HTTP download flow by computing an identity (token user id or IP) in `convex/downloads.ts`, hashing it, and using an indexed `downloadDedupes` lookup to enforce uniqueness per hour before emitting a `skillStatEvent`. <h3>Confidence Score: 4/5</h3> - This PR is largely safe to merge, but has a behavioral regression in API token usage tracking for download requests. - Core schema/index updates and dedupe logic look consistent, tests cover the new bucketing/identity behavior, and the metric path remains best-effort. The main issue is that optional token auth used for downloads does not update `lastUsedAt`, which is a real behavioral change compared to other token-authenticated endpoints. - convex/lib/apiTokenAuth.ts <sub>Last reviewed commit: df472b3</sub> <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=a1d58d20-b4dd-4cbb-973a-9fd7824e1921)) <!-- /greptile_comment --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 17:16:48 -05:00
yindo closed this issue 2026-02-15 17:16:48 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: openclaw/clawhub#309