Skip to content

refactor: migrate account fetch to TanStack Start server function#999

Closed
igboyes wants to merge 5 commits into
mainfrom
igboyes/vir-2367-migrate-account-fetch-to-tanstack-start-server-function
Closed

refactor: migrate account fetch to TanStack Start server function#999
igboyes wants to merge 5 commits into
mainfrom
igboyes/vir-2367-migrate-account-fetch-to-tanstack-start-server-function

Conversation

@igboyes
Copy link
Copy Markdown
Member

@igboyes igboyes commented May 29, 2026

Summary

  • Replaces the legacy superagent REST call for /account with a TanStack Start server function (getAccount) backed by Drizzle/Postgres, following the data.tsfunctions.ts layering convention
  • Tightens the auth redirect logic in _authenticated.tsx so only genuine UnauthorizedError (401) bounces the user to /login; transient failures (network blips, 5xx) are swallowed so cached account data keeps the layout mounted
  • Adds unit tests for the getAccount data layer and rewrites the _authenticated route tests to drive beforeLoad directly instead of relying on nock HTTP interception

Test plan

  • Verify login → authenticated layout loads account from the server function
  • Confirm a 401 (session expiry) redirects to /login with the correct redirect search param
  • Confirm a transient error (e.g. momentary network failure) does not redirect a logged-in user
  • Run pnpm --filter @virtool/web exec vitest run src/server/account/__tests__/data.test.ts
  • Run pnpm --filter @virtool/web exec vitest run src/routes/__tests__/-_authenticated.test.tsx

igboyes added 2 commits May 29, 2026 11:42
Add src/server/account/ as a TanStack Start server feature backing the
account fetch directly with Postgres, ahead of repointing the client
query off the Python GET /api/account endpoint.

- data.ts: getAccount(db, userId) — concurrent user lookup + group join,
  permission union across groups, primary-group resolution, settings
  coerced over defaults, AccountNotFoundError on a missing user row.
- functions.ts: createServerFn shell reading userId from context.session
  (authenticated by default via the global middleware), mapping
  AccountNotFoundError to a 404.

Settings now read from Postgres; docs/database.md marks Settings as
Postgres-primary to match.
Switch fetchAccount() from the superagent REST client to the getAccount()
server function. Update _authenticated route to distinguish auth failures
(UnauthorizedError) from transient errors — only genuine 401s redirect to
/login. Update tests to match the new server-function-based flow.
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 29, 2026

VIR-2367

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates user settings to Postgres and introduces a new server function getAccount to fetch account data, permissions, and settings using Drizzle. It also updates the authenticated route to handle transient fetch errors gracefully and adds corresponding tests. The review feedback highlights three key issues: first, the rethrowAsHttp call in the server function is not awaited, which will lead to unhandled promise rejections; second, swallowing transient errors in beforeLoad when no cached data exists can result in an infinite loading spinner; and third, casting the server response to Promise<Account> bypasses TypeScript nullability checks for administrator_role and primary_group, introducing a type-safety risk.

Comment thread apps/web/src/server/account/functions.ts
Comment thread apps/web/src/routes/_authenticated.tsx
Comment thread apps/web/src/account/api.ts Outdated
igboyes added 3 commits May 29, 2026 14:45
- await rethrowAsHttp(err) in functions.ts so auth/not-found errors
  propagate correctly instead of silently becoming unhandled rejections
- re-throw transient beforeLoad errors when no account is cached,
  replacing an infinite spinner with TanStack Router's error boundary
- fix Account type: administrator_role and primary_group are nullable;
  update hasSufficientAdminRole, Nav, and Sidebar to accept null;
  remove the as Promise<Account> cast from fetchAccount()
- wire getAccount server fn mock via vi.hoisted() in setup.tsx to avoid
  a TDZ crash (setup → routeTree → _authenticated → account/api eagerly
  imports @server/account/functions before ./api/account loads)
- move mockApiGetAccount to tests/api/account.ts and update 18 test
  files to import it from there instead of tests/fake/account
…ate-account-fetch-to-tanstack-start-server-function

# Conflicts:
#	apps/web/src/account/api.ts
#	apps/web/src/administration/components/__tests__/AdministratorCreate.test.tsx
#	apps/web/src/administration/components/__tests__/AdministratorList.test.tsx
#	apps/web/src/routes/_authenticated.tsx
#	apps/web/src/users/components/__tests__/ManageUsers.test.tsx
#	apps/web/src/users/components/__tests__/UserDetail.test.tsx
@igboyes igboyes closed this Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant