IdentityXFrontend
Coding Conventions
How the IdentityX frontend consumes the API — generated clients, envelope, auth.
Consume the generated client
- All API calls go through
@trieoh/identityx-api(orval-generated from the spec). No hand-written fetch wrappers per endpoint. - Regenerate after spec changes:
pnpm orval— the client is not hand-edited. - Hooks are TanStack Query hooks from the generated package; let React Query own caching/retry/invalidation instead of writing bespoke request state.
Runtime setup
Configure the shared fetch stack once, at app startup:
configureApiClient({
baseURL: env.VITE_API_URL, // → https://api.trieoh.com/identityx
authBaseURL: env.VITE_AUTH_API_URL, // used for token refresh
})Envelope & errors
- The
fun.Responseenvelope is unwrapped at the client layer — you never see it. Success returns the payload directly. - Failures reject with
ApiError(FetchClientError): the envelope is in.envelope, so error UI readserror.envelope.error.message(or the typed code). - Public/anonymous routes: call generated hooks with
{ public: true }so they skip auth headers and any BFF proxy.
Authentication
- Users authenticate through IdentityX (
/auth/register,/auth/login) — the access token is a JWT carryingsubject.id, which downstream services use as the owner/purchaser id. - Tokens are attached by the shared fetcher; refresh is handled via
authBaseURL. Don't stash tokens inlocalStoragemanually — use the platform's auth flow. - Svc/machine flows use API keys server-side, never in the browser.
Keeping in sync with the spec
- Spec changed? Run
just generate-orvaland let the type errors guide the UI updates. - The generated types are the source of truth for payload shapes — don't
as-cast around them.
Don't
- Don't call endpoints by URL string — import the generated functions.
- Don't hand-roll response envelopes or error parsing.
- Don't duplicate schemas — import from the client package.