Skip to content

feat: cross-machine usage aggregation with device-level dedup#252

Open
Yeachan-Heo wants to merge 1 commit intojunhoyeo:mainfrom
Yeachan-Heo:feat/cross-machine-client-aggregation
Open

feat: cross-machine usage aggregation with device-level dedup#252
Yeachan-Heo wants to merge 1 commit intojunhoyeo:mainfrom
Yeachan-Heo:feat/cross-machine-client-aggregation

Conversation

@Yeachan-Heo
Copy link
Copy Markdown
Contributor

@Yeachan-Heo Yeachan-Heo commented Feb 28, 2026

Summary

  • Ports the device-level deduplication logic from PR feat: cross-machine usage aggregation + automatic sync #55 (feat/cross-machine-aggregation-sync) into the current client-based codebase structure
  • Each client (e.g., "claude", "cursor") now tracks per-device contributions via a devices field keyed by API token ID
  • On resubmit from the same device, only that device's data is replaced — other devices' data is preserved, preventing double-counting
  • Legacy data (without device tracking) is gracefully migrated to a __legacy__ device key on first merge
  • Client-level totals and model breakdowns are recalculated from the sum of all devices

Changes

  • helpers.ts: Added DeviceClientData interface, devices? field on ClientBreakdownData, recalculateClientAggregate helper, and updated mergeClientBreakdowns to accept deviceId and perform device-level merge with legacy migration
  • route.ts: INSERT path now initializes devices[tokenId] from the start; UPDATE path passes tokenRecord.tokenId to the merge function
  • schema.ts: Added devices? to the sourceBreakdown JSONB type definition
  • submit.test.ts: Added 8 new tests covering device-level dedup scenarios (resubmit, multi-device aggregation, legacy migration, device removal, cross-device model aggregation, multi-client multi-device)

Test plan

  • All 28 tests pass (20 existing + 8 new device-level dedup tests)
  • No TypeScript errors in modified files
  • Manual verification: submit from device A, submit from device B, verify totals = A + B
  • Manual verification: resubmit from device A with updated data, verify totals = A' + B (not A + A' + B)
  • Verify backward compatibility with existing data (no devices field) — should auto-migrate to __legacy__

🤖 Generated with Claude Code


Summary by cubic

Add per-device usage tracking and dedup to client aggregation to support cross‑machine submissions. Resubmits now replace only that device’s data, preventing double counting and keeping totals accurate.

  • New Features
    • Track per-device contributions in client breakdowns via devices[tokenId]; mergeClientBreakdowns now replaces only the submitting device and recalculates aggregates.
    • POST /api/submit initializes devices[tokenId] on insert and passes tokenId on update to avoid legacy paths and resubmit inflation.
    • Legacy data auto-migrates to a legacy device on first merge; client totals and model breakdowns are rebuilt from device data.
    • Schema adds devices to sourceBreakdown; 8 tests cover resubmit, multi-device aggregation, legacy migration, device removal, and cross-device model sums.

Written for commit 556afd9. Summary will update on new commits.

Port device-level tracking from PR junhoyeo#55 into the client-based structure.
Each client now tracks per-device contributions (keyed by API token ID)
to prevent double-counting when the same user submits from multiple
machines. On resubmit, only the device's data is replaced while other
devices' data is preserved. Legacy data without device tracking is
gracefully migrated to a __legacy__ device key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Feb 28, 2026

@Yeachan-Heo is attempting to deploy a commit to the Inevitable Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/frontend/src/lib/db/helpers.ts">

<violation number="1" location="packages/frontend/src/lib/db/helpers.ts:222">
P2: Legacy incoming payloads that only provide modelId (no models) will drop model-level attribution after recalculation because device contributions only copy incomingClient.models. recalculateClientAggregate rebuilds client.models exclusively from device.models, so legacy modelId data is lost.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

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.

2 participants