Skip to content

AUTH-GUEST-MIGRATE-001: Safe guest-to-wallet identity migration #55

Description

@jamalfrnk

Problem

AUTH-GUEST-001 (issue #33) deliberately deferred guest-to-wallet migration -- when a guest connects a wallet, their practice history (orders/positions/risk limits/analytics) currently stays under the guest identity rather than merging into the newly-connected wallet identity. This issue tracks doing that migration safely.

Repository evidence

server/src/auth/users.ts's createGuestUser() and findOrCreateUser() are currently independent paths with no migration/merge logic between them. users.kind ('wallet' | 'guest') distinguishes the two but nothing transitions a row from one to the other.

Risk

P2 -- valuable for guest retention/conversion, not release-blocking. The real risk this issue exists to manage is data-integrity: an unsafe migration could duplicate orders, double-count P&L, or merge two unrelated accounts' data.

Scope

  • Design and implement a transactional migration: when an authenticated guest connects and verifies a wallet, move (not copy) their orders/fills/positions/risk_limits rows to the wallet's users.id, then either delete or permanently mark the guest row as migrated (never leave it independently usable again).
  • Must be idempotent -- retrying a partially-failed migration must not duplicate rows.
  • Must handle the case where the connecting wallet already has its own existing history (decide and document: reject the migration, or merge -- merging two non-empty histories is a real design decision, not a default).
  • Add explicit tests for: successful migration, retry-after-partial-failure, migration-target-already-has-history, concurrent migration attempts (two requests racing to migrate the same guest).

Non-goals

  • Not migrating guest identities between two different guest sessions.
  • Not building a UI flow beyond what's needed to trigger the migration (e.g. a "Save your progress" prompt) -- that can be minimal.

Dependencies

AUTH-GUEST-001 (issue #33) and WALLET-001 (issue #32), both must be merged first.

Proposed implementation

A single DB transaction reassigning userId foreign keys across orders/fills/positions/risk_limits/any analytics tables, gated by an explicit confirmation step, with the guest row itself marked non-reusable afterward (e.g. a migratedTo column or immediate deletion once confirmed safe).

Acceptance criteria

A guest with real paper-trading history who then connects and verifies a wallet ends up with that same history now owned by the wallet identity, verified by direct DB/API inspection; no duplicate rows; the old guest session can no longer be used to access the migrated data.

Definition of done

Server tests cover every scenario in Scope above; reviewer PASS with explicit sign-off on the transactional-safety properties (idempotency, no duplication, no cross-account bleed).

Test plan

Migration success, idempotent retry, existing-history-on-target-wallet, concurrent-migration race, guest row becomes unusable post-migration.

Security review

This is the highest-risk part of the whole guest-session feature -- ownership/ID reassignment logic needs the same rigor as the existing cross-user ownership tests in paperEngine.test.ts, and then some (a bug here doesn't just leak data across users, it could silently corrupt financial history).

Accessibility review

Whatever UI trigger is added should be keyboard-accessible and clearly worded (this is an irreversible action once confirmed).

Observability requirements

Log every migration attempt/success/failure with both user IDs involved (never log wallet signatures or session tokens).

Performance considerations

Should be a single transaction, not N sequential round-trips per row type.

Rollback plan

Since this can move real (paper) trading history, a failed/rolled-back migration must leave the guest identity's data fully intact and usable, not partially moved.

Documentation requirements

Extend docs/architecture/wallet-and-identity.md's guest-session section.

Completion evidence

(added on merge)

Reviewer verdict

(pending)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Valuable hardening, scalability, or developer-experience workepic:securitySecurity and privacyepic:walletWallet connectivity and identity

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions