fix(api): don't clobber good profile data on failed bsky fetch
getProfile's refreshProfile overwrote users.avatar/display_name with an
empty name and a CID-less avatar URL whenever the bsky profile fetch in
retrieveProfile failed (record stays {}), and published the garbage to
NATS. A single failed fetch permanently corrupted the row.
Now only write a field when the fetch actually produced it, preserving
existing DB values otherwise; build the avatar URL from the real CID and
mimeType extension; and serve the resolved user in presentation so the
response and DB agree.