Summary
The `apps/admin/src/app/(authenticated)/posts/page.tsx` adapter maps API responses to the admin's `Post` type. The mapping is forced because the API doesn't actually emit some fields the admin needs:
- `author.displayName` — set to `''` (empty string). PostListClient renders `{post.author.displayName}` which produces a blank cell for every row.
- `commentsCount` — set to `0`. Misleads operators into thinking no posts have comments.
Fix options
(a) Join author display name API-side — change `/api/v1/posts` list query to JOIN `users` and emit `{author: {id, display_name}}`. Best UX, breaks API shape.
(b) Frontend fallback — when displayName is empty, show `shortId(author_id)` (matching `posts/[id]/revisions/page.tsx:289`'s pattern). Cheap; consistent with existing convention.
(c) Defer until generated api-types lands (#510 / equivalent).
`commentsCount` requires a separate `SELECT COUNT(*)` per post (or a column on the posts table). Defer to a follow-up.
Recommendation
Ship (b) now as a UI patch; track (a) in api-types refactor.
Summary
The `apps/admin/src/app/(authenticated)/posts/page.tsx` adapter maps API responses to the admin's `Post` type. The mapping is forced because the API doesn't actually emit some fields the admin needs:
Fix options
(a) Join author display name API-side — change `/api/v1/posts` list query to JOIN `users` and emit `{author: {id, display_name}}`. Best UX, breaks API shape.
(b) Frontend fallback — when displayName is empty, show `shortId(author_id)` (matching `posts/[id]/revisions/page.tsx:289`'s pattern). Cheap; consistent with existing convention.
(c) Defer until generated api-types lands (#510 / equivalent).
`commentsCount` requires a separate `SELECT COUNT(*)` per post (or a column on the posts table). Defer to a follow-up.
Recommendation
Ship (b) now as a UI patch; track (a) in api-types refactor.