* fix(profiles): enforce per-account profile name uniqueness
Profile create and rename accepted any name, so one account could hold
unlimited profiles all called "Laura" (every client allowed it too).
Reject a create or rename whose trimmed, case-insensitive name matches
another profile on the same account with 409 name_conflict. Scoping is
per account by construction — the check runs against a single user's
profile store, so different accounts can still each have a "Laura".
Renames exclude the profile being updated, so re-saving a profile under
its own name (e.g. avatar-only edits that resubmit the name) still works.
Also reject whitespace-only names on create and rename; a name of " "
previously passed the blank check.
Additive-only per the v1 API rules: new 409 error code on existing
endpoints, following the profile_limit_reached pattern.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(profiles): store the trimmed profile name
The conflict check compared trimmed names but create/rename persisted
the raw input, so " Laura " could land with stray whitespace and render
inconsistently. Normalize to the trimmed form before storage on both
paths. Addresses the CodeRabbit review finding on PR #342.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(profiles): cover whitespace-only rejection and rename trimming
Also document the check-then-write race in profileNameConflicts: the
userstore backends carry no unique index on name, so concurrent creates
can still race past the guard, same as profile_limit_reached.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: rxwatcher <rxwatcher@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Quick <31828688+Quick104@users.noreply.github.com>