Skip to content

fix(submit): preserve source-scoped multi-machine submissions#388

Open
IvGolovach wants to merge 3 commits intojunhoyeo:mainfrom
IvGolovach:fix/source-scoped-submissions
Open

fix(submit): preserve source-scoped multi-machine submissions#388
IvGolovach wants to merge 3 commits intojunhoyeo:mainfrom
IvGolovach:fix/source-scoped-submissions

Conversation

@IvGolovach
Copy link
Copy Markdown
Contributor

@IvGolovach IvGolovach commented Apr 1, 2026

Summary

  • preserve usage from multiple machines by storing submissions per source instead of collapsing all submits into a single row per user
  • upgrade the first source-aware submit from a legacy account in place to avoid duplicate totals during cutover
  • aggregate profile, embed, and leaderboard reads across all submission rows for the same user

Why

Tokscale currently stores a single submission row per user. That means a later submit from another machine can overwrite usage for the same client instead of aggregating it, which breaks profiles, leaderboard totals, and public stats for users who submit from more than one device.

Diff scope

  • add sourceId and sourceName to submit payload validation and CLI submission metadata
  • add source-scoped submission storage with additive migration 0005_tan_rumiko_fujikawa
  • upgrade the existing unsourced row in place on the first source-aware submit to avoid legacy duplication
  • reject ambiguous unsourced submits with 409 once a user has entered source-scoped mode
  • aggregate profile, embed, and leaderboard reads across all submission rows
  • add regression tests for scope resolution, profile/embed aggregation, and auth/submit edge cases

Test proof

  • cargo test -p tokscale-cli
    • unit tests: 314 passed, 0 failed, 1 ignored
    • integration tests: 74 passed, 0 failed
  • cargo clippy -p tokscale-cli --all-features -- -D warnings
    • passed
  • bun x vitest run __tests__/api/*.test.ts __tests__/lib/*.test.ts
    • 17 files, 123 tests passed
  • cargo fmt --all --check
    • passed
  • git diff --check
    • passed

Migration notes

  • adds migration 0005_tan_rumiko_fujikawa
  • additive schema change: introduces source_id and source_name plus source-scoped uniqueness
  • legacy single-row accounts are upgraded in place on the first source-aware submit
  • no destructive backfill is required up front

Rollback plan

  • if merged with a merge commit: git revert <merge_commit_sha>
  • if merged as a squash commit: git revert <squash_commit_sha>
  • rollback would require a follow-up schema migration before removing the new columns or indexes in production

Known residual risks

  • older clients that continue submitting without source identity will receive 409 after the account has entered source-scoped mode
  • this PR does not add a new UI for managing or renaming sources beyond the submitted sourceName

Closes

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 1, 2026

@IvGolovach 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.

4 issues found across 18 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/app/api/users/[username]/route.ts">

<violation number="1" location="packages/frontend/src/app/api/users/[username]/route.ts:68">
P2: Selecting latest submission metadata with only `updatedAt` ordering is nondeterministic on timestamp ties, so `cliVersion`/`schemaVersion` and freshness metadata can vary across requests.</violation>
</file>

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

<violation number="1" location="packages/frontend/src/lib/db/helpers.ts:89">
P2: Unsourced submissions are still accepted for mixed-state accounts because the unsourced-row return happens before the missing-source rejection, so `rejectMissingSourceIdentity` never triggers when an unsourced row exists alongside scoped rows.</violation>
</file>

<file name="packages/frontend/src/lib/db/migrations/0005_tan_rumiko_fujikawa.sql">

<violation number="1" location="packages/frontend/src/lib/db/migrations/0005_tan_rumiko_fujikawa.sql:5">
P1: Migration builds multiple indexes on `submissions` non-concurrently, which can block writes during deploy and cause ingestion downtime.</violation>
</file>

<file name="packages/frontend/src/app/api/submit/route.ts">

<violation number="1" location="packages/frontend/src/app/api/submit/route.ts:263">
P2: `isNewSubmission` remains true on insert-conflict fallback, causing incorrect `mode: "create"` responses for merged submissions.</violation>
</file>

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

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.

2 issues found across 11 files (changes from recent commits).

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/__tests__/api/submitAuth.test.ts">

<violation number="1" location="packages/frontend/__tests__/api/submitAuth.test.ts:361">
P2: The regression test labeled as a fallback/merge test bypasses the transaction callback by resolving `db.transaction` directly, so it never executes the actual fallback/conflict logic it claims to validate. This can let real regressions in the fallback path slip through.</violation>
</file>

<file name="packages/frontend/src/lib/db/migrations/0005_conscious_cargill.sql">

<violation number="1" location="packages/frontend/src/lib/db/migrations/0005_conscious_cargill.sql:5">
P1: Migration uses PostgreSQL version-sensitive `UNIQUE NULLS NOT DISTINCT`, which can fail on older Postgres deployments.</violation>
</file>

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

junhoyeo added a commit that referenced this pull request Apr 1, 2026
…ests

Constraint: Keep the cherry-picked PR #388 snapshot lint-clean under this repo's frontend ESLint rules
Rejected: Leave the original variable name | fails @next/next/no-assign-module-variable in local lint
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep this as a tiny follow-up on top of the original authored commits; do not fold broader changes into the credit-preserving rewrite
Tested: packages/frontend/node_modules/.bin/eslint --config packages/frontend/eslint.config.mjs packages/frontend/__tests__/lib/getUserEmbedStats.test.ts
Not-tested: Full frontend verification matrix (history rewrite only; behavior unchanged from prior verified branch)
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