Skip to content

Normalize usernames for safe indexed lookup - #194

Merged
coder13 merged 4 commits into
masterfrom
agent/issue-185-normalized-usernames
Jul 14, 2026
Merged

Normalize usernames for safe indexed lookup#194
coder13 merged 4 commits into
masterfrom
agent/issue-185-normalized-usernames

Conversation

@coder13

@coder13 coder13 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • centralize optional username normalization and validation for writes, exact lookup, and capped prefix lookup
  • preserve display casing while storing a lowercase MongoDB lookup key behind an explicitly migrated sparse unique index
  • return stable 400 validation and 409 case-insensitive conflict responses without interpolated regular expressions
  • mirror and reconcile usernames through PostgreSQL by WCA user ID while MongoDB remains the source of truth
  • add a dry-run-first, collision-aware, idempotent backfill plus production ordering and rollback documentation

Privacy behavior

Email is never a discovery input or fallback. Email-like username input receives the same generic INVALID_USERNAME response as other invalid input and never issues a lookup. Privacy-marker detection happens after NFKC canonicalization, so compatibility characters such as fullwidth and small @ cannot bypass it.

The legacy backfill never prints private raw values. It removes email-like usernames from MongoDB and reconciles both PostgreSQL username fields to NULL by WCA user ID. This branch preserves #192's no-email ingestion and dual-write behavior.

Dependency and merge order

This branch is rebased onto the current head of #192 (72e1494), so the integration with the email purge has been resolved and tested. Because #192 is not yet on master, this PR temporarily includes its two commits.

Merge and deploy #192 first. After it lands, refresh this branch against master so the PR contains only #185's commits. Intended rollout order remains #192#185 → friendship/discovery work.

Migration behavior

The MongoDB script defaults to a read-only, value-free report. Applying it writes the planned MongoDB targets, rereads and verifies them, then reconciles exact PostgreSQL targets by WCA user ID when PostgreSQL is enabled. PostgreSQL-disabled deployments are reported explicitly and can rerun the same idempotent reconciliation before bringing the mirror back.

Invalid non-email legacy usernames remain undiscoverable. Collision members retain display values but have no normalized key; index creation fails closed until every collision is explicitly resolved. Username writes and discovery must remain disabled during that state, preventing a third account from claiming a collided key.

--create-index requires --apply, zero pending changes, zero privacy removals, zero collisions, and zero PostgreSQL verification mismatches. It then creates or verifies the named sparse unique index. A repeated apply reports no modified rows.

Validation

  • CI=true yarn test — 3 workspaces passed, 224 tests total
  • yarn lint — 3 workspaces passed
  • yarn workspace letscube-server postgres:schema:validate — passed
  • yarn build — passed (existing Vite chunk-size warnings only)
  • git diff --check origin/master...HEAD — passed
  • disposable MongoDB 6 + PostgreSQL 17 rehearsal — applied every migration, ran Stop collecting and retaining WCA email #192's email purge, verified collision-blocked index creation, resolved the collision, created the index, reran enabled and PostgreSQL-disabled modes idempotently, and verified no email-like usernames or compatibility emails remained

Closes #185

coder13 added 4 commits July 12, 2026 20:43
Request only public WCA identity, allowlist login fields, and stop MongoDB and PostgreSQL writes. Add a value-free two-phase purge with an enforced privacy rollback floor so the compatibility column can remain safely empty until a later drop.
Exit unsuccessfully when MongoDB cannot be reached and clear the PostgreSQL compatibility column independently of guarded user upserts. This prevents connection failures or equal timestamps from leaving legacy email values behind.
Centralize username validation and add a collision-aware MongoDB backfill. Mirror normalized keys through an additive PostgreSQL migration for safe friend discovery.
Reconcile MongoDB username targets into PostgreSQL and fail index creation while collisions remain. Canonicalize privacy markers and keep test authentication on the shared normalization path.
@coder13
coder13 force-pushed the agent/issue-185-normalized-usernames branch from de3b389 to 35e3198 Compare July 13, 2026 04:13
@coder13
coder13 merged commit 2120740 into master Jul 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Normalize usernames for safe, indexed user lookup

1 participant