3.4 KiB
3.4 KiB
Tasks: enterprise-react-auth
Change ID: enterprise-react-auth
Package: @suaveplan/react-auth
Target path: react/auth/react-auth
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/oauth-client, @suaveplan/react-translate
1. Scaffold
- Create directory tree per proposal layout.
- Write
package.jsonat0.1.0with"sideEffects": false, exports map. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/types workspace:^,@suaveplan/events workspace:^,@suaveplan/oauth-client workspace:^,@suaveplan/react-translate workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build. - Write
tsconfig.json,vitest.config.ts, scripts.
2. Error codes and types
- Define
AuthErrorextendingSuaveplanError; codes:AUTH_UNAUTHENTICATED,AUTH_TOKEN_EXPIRED,AUTH_REFRESH_FAILED,AUTH_CONTEXT_MISSING. - Define
AuthUser,AuthState,AuthConfig,AuthContextValue,AuthProviderProps,AuthGuardProps,SignInOptions,SignOutOptions. - Write
AuthConfigSchemaZod schema.
3. Token utilities
src/utils/token-storage/—createTokenStorage(adapter: 'memory' | 'localStorage' | 'sessionStorage'):setTokens(tokens),getTokens(),clearTokens().src/utils/session-persistence/—saveSession(user),loadSession(): AuthUser | null,clearSession().- Write tests + md for each.
4. AuthContext + AuthProvider
- State:
user: AuthUser | null,isLoading,isAuthenticated. signIn(options: SignInOptions)— calls@suaveplan/oauth-clientauthorization + token exchange; stores tokens; emits@suaveplan/eventsauth:signed_in. OTelauth.sign_inspan.signOut(options?)— clears tokens + session; emitsauth:signed_out. OTelauth.sign_outspan.refreshToken()— calls@suaveplan/oauth-clienttoken refresh; on failure throwsAuthError(AUTH_REFRESH_FAILED). OTelauth.token_refreshspan.- Auto-refresh: installs a timer to refresh before expiry.
useAuth()throwsAuthError(AUTH_CONTEXT_MISSING)outside provider.- Write
auth-context.test.tsx(≤500 lines): sign-in, sign-out, refresh, auto-refresh timer, context missing.{ timeout: 10000 }. - Write
auth-context.md.
5. Hooks
useUser(): AuthUser | null— from context.useIsAuthenticated(): boolean.useAuthToken(): string | null— current access token.- Write tests + md for each.
6. AuthGuard + withAuth
AuthGuard— renders children when authenticated; callsonUnauthenticated(default: throwsAuthError(AUTH_UNAUTHENTICATED)) when not.withAuth(Component)— HOC wrappingAuthGuard.- Write tests, stories (authenticated, unauthenticated-redirect, loading), md.
7. E2E
e2e/auth.spec.ts— Playwright with injected mock@suaveplan/oauth-client:- Render
AuthGuardwhile unauthenticated →onUnauthenticatedfires. - Call
signIn()→ user set in context →AuthGuardrenders children. - Call
signOut()→ user cleared.
- Render
8. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-auth— green.bunx turbo test:coverage --filter=@suaveplan/react-auth— 100%.bun scripts/publish.ts --package @suaveplan/react-auth.- Archive change folder.