TypeShi
web-based typing performance application
Project metadata
Overview
A web-based typing performance application that helps users improve typing speed and accuracy. Built for CS 3354.009 (Software Engineering) at UT Dallas. Dark theme inspired by Monkeytype.
Features
- Timed typing tests with configurable durations (15, 30, 60, 120 seconds)
- Real-time visual feedback: correct characters highlight green, incorrect highlight red
- WPM and accuracy calculation
- Guest access, tests without an account or login
- User authentication via Auth0 (email/password or Google OAuth)
- Automatic result saving for authenticated users
- Profile dashboard: average WPM, best WPM, total tests taken, average accuracy
- Paginated test history with the ability to delete individual results
- Account management: editable username, password reset via Auth0
Architecture
Request flow
- User visits the Vercel URL, browser loads the React SPA
- Frontend fetches random words from /api/words (no auth required)
- User types; all keystroke logic runs locally in the browser with zero network calls
- Timer ends; WPM and accuracy calculated client-side
- If authenticated, frontend POSTs results to /api/tests with JWT in the Authorization header
- Backend middleware validates the JWT against Auth0's public keys (JWKS)
- Prisma inserts the test result into PostgreSQL
- Profile page fetches stats and history via two parallel GET requests
Authentication flow
- User clicks login; browser redirects to Auth0's Universal Login page
- User enters credentials on Auth0's domain; the app never sees the password
- Auth0 validates and issues a signed JWT (RS256)
- Browser redirects back to TypeShi with the token
- Frontend stores the token in memory, not localStorage
- Every authenticated API call includes the token as Authorization: Bearer <token>
- Backend validates the signature using Auth0's cached public keys
Project structure
20 source files total.
Database schema
users id (UUID, PK), auth0_id (unique, links to Auth0 account), email (unique), username (unique), created_at, updated_at
typing_tests id (UUID, PK), user_id (FK to users, cascade delete), wpm and accuracy (Decimal), duration (seconds), total_chars, correct_chars (Integer), created_at. Indexed on [user_id, created_at DESC] for fast history queries.
word_bank id (auto-increment), word (unique), ~200 common English words seeded on setup.
Scoring logic
Words Per Minute:
The standard "5 characters = 1 word" convention normalizes for varying word lengths. Only correctly typed characters count toward WPM (net WPM, not gross).
Accuracy:
Rounded to one decimal place. Defaults to 0 if no characters were typed.
Edge cases:
- Typing through all available text before the timer ends ends the test early; WPM uses actual elapsed time
- Backspace resets a character's status to "pending" and adjusts both correct and total counts
- Zero characters typed results in 0 WPM and 0% accuracy, with no division by zero
Requirements coverage
Satisfies all functional requirements R1–R10 from the project requirements document:
Full stack
React 18 · TypeScript · Vite · React Router 6 · Auth0 · Node.js 20 · Express · Zod · Prisma · PostgreSQL 16 · Helmet · CORS · Vercel · Render
Results
Source files | 20 | |
Deployed across 3 services (Vercel, Render, Render Postgres) | Yes | |
RS256 JWT validated against Auth0 JWKS | Yes | |
Composite index on `[user_id, created_at DESC]` | Yes | |
Functional requirements satisfied | R1–R10, all 10 | |
Zod validation on request bodies and queries | Yes | |
Helmet + CORS origin restrictions | Yes |
