Skip to content

Conversation

@Vishal27alpha
Copy link

Description

What

Adds a new practice typing mode that allows users to type freely without affecting:

  • personal bests
  • XP
  • leaderboards
  • result history

Why

This enables low-pressure practice sessions while preserving competitive integrity of stats.

How

  • Extended shared schemas to include practice mode
  • Backend ignores practice results for persistence, XP, PB, and leaderboards
  • Frontend hides practice mode from result filters

Notes

  • API response shape remains unchanged
  • No database or contract changes required

Relevant files:

  • packages/schemas/src/shared.ts
  • backend/src/api/controllers/result.ts
  • frontend/src/ts/constants/default-result-filters.ts

Copilot AI review requested due to automatic review settings February 8, 2026 10:13
@monkeytypegeorge monkeytypegeorge added backend Server stuff frontend User interface or web stuff packages Changes in local packages labels Feb 8, 2026
@github-actions github-actions bot added the waiting for review Pull requests that require a review before continuing label Feb 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

Continuous integration check(s) failed. Please review the failing check's logs and make the necessary changes.

@github-actions github-actions bot added waiting for update Pull requests or issues that require changes/comments before continuing and removed waiting for review Pull requests that require a review before continuing labels Feb 8, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new practice typing mode intended for “no-stats” sessions, wiring it through shared mode schemas, backend result submission, and default frontend result filters.

Changes:

  • Extend shared mode/schema typing to include practice.
  • Backend: special-case practice in result submission (skip PB checks, skip DB insert, XP=0).
  • Frontend: default result filters mark practice as excluded.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
packages/schemas/src/shared.ts Adds practice to the modes derived from PersonalBestsSchema.
backend/src/api/controllers/result.ts Adds practice handling in result endpoints and XP calculation.
frontend/src/ts/constants/default-result-filters.ts Excludes practice from default stats/result filtering.

zen: z.record(z.literal("zen"), z.array(PersonalBestSchema)),

// practice mode: intentionally empty, never tracked
practice: z.never(),
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

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

practice: z.never() makes PersonalBestsSchema impossible to satisfy (key becomes required but can never validate), so parsing existing user/tag PB objects will start failing. Make the key optional while still adding it to ModeSchema (eg z.never().optional()), or model it as optional/undefined and keep PB storage unchanged.

Suggested change
practice: z.never(),
practice: z.never().optional(),

Copilot uses AI. Check for mistakes.
Comment on lines +216 to +217
const isPractice = completedEvent.mode === "practice";

Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

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

isPractice currently only skips PB checks + DB insert, but practice is supposed to not affect stats/leaderboards. Later in this handler you still update typing stats (updateTypingStats/PublicDAL.updateStats), streak, testActivity, and potentially daily leaderboards (if config rules match practice). Wrap those side effects in if (!isPractice) too (or early-return with a practice-specific response) to match the mode contract.

Copilot uses AI. Check for mistakes.
Comment on lines 668 to 670
const data: PostResultResponse = {
insertedId: insertedId ?? "practice",
isPb,
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

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

Returning insertedId: "practice" will be treated as a real result id by the frontend (it sets edit-tags data-result-id and saves a snapshot with _id = insertedId), leading to broken tag editing / local history for practice runs. Either persist a real result id (and exclude it from stats/history), or change the response/consumer so practice runs don’t provide/use an id.

Copilot uses AI. Check for mistakes.
Comment on lines +216 to +217
const isPractice = completedEvent.mode === "practice";

Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

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

Add/extend controller tests for mode: "practice" to assert no persistence and no stat updates (eg ResultDAL.addResult, UserDAL.updateTypingStats, PublicDAL.updateStats, UserDAL.updateStreak, incrementTestActivity, daily leaderboard). Current tests already mock these calls for normal modes, so adding a practice case should be straightforward.

Copilot uses AI. Check for mistakes.
@fehmer
Copy link
Member

fehmer commented Feb 8, 2026

You can already turn off result saving in the comand line result saving off.

@Vishal27alpha Vishal27alpha changed the title feat: add practice typing mode (no stats, xp, or pb) feat: add practice typing mode (no stats, xp, or pb) (@Vishal27alpha) Feb 8, 2026
@github-actions github-actions bot removed the waiting for update Pull requests or issues that require changes/comments before continuing label Feb 8, 2026
@Vishal27alpha
Copy link
Author

Thanks for pointing that out, I wasn’t aware this already existed via the command line.

That explains the gap I felt from a user perspective. Would you be open to reframing this PR to focus on exposing the existing practice mode in the UI (making it more discoverable), rather than adding new backend behavior?

Happy to adjust or close the PR based on your preference.

@Miodec
Copy link
Member

Miodec commented Feb 8, 2026

Thanks for pointing that out, I wasn’t aware this already existed via the command line.

That explains the gap I felt from a user perspective. Would you be open to reframing this PR to focus on exposing the existing practice mode in the UI (making it more discoverable), rather than adding new backend behavior?

Happy to adjust or close the PR based on your preference.

Lets add a "result saving" settin to the account section in the settings page. In the description mention the word 'practice' so its easier to find. We should also add a 'practice' alias to the result saving commandline commands.

@Vishal27alpha
Copy link
Author

Thanks a lot for the clarification that makes perfect sense.
I’m happy to try reworking this PR in that direction:

-Add a “Result saving” toggle in the Account section of Settings
-Explicitly mention practice in the UI copy for better discoverability
-Add practice as an alias to the existing command-line commands

I’ll start exploring this and update the PR accordingly, unless you’d prefer this to be handled as a separate PR instead.

@Miodec
Copy link
Member

Miodec commented Feb 8, 2026

Thanks a lot for the clarification that makes perfect sense. I’m happy to try reworking this PR in that direction:

-Add a “Result saving” toggle in the Account section of Settings -Explicitly mention practice in the UI copy for better discoverability -Add practice as an alias to the existing command-line commands

I’ll start exploring this and update the PR accordingly, unless you’d prefer this to be handled as a separate PR instead.

Same pr is fine

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

Labels

backend Server stuff frontend User interface or web stuff packages Changes in local packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants