The /admins create/patch endpoints now plumb email through to the repo so the dashboard's invite + edit forms aren't silently dropping it on the floor. Discovered during smoke testing — the database column existed and was exposed in the response DTO, but neither the request DTO nor the repo's create() accepted it. CreateAdminRequest gains optional email; PatchAdminRequest gains email with JSON Merge Patch semantics: absent → don't change null → clear (write NULL) "<string>" → set to that value The tri-state needs Option<Option<String>> with a tiny custom deserializer; serde collapses absent and null otherwise. normalize_email() trims, treats blanks as None, and rejects obviously bogus values (no '@', >254 chars) with a 422. Real email verification is a future concern. Repo trait gains an email parameter on create() and a new update_email() method. The unique-violation branch in create now inspects constraint() to distinguish duplicate username from duplicate email. Integration test exercises create-with-email, PATCH null clears, PATCH value sets, PATCH without email key no-ops on email. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
22 KiB
22 KiB