Keep legal first and last names for formal lists; show DisplayFirstName on teams, calendars, and import matching so two Josiahs can be told apart. Co-authored-by: Cursor <cursoragent@cursor.com>
1.9 KiB
1.9 KiB
Student nicknames
Created: 2026-09-11
Last updated: 2026-09-11
Description: Optional nickname used as the display first name on informal surfaces.
Behavior
- First Name and Last Name stay the official name (
Name,FirstNameLastName,LastNameFirstName). - Optional Nickname on
Student. Blank or whitespace is stored as null. DisplayFirstNameis the trimmed nickname when set, otherwise first name.- Informal UI (teams, event rankings, calendars, meeting lists, rank badges, team member print tokens) uses
DisplayFirstName. {{FirstName}}stays legal. New tokens:{{Nickname}}(empty when unset) and{{DisplayFirstName}}.
Data
Migration AddStudentNickname adds nullable Students.Nickname (max 100). Applied on next app start via MigrateAsync.
Testing
Unit tests stay in the Core Tests project (no Blazor/bUnit). They lock the two-Josiahs contract:
| Layer | What we assert |
|---|---|
| Entity | DisplayFirstName / ToString / NormalizeNickname; legal Name / FirstNameLastName / LastNameFirstName ignore nickname |
| Display | Formatters and alphabetical team lists use nickname; suffix markers still attach; no nickname falls back to first name |
| Matching | Fuzzy matcher, year-rollover paste, assignment CSV columns, team import, notes import, and ranking import distinguish Jo vs Josiah B |
| Collision | Assignment header Josiah still binds the first Josiah (requirement files must use display names) |
Catalog includes Nickname and DisplayFirstName; merge keeps {{FirstName}} legal |
Not covered by unit tests: Blazor create/edit/index captions, NotePrintService token map (same keys as the catalog/merger contract), and rewriting stored team identifiers.
Follow-up
After setting nicknames on students who share a first name, rename any team identifiers that still collide (identifiers are stored, not recomputed).