> For the complete documentation index, see [llms.txt](https://suigar.gitbook.io/suigar-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://suigar.gitbook.io/suigar-docs/game-onboarding/refactor-roadmap.md).

# Refactor roadmap

## Goal

Increase clarity, predictability, and maintainability across the frontend and backend without changing behavior.

This roadmap is intentionally biased toward:

* smaller modules with one clear reason to change
* pure decision logic extracted away from I/O orchestration
* stable naming and folder patterns
* no hidden transport or domain rules buried in page components or services
* systematic tests around extracted pure modules before deeper rewrites

## Non-goals

* no product behavior changes
* no visual redesign
* no schema rewrites unless needed for clarity later
* no transport migration just for style

## Pain Map

### Frontend

1. `frontend/src/features/auth/hooks/useWalletTransaction.ts` Too many responsibilities: sponsorship policy, direct zkLogin prep, retries, signing, execution, cache invalidation, perf logging, E2E hooks, session recovery.
2. Game page controller hooks Files:

   * `frontend/src/features/games/pvp-coinflip/use-pvp-coinflip-page.ts`
   * `frontend/src/features/games/range/use-range-page.ts`
   * `frontend/src/features/games/limbo/use-limbo-page.ts`
   * `frontend/src/features/games/wheel/use-wheel-page.ts`
   * `frontend/src/features/games/plinko/use-plinko-page.ts`
   * `frontend/src/features/games/coinflip/use-coinflip-page.ts`

   Repeated patterns exist for reveal lifecycle, prewarm, optimistic preview balance, cooldowns, animation handoff, and button gating.
3. Large page components Files:

   * `frontend/src/features/referral/page/referral-page.tsx`
   * `frontend/src/features/account/page/account-page.tsx`
   * `frontend/src/components/deposit-dialog.tsx`
   * `frontend/src/components/side-menu.tsx`

   These mix layout, state orchestration, query wiring, formatting, and feature policy.

### Backend

1. `backend/src/app/domains/giveaway/giveaway-campaign.service.ts` One service currently owns campaign CRUD, chain planning, chain settlement, eligibility rules, ticket math, winner selection, payout orchestration, and SuiNS resolution.
2. `backend/src/app/domains/analytics/stats.service.ts` Large query and aggregation surface with many unrelated reporting concerns.
3. `backend/src/app/domains/user/user.service.ts` Mixed responsibilities across account lifecycle, projections, and policy checks.
4. Indexer handlers Files under `backend/src/indexer/handlers` Repeated event-mapping and write orchestration patterns are still too bespoke.

## Target Patterns

### Frontend

* One controller hook per feature page.
* Controller hooks orchestrate only.
* Pure rules, transport policies, cache keys, and formatters live in sibling `*.ts` modules.
* Shared game lifecycle logic must live under `frontend/src/features/games/core`.
* Page components should mostly compose sections and pass props.
* New feature modules should prefer this shape:
  * `page.tsx`
  * `use-<feature>-page.ts`
  * `<feature>-queries.ts`
  * `<feature>-formatters.ts`
  * `<feature>-policy.ts`
  * `<feature>-types.ts`

### Backend

* Domain services orchestrate only.
* Pure rules go into `*-policy.ts` or `*-eligibility.ts`.
* Query shaping goes into `*-queries.ts` when SQL starts dominating a service.
* Chain transaction planning goes into `*-chain.ts`.
* External identity resolution like SuiNS gets isolated from campaign orchestration.
* Indexer handlers should follow: parse -> normalize -> write via shared write helpers.

## Phase Plan

### Phase 1: Extract Pure Logic From Hotspots

Frontend:

* split `useWalletTransaction` into shared state/policy helpers, cache helpers, and execution strategy helpers
* keep hook order stable and minimize module-local hidden state

Backend:

* extract giveaway eligibility math, ticket computation, and reward/draw helpers into pure modules

Exit criteria:

* no behavior change
* typecheck green
* focused regression tests on extracted pure modules

### Phase 2: Normalize Gameplay Controller Architecture

* define one shared contract for game button gating
* define one shared contract for reveal lifecycle completion
* define one shared contract for balance preview freeze/thaw
* reduce per-game hook differences to game-specific math and animations

Exit criteria:

* each game page hook becomes mostly declarative wiring
* shared game lifecycle modules own the suspense mechanics

### Phase 3: Break Up Oversized Frontend Pages

* referral page
* account page
* deposit dialog
* side menu

Approach:

* extract read models
* extract section components
* extract action handlers and mutations
* extract copy/formatting helpers

Exit criteria:

* page files become layout/composition shells
* feature rules stop living inside JSX files

### Phase 4: Split Backend Domain Services

* `giveaway-campaign.service.ts`
* `stats.service.ts`
* `user.service.ts`

Approach:

* separate query modules
* separate policy modules
* separate chain interaction modules
* preserve controller and DI surface first, then reduce service size internally

Exit criteria:

* no service should mix pure rule evaluation, SQL construction, and remote-chain orchestration in the same section

### Phase 5: Indexer Normalization

* standardize mapper naming
* standardize idempotent write flow
* standardize event identity derivation
* isolate query-side helpers from event handling

## Working Rules

* Refactors must move logic behind clearer names before changing any behavior.
* Every extracted pure module gets either direct tests or indirect service coverage in the same tranche.
* Avoid giant “big bang” rewrites.
* Prefer reversible slices that keep public call sites stable.
* When a file exceeds roughly 600-800 lines and mixes multiple concerns, default to extraction.

## First Tranche

Current tranche:

* Frontend: extract shared wallet transaction constants, policy state, cache generation, and transport helpers out of `useWalletTransaction.ts`
* Backend: extract giveaway eligibility evaluation and ticket math out of `giveaway-campaign.service.ts`
* Frontend: normalize the shared game action availability contract used by the main game page hooks
* Frontend: extract prepared transaction cache eviction/read rules out of `useWalletTransaction.ts`

Why this first:

* both areas carry high churn and hidden rules
* both areas are reused widely
* both benefit from pure-module tests before deeper decomposition

## Progress

Completed in the current tranche:

* `frontend/src/features/auth/utils/wallet-transaction-shared.ts` Shared wallet transaction constants, perf helpers, sponsorship policy cache state, circuit helpers, and cache generation are now outside the hook.
* `frontend/src/features/auth/utils/prepared-transaction-cache-store.ts` Prepared sponsor/direct transaction cache eviction, ready-read, and discard rules are now isolated and directly testable.
* `frontend/src/features/games/core/game-action-availability.ts` The main single-player game pages now share one explicit action-readiness contract instead of repeating ad hoc `isTransactionPrimed && !isPrimingTransaction` formulas.
* `frontend/src/features/games/core/use-standard-game-transaction.ts` Coinflip, Plinko, Limbo, Range, Wheel, and Soccer now share one transaction lifecycle boundary for pending state, login gating, sponsored prewarm, prepared-transaction claiming, and click-time readiness. Within this lifecycle, game hooks retain only their transaction arguments, response parsing, game math, and reveal choreography.
* `backend/src/app/domains/giveaway/giveaway-campaign-eligibility.ts` Giveaway eligibility, ticket math, and bonus multiplier logic are separated from service orchestration.
* `backend/src/app/domains/giveaway/giveaway-campaign-draw.ts` Giveaway winner selection and seeded draw behavior are separated from service orchestration.

Guardrail tests added in the same tranche:

* `frontend/src/features/auth/utils/prepared-transaction-cache-store.test.ts`
* `frontend/src/features/games/core/game-action-availability.test.ts`
* `frontend/src/features/games/core/use-standard-game-transaction.test.tsx`
* `backend/test/giveaway-campaign-eligibility.spec.ts`
* `backend/test/giveaway-campaign-draw.spec.ts`

Next target after this tranche:

* split execution strategy selection and sponsorship/direct-prep orchestration further out of `useWalletTransaction.ts`
* move repeated round-result parsing and reveal completion contracts behind the standard game transaction boundary
