feat: cross-machine usage aggregation + automatic sync#55
feat: cross-machine usage aggregation + automatic sync#55Yeachan-Heo wants to merge 14 commits intojunhoyeo:mainfrom
Conversation
…e aggregation - Add DeviceSourceData interface for per-device contribution tracking - Add devices field to SourceBreakdownData type in helpers.ts and schema.ts - Modify mergeSourceBreakdowns() to accept deviceId parameter - Add recalculateSourceAggregate() helper to sum across devices - Migrate existing data without devices field to __legacy__ device - Update submit route to pass tokenRecord.tokenId as deviceId - Add tests for same-device replacement, cross-device aggregation, and legacy migration
- Add sync.ts with setupSync(), removeSync(), syncStatus() functions - Support crontab (macOS/Linux) and Task Scheduler (Windows) - Use process.argv[1] for CLI path resolution - Crontab entry uses --quiet flag for silent execution - Log output to ~/.config/tokscale/sync.log
…ron cleanup - Store devices[deviceId] on new day inserts to prevent double-counting when same device resubmits (was migrating to __legacy__ and adding) - Fix shell injection risk in crontab setup using printf with escaped quotes - Fix Windows Task Scheduler logging by wrapping in cmd.exe for redirections - Use specific grep pattern 'tokscale submit --quiet' to avoid removing unrelated cron jobs - Add tests for insert→resubmit flow to verify no double-counting
… direct tests
- Add ?? {} defensive defaults for models access in mergeSourceBreakdowns()
- Use TOKSCALE_SYNC_MANAGED marker for cron entries (prevents false matches)
- Windows sync now uses .cmd script file approach (simpler, no quoting issues)
- Add direct mergeSourceBreakdowns() function call tests for legacy data handling
…e, Windows cmd wrapper
…pe coercion - Legacy migration now uses '__legacy__' device instead of current deviceId - This preserves historical data separately from new device contributions - Added Number(...) || 0 for all arithmetic in recalculateSourceAggregate - Handles potential string values from JSON serialization - Updated tests to expect __legacy__ entry for legacy data migrations
- Reset aggregates before empty devices check to prevent stale values - Use Number() coercion in recalculateDayTotals for consistency
Convert all || 0 patterns to Number(...) || 0 to handle cases where values may be strings from JSON parsing or database retrieval.
|
@Yeachan-Heo is attempting to deploy a commit to the Inevitable Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
f906e18 to
6591b0e
Compare
|
Hey @Yeachan-Heo, thanks for opening a PR tackling two tasks. Appreciate the contribution despite the complexity! 🙌 One heads-up: the commits and PR body had the |
- Windows sync: Mark as experimental/disabled pending security review - bunx detection: Prevent sync setup from temp cache paths with clear error message - Crontab security: Add path validation to prevent injection via control chars - Legacy migration: Fix modelId→models conversion to preserve model breakdown Closes issues identified in PR junhoyeo#55 review.
🔧 Additional Fixes AppliedAddressed the security and stability issues identified in the review. Here's what was fixed: 1. Windows Sync → Experimental (Disabled)
2. bunx Temp Path Detection
3. Crontab Security
4. Legacy
|
| File | Changes |
|---|---|
packages/cli/src/sync.ts |
+148 lines (bunx detection, path validation, Windows experimental) |
packages/frontend/src/lib/db/helpers.ts |
+23 lines (modelId migration fix) |
packages/frontend/__tests__/api/submit.test.ts |
+53 lines (migration tests) |
Commit
5f932fc fix: address security and stability issues in cross-machine sync
All changes are surgical and independently verifiable. Ready for re-review! 🚀
|
@Yeachan-Heo fyi, I will hold this pr from merging before #64 -- there will be significant changes there! |
As of today, no users have the deprecated |
Resolved conflicts: - README.md: Keep main's structure (Overview before Contents), add Automatic Sync to TOC - cli.ts: Combine knownCommands to include both 'sync' and 'pricing' - submit.ts: Keep quiet flag feature with main's simplified structure
The submit command already has minimal necessary logs, and output is redirected to log file for cron jobs anyway. --no-spinner exists for scripts that need clean stdout.
|
@cubic-dev-ai review this pull request |
@junhoyeo I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
2 issues found across 7 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/cli/src/sync.ts">
<violation number="1" location="packages/cli/src/sync.ts:26">
P2: Variable `path` shadows the imported `path` module from `node:path`. This creates confusion and potential runtime errors if the function is later modified to use `path.join()` or similar methods. Rename to `cliPath` or `execPath`.</violation>
</file>
<file name="packages/cli/src/cli.ts">
<violation number="1" location="packages/cli/src/cli.ts:461">
P2: The new `--interval` flag is accepted but ignored: `setupSync` does not use the interval and the cron entry is hard-coded to hourly. Either implement interval handling or remove the flag to avoid misleading users.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
It looks like there haven’t been updates on this PR lately. Is it still active? |
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>
Summary
tokscale synccommands for hourly crontab automationProblem Solved
New Commands
Changes
devicesfield--quietflag totokscale submitfor cron compatibility~/.config/tokscale/sync.logdevices.__legacy__Testing