Skip to content

Add username field to CoPlan::User#86

Merged
HamptonMakes merged 2 commits intomainfrom
add-username-to-users
Apr 6, 2026
Merged

Add username field to CoPlan::User#86
HamptonMakes merged 2 commits intomainfrom
add-username-to-users

Conversation

@HamptonMakes
Copy link
Copy Markdown
Collaborator

Summary

Adds a username field to users — a clean, human-readable handle like hampton for use in @-mentions (coming next).

How it works

  • Auto-derived from external_id — strips the @domain.com part and lowercases (e.g., hampton@squareup.comhampton)
  • Collision handling — if alice is taken, the next user gets alice1
  • Explicitly settable — you can set username directly and it won't be overwritten
  • Validated — unique, lowercase alphanumeric with dots/hyphens/underscores
  • Backfilled — data migration derives usernames for all existing users

Fields

Field Purpose Example
name Display name Hampton Lintorn-Catlin
username Handle for @-mentions hampton
external_id Auth identity (OIDC) hampton@squareup.com

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4278beec1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,11 @@
class BackfillUsernames < ActiveRecord::Migration[8.1]
def up
CoPlan::User.where(username: nil).find_each do |user|
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Commit the copied add-username migration before backfill

This backfill references username in host-app migrations, but there is no db/migrate/*add_username_to_coplan_users.co_plan.rb committed alongside it. In this repo, db:migrate is wired to run co_plan:install:migrations first, and existing .co_plan files show copied engine migrations get new timestamps; that means a fresh environment can copy the add-column migration with a timestamp later than 20260406200000, causing this migration to run first and fail with an unknown username column.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in b5b8b1c — committed the copied migration file so fresh environments always run it before the backfill.

Comment on lines +30 to +31
base = external_id.to_s.split("@").first.downcase.gsub(/[^a-z0-9._-]/, "")
base = base.presence || external_id.to_s.downcase.gsub(/[^a-z0-9._-]/, "")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Strip leading punctuation when deriving usernames

The derivation keeps leading ./_/- from external_id (split("@").first + gsub), but the validation requires the first character to be [a-z0-9]. For valid existing IDs like _alice@example.com or -svc@idp, before_validation assigns an invalid username and save! fails, which can break sign-in and also abort the backfill on those rows.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch — added .sub(/\\A[^a-z0-9]+/, "") to strip leading punctuation in both the host callback and the backfill migration. Fixed in b5b8b1c.

- Add username column (unique, indexed) to coplan_users
- Engine validates format and uniqueness but does NOT auto-derive
- Host app derives username from external_id in its authenticate callback
- Engine accepts username (and avatar_url, title, team) from auth attrs
- Backfill migration derives usernames for existing users
- Add model specs for persistence, format validation, uniqueness

Amp-Thread-ID: https://ampcode.com/threads/T-019d6373-a857-75b8-b976-dc9a989c53e0
Co-authored-by: Amp <amp@ampcode.com>
@HamptonMakes HamptonMakes force-pushed the add-username-to-users branch from 4278bee to 5142a0b Compare April 6, 2026 18:34
- Commit the copied engine migration so fresh environments run it
  before the backfill
- Strip leading dots/hyphens/underscores from derived usernames so
  they pass the [a-z0-9] first-character validation

Amp-Thread-ID: https://ampcode.com/threads/T-019d6373-a857-75b8-b976-dc9a989c53e0
Co-authored-by: Amp <amp@ampcode.com>
@HamptonMakes HamptonMakes merged commit ee27317 into main Apr 6, 2026
5 checks passed
@HamptonMakes HamptonMakes deleted the add-username-to-users branch April 6, 2026 20:38
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.

1 participant