Skip to content

feat(account): username with a weekly change limit - #43

Merged
kris1027 merged 18 commits into
mainfrom
feat/account-username
Oct 11, 2026
Merged

kris1027 merged 18 commits into
mainfrom
feat/account-username

Conversation

@kris1027

@kris1027 kris1027 commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Adds a username to every account: chosen when signing up, changeable on /account at most once a week, and shown in the navbar. Plan and decisions: prompts/account-username.md.

What changes

  • Database (20261011120000_account_username.sql): a new profiles table that only its owner can read and update. The database enforces every rule, so writes made directly through the API follow them too:

    • 2–30 ASCII characters (letters, digits, _ . -), no spaces, cannot start or end with . or -;
    • a short list of reserved names;
    • unique regardless of case;
    • a 7-day lock after each change (rolling), enforced by a trigger that also sets the change time itself.

    Nobody can delete their row, so deleting it can't be used to reset the lock.

  • username_available(text) is the one security definer function and the one anon can call, so the sign-up form can check a name before the account exists. It returns only a boolean. 140-security-sweep excludes it by exact signature and checks that it returns a boolean.

  • Sign up: a required Username field. A taken name is refused before any account is created. If someone takes the name in between the check and sign-up, the person lands on /account?notice=username-taken to choose another.

  • /account: a Username section with three states: no username yet, editable, or locked with the unlock time shown in the viewer's own time zone. From lg up the settings sit in two columns (Account and Username on the left, Change password on the right). Change password now asks for the new password twice, and both card buttons line up at the bottom.

  • Navbar: shows the username and its first letter in the avatar, and falls back to the email name.

  • Privacy: /privacy lists the username, and LEGAL_LAST_UPDATED is now 2026-10-11.

Deploy

The migration only adds objects, so the deployment that is live now keeps working. It must be pushed with supabase db push before this PR is merged (docs/deploy.md). Pushed on 2026-10-11; local and remote migration lists match.

Checks

  • pnpm test: 2282 passed
  • pnpm test:db: 332 passed (new 170-profiles-username)
  • pnpm typecheck, pnpm lint, pnpm db:types:check: clean
  • pnpm build: OK; /shows and /movies are still prerendered
  • Manual run against the local stack:
    • sign up, with an invalid name refused and a taken name refused without creating an account;
    • /account locked and then unlocked, with the change saved;
    • navbar shows the new name;
    • layout checked at 1280px and 375px;
    • mismatched new passwords are refused.

🤖 Generated with Claude Code

kris1027 and others added 9 commits October 11, 2026 12:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027 kris1027 added feature New user-facing functionality test Automated tests and test infrastructure ui Layouts, styling, and shared interface components auth Sign-in, sign-out, sessions, and account recovery database Schemas, migrations, queries, and row-level security security Authorization, secret protection, and vulnerability fixes labels Oct 11, 2026
@kris1027 kris1027 self-assigned this Oct 11, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in BeStats Oct 11, 2026
@vercel

vercel Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
bestats Ready Ready Preview Oct 11, 2026 12:00pm UTC

kris1027 and others added 9 commits October 11, 2026 13:55
The weekly lock now raises its own SQLSTATE, BS002, so the account and
sign up actions read only the code, through classifyProfileWriteError in
lib/auth/supabase-error.ts, instead of matching codes and message text
in each action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reserved name refusal and the /account card line now read the same
entries the action outcomes use, so a reserved name can never read
differently from a taken one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The drift test now compiles both profiles format checks and runs them
over the same names as the Zod schema, so a change to the character
class or the start and end rule on either side fails (R8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every Server Action resolves the user with getOptionalUser and reports
an ended session instead of redirecting; requireUser is for private
pages. The notes said otherwise, so they now match the code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AuthField is derived from one const list, and fromZodError narrows with
it instead of repeating every name in an || chain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027
kris1027 merged commit 6f48ccd into main Oct 11, 2026
4 checks passed
@kris1027
kris1027 deleted the feat/account-username branch October 11, 2026 12:03

This branch was successfully deployed

1 active deployment
Preview — 97ccf6ca Deployed Oct 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Sign-in, sign-out, sessions, and account recovery database Schemas, migrations, queries, and row-level security feature New user-facing functionality security Authorization, secret protection, and vulnerability fixes test Automated tests and test infrastructure ui Layouts, styling, and shared interface components

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant