Repository navigation
Add user-selected usernames - #451
Conversation
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR implements comprehensive username support across the application. Users now provide a username during signup, which is validated, stored, and included in session and profile data. A new account profile API endpoint allows users to view and update their username, with corresponding UI and test updates. ChangesUsername feature implementation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
|
🔎 Preview deployed: https://kody-pr-451.kentcdodds.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@e2e/playwright-utils.ts`:
- Around line 42-47: The helper currently treats any HTTP 409 as a successful
seed which can hide username collisions; update the response handling in the
seeding helper (the block that checks response.ok() / response.status() and
returns { email, username, password }) to parse the response body (e.g., await
response.json()) when status === 409 and verify the error indicates the same
user already exists (matching message/code or email/username in the payload);
only swallow the 409 and return credentials if that explicit "already exists for
this user" condition is met, otherwise throw an Error with the status and the
parsed error detail so collisions or other 409 causes fail the test.
In `@packages/worker/client/routes/account.tsx`:
- Around line 41-46: The code uses new URL(href).search which throws when href
is a relative path on the server; modify account.tsx to compute the query string
safely by using a conditional: keep setting href/lastLoadedHref as now, but
replace new URL(href).search with a safe value (e.g. const search = typeof
window === 'undefined' ? (href.includes('?') ? '?' + href.split('?')[1] : '') :
new URL(href).search) and then call fetch(`${accountProfileApiPath}${search}`,
...). Update references around lastLoadedHref/href and the fetch call so
server-side execution never calls new URL with a relative URL.
In `@packages/worker/src/app/database-errors.ts`:
- Around line 4-6: The regex extracting the column name from the SQLite unique
constraint error (the pattern assigned to match in database-errors.ts) only
allows letters and underscores and will miss names with digits; update the
capture group to include digits (for example change ([a-z_]+) to ([a-z0-9_]+) or
use \w+ with the existing case-insensitive flag) so the code that inspects
currentError.message correctly extracts column names like field_123 or col2.
In `@packages/worker/src/app/handlers/session.ts`:
- Around line 32-35: The code uses Number.parseInt on session.id which accepts
partial numeric strings; before converting and querying with
db.findOne(usersTable, { where: { id: userId } }) validate session.id with a
strict numeric check (e.g., test against /^\d+$/) and only call Number.parseInt
and perform the DB lookup when the test passes; otherwise treat userRecord as
null to avoid accidental partial-number lookups.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 950a47d4-3f75-40d3-9ab7-4bd91bfc3b38
📒 Files selected for processing (20)
e2e/auth-test-user.tse2e/playwright-utils.tspackages/worker/client/routes/account-approval-shared.tspackages/worker/client/routes/account.tsxpackages/worker/client/routes/login.tsxpackages/worker/client/session.tspackages/worker/src/app/audit-log.tspackages/worker/src/app/authenticated-user.tspackages/worker/src/app/database-errors.tspackages/worker/src/app/handlers/account-profile.node.test.tspackages/worker/src/app/handlers/account-profile.tspackages/worker/src/app/handlers/auth-handler.node.test.tspackages/worker/src/app/handlers/auth.tspackages/worker/src/app/handlers/session-handler.node.test.tspackages/worker/src/app/handlers/session.tspackages/worker/src/app/router.tspackages/worker/src/app/routes.tspackages/worker/src/app/username.tspackages/worker/src/env-schema.tstools/mcp-test-support.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/worker/migrations/0038-backfill-usernames.sql`:
- Around line 1-12: The migration currently overwrites all usernames because
both UPDATEs lack a WHERE filter; change them to only touch rows with missing
usernames (e.g., WHERE username IS NULL OR username = '') and avoid
double-writing by applying the special-case mapping for email
'me@kentcdodds.com' first (UPDATE users SET username = 'kentcdodds', updated_at
= CURRENT_TIMESTAMP WHERE email = 'me@kentcdodds.com' AND (username IS NULL OR
username = '')), then set generated usernames only for remaining rows (UPDATE
users SET username = '__username_backfill__' || id, updated_at =
CURRENT_TIMESTAMP WHERE username IS NULL OR username = ''); reference the users
table and the username, email, id, updated_at columns when making these changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6727db1a-b6db-4e78-8e05-bbf723975150
📒 Files selected for processing (3)
packages/worker/migrations/0038-backfill-usernames.sqltools/seed-test-data.node.test.tstools/seed-test-data.ts
✅ Files skipped from review due to trivial changes (1)
- tools/seed-test-data.node.test.ts
| UPDATE users | ||
| SET | ||
| username = '__username_backfill__' || id, | ||
| updated_at = CURRENT_TIMESTAMP; | ||
|
|
||
| UPDATE users | ||
| SET | ||
| username = CASE | ||
| WHEN email = 'me@kentcdodds.com' THEN 'kentcdodds' | ||
| ELSE email | ||
| END, | ||
| updated_at = CURRENT_TIMESTAMP; |
There was a problem hiding this comment.
Backfill currently overwrites all usernames, not just missing ones
Line 6 updates every row with no guard, so any pre-existing username gets replaced (email/kentcdodds). It also makes Line 1’s value temporary and rewrites updated_at twice for all users.
Suggested migration shape
-UPDATE users
-SET
- username = '__username_backfill__' || id,
- updated_at = CURRENT_TIMESTAMP;
-
UPDATE users
SET
username = CASE
WHEN email = 'me@kentcdodds.com' THEN 'kentcdodds'
ELSE email
END,
updated_at = CURRENT_TIMESTAMP;
+WHERE username IS NULL OR username = '';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| UPDATE users | |
| SET | |
| username = '__username_backfill__' || id, | |
| updated_at = CURRENT_TIMESTAMP; | |
| UPDATE users | |
| SET | |
| username = CASE | |
| WHEN email = 'me@kentcdodds.com' THEN 'kentcdodds' | |
| ELSE email | |
| END, | |
| updated_at = CURRENT_TIMESTAMP; | |
| UPDATE users | |
| SET | |
| username = CASE | |
| WHEN email = 'me@kentcdodds.com' THEN 'kentcdodds' | |
| ELSE email | |
| END, | |
| updated_at = CURRENT_TIMESTAMP | |
| WHERE username IS NULL OR username = ''; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/worker/migrations/0038-backfill-usernames.sql` around lines 1 - 12,
The migration currently overwrites all usernames because both UPDATEs lack a
WHERE filter; change them to only touch rows with missing usernames (e.g., WHERE
username IS NULL OR username = '') and avoid double-writing by applying the
special-case mapping for email 'me@kentcdodds.com' first (UPDATE users SET
username = 'kentcdodds', updated_at = CURRENT_TIMESTAMP WHERE email =
'me@kentcdodds.com' AND (username IS NULL OR username = '')), then set generated
usernames only for remaining rows (UPDATE users SET username =
'__username_backfill__' || id, updated_at = CURRENT_TIMESTAMP WHERE username IS
NULL OR username = ''); reference the users table and the username, email, id,
updated_at columns when making these changes.
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit eb1d943. Configure here.
| WHEN email = 'me@kentcdodds.com' THEN 'kentcdodds' | ||
| ELSE email | ||
| END, | ||
| updated_at = CURRENT_TIMESTAMP; |
There was a problem hiding this comment.
Migration lacks UNIQUE constraint for username column
High Severity
The backfill migration populates the username column but never adds a UNIQUE constraint or unique index on it. The existing schema (from 0001-init.sql) only creates a non-unique index (CREATE INDEX ... idx_users_username). Both auth.ts and account-profile.ts contain catch blocks that handle UNIQUE constraint failed: users.username errors as a race-condition safety net, but those errors can never be raised without a database-level unique constraint. Concurrent signups or profile updates choosing the same username can slip past the application-level findOne pre-check and insert duplicate usernames.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit eb1d943. Configure here.


Summary
users.usernamecolumn./account/profile.jsonfor reading/updating the signed-in user's username.me@kentcdodds.com->kentcdodds, and update seed defaults for valid usernames.Walkthrough
Testing
npm run validatenpx playwright test e2e/smoke.spec.tsnpx vitest run --config vitest.node.config.ts tools/seed-test-data.node.test.ts packages/worker/client/app-session-refresh.node.test.tsnpm run typechecknpm run lintSummary by CodeRabbit
New Features
Bug Fixes / Validation
Data Migration
Tests