🐛 fix(auth): prevent repeated /api/user/self calls and ensure sign‑out redirect
- Call `auth.fetchSelf()` inside a one-time `useEffect` in `web/src/routes/_authenticated/route.tsx`
to avoid re-render triggered loops that spam `/api/user/self`.
- Make the sign-out flow await `auth.logout()`, close the dialog, then navigate to `/sign-in`
with the current location as `redirect` in `web/src/components/sign-out-dialog.tsx`,
guaranteeing the guard and redirect work reliably.
- No changes to old Semi UI archive; no linter errors introduced.
Test plan:
- Click “Sign out”: only one `/api/user/logout` request, no repeated `/api/user/self`,
then redirected to `/sign-in?redirect=<previous_url>`.
- Refresh authenticated pages: at most one `/api/user/self` fetch occurs.