Closes#43673
## Changes
Sorts the `/software/titles` endpoint by display name (when set) instead
of the internal `software_titles.name` (often an installer filename).
**3 changes in `server/datastore/mysql/software_titles.go`:**
1. **Order key mapping** (line 24): `"name"` sort key now maps to
`COALESCE(NULLIF(stdn.display_name, ''), st.name)` — uses display name
when set, falls back to `st.name`. `NULLIF` ensures cleared display
names (empty string) are treated as unset.
2. **Secondary sort** (line 579): Same `COALESCE(NULLIF(...))`
expression for tie-breaking when sorting by a non-name column.
3. **LEFT JOIN** (line 635): Joins `software_title_display_names` so the
COALESCE expressions can resolve.
## Testing
### Manual testing
Inserted test software titles with display names that sort differently
from installer filenames. Confirmed:
- Before fix: sorted by internal `st.name` (installer filename)
- After fix: sorted by display name, with fallback to `st.name` when no
display name is set
- Verified with `order_direction=asc`, `desc`, and secondary sort via
`hosts_count`
### Unit tests
`server/datastore/mysql/software_titles_sort_test.go` — 5 subtests (no
MySQL required):
- Order key mapping uses `NULLIF` for empty display names
- Secondary sort uses `NULLIF` for empty display names
- Primary name sort doesn't add redundant secondary name sort
- SQL template includes `display_names` join
- Empty display name falls back to `st.name` in sort expression
SQL fixture (`select_software_titles_sql_fixture.gz`) regenerated to
match updated queries.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Software titles listing now sorts by team-specific display names when
present, falling back to default names; tie-breaking and overall sort
behavior refined for more consistent ordering.
* **Tests**
* Added tests validating display-name sorting, correct fallback for
empty names, secondary sort behavior, and generated query structure to
ensure consistent results.
[](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/44873)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->