Segment-aware aliases and roles, success toasts, group membership notes, life event data quality
Segment-aware character aliases - aliases migrated from a flat JSON column on the characters table to a dedicated character_aliases table with optional start/end book and segment boundaries. 518 alias records migrated across 343 characters. Curator UI on the character detail tab with Active/Deleted/Activity sub-tabs, form drawer with cascading segment pickers, and full CRUD API with contribution system support.
Segment-aware character roles - new character_roles table tracks when a character's narrative role changes across a series (e.g. supporting to protagonist). The existing characters.role field is retained as the default fallback. Curator UI with overlap detection warnings when multiple roles lack end segments. Includes getEffectiveRole() utility for resolving the active role at any segment position.
Success toast notifications - added toast.success() calls site-wide for all actions that previously had no success feedback. Covers admin lookup values (create, edit, delete, reorder for both parent and child values), admin settings save, blog post save/publish (migrated from inline Notice to toast), blog image upload/delete/cover, and curator entity create/edit forms. Blog post form cleaned up by removing the old success state and timer in favour of toast.
Group membership notes - new optional notes text field on group memberships for recording context about a character's membership. Added across the full stack: schema column, migration, Zod validation schemas, GET/POST/PATCH API routes for both character and group contexts, membership form drawer with rich text editor (bold, italic, entity links, suggest links), and all type definitions. Notes display on the public character detail page below the group name, matching the relationship notes pattern. Fixed startBookId incorrectly required in form schema, which prevented editing memberships without a start book.
His Dark Materials group memberships - 12 memberships added across four His Dark Materials groups: The Magisterium (Mrs Coulter, Father Gomez, Fra Pavel, Lord Boreal), The General Oblation Board (Mrs Coulter as leader, Fra Pavel), The Gyptians (John Faa as leader, Farder Coram, Ma Costa, Billy Costa), and Clan of Serafina Pekkala (Serafina Pekkala as leader, Ruta Skadi). Seven memberships include contextual notes. All entities have correct source attribution.
Audit log source diff fix - editing any entity (book, character, author, series, universe, group) previously showed "Sources" as changed in the activity log even when sources were untouched. Caused by null vs '' mismatch between DB values and form values in the computeChangedFields comparison. Fixed across all six entity PATCH routes.
Life event subtype fix - fixed the award subtype dropdown not populating when opening the edit life event drawer. The clear-subtype effect was firing during the initial form reset, wiping the saved subtype value before the child lookup values loaded. Also shows a loading placeholder instead of an empty select during fetch.
Life event data quality - 11 invalid other type events reclassified to correct types (escape, appointment, founding, etc.). 78 life event notes enriched with entity links to characters, books, series, authors, and groups. Missing source attribution added for Father Gomez and all 12 His Dark Materials group memberships.
Group picker fix - fixed the group selector on the public character detail page showing "No results found" when adding a character to a group. The availableGroups prop was not being passed to the membership form drawer.
Life Stage physical attribute - new physical attribute type with seven values: Infant, Child, Adolescent, Young Adult, Adult, Middle Aged, Elderly. Uses the existing segment-aware physical attributes infrastructure.
Community group type - nine groups reclassified from faction/nation to community: Edema Ruh, The Aiel, The Dothraki, The Wildlings, Two Rivers Folk, The Northmen, Zion Cluster, The Adem, and Fremen. Four new His Dark Materials groups added: The Magisterium, The General Oblation Board, The Gyptians, and Clan of Serafina Pekkala.
Occupation expansion - ten new occupation types added (activist, caretaker, composer, cowboy, enforcer, homemaker, minister, naval officer, pirate, security officer). 79 occupation assignments across 61 characters who previously had none.
TypeScript error fixes - resolved 26 pre-existing type errors across 8 files: SolutionRevealBoundaries type now properly imported in spoiler filter, isSolutionSensitive added to appearance/state data interfaces, invalid seriesId removed from group test fixture, canonicalName added to missing link suggestion test objects, mock callable types fixed in permanent-delete tests, and excess property errors cleaned up in suggest-links tests.
Test alignment - updated 7 test files where error message assertions had fallen out of sync with the current wording ("Could not save" / "Your changes to ... could not be saved" instead of the old "Failed to save").
CHARACTER_ROLES constant fix - added missing 'major' value that was present in lookup values but absent from the TypeScript constant.
Search group validation fix - fixed pre-existing Zod validation error when groups appeared in search results (universe/series fields were required but never populated for groups).
Legacy aliases column dropped - the characters.aliases JSON column has been removed from the schema now that all queries use the dedicated character_aliases table. All listing queries use a new getAliasesByCharacterIds() helper, search uses an IN subquery on the aliases table, and parseAliases() utility removed. Six display components updated to consume string[] directly. Migration generated (0056_exotic_zaran.sql).
Test fixes - three pre-existing test failures resolved: authors list heading level (h2 to h3), genre series count logic (now counts distinct series with any tagged book), and character timeline collapse assertions (CSS class check instead of DOM presence). Group membership test updated for optional startBookId.