diff --git a/apps/client/src/App.tsx b/apps/client/src/App.tsx
index 9abf403b..adb15a6a 100644
--- a/apps/client/src/App.tsx
+++ b/apps/client/src/App.tsx
@@ -1,22 +1,14 @@
-import { analytics } from '@pinback/analytics';
import { router } from '@routes/router';
-import { useGetAmplitudeUserProperties } from '@shared/apis/queries';
-import { useEffect } from 'react';
+import AmplitudeProvider from 'src/providers/AmplitudeProvider';
import { RouterProvider } from 'react-router-dom';
import './App.css';
function App() {
- const { data: userProperties } = useGetAmplitudeUserProperties();
-
- useEffect(() => {
- if (!userProperties) return;
- analytics.identify(
- String(userProperties.userId),
- userProperties.jobRole ? { job_role: userProperties.jobRole } : undefined
- );
- }, [userProperties]);
-
- return ;
+ return (
+
+
+
+ );
}
export default App;
diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx
index 6812524b..dacbcb9a 100644
--- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx
+++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx
@@ -6,76 +6,71 @@ import { useQueryClient } from '@tanstack/react-query';
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
+const REDIRECT_URI = import.meta.env.VITE_GOOGLE_REDIRECT_URI;
+
const GoogleCallback = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const queryClient = useQueryClient();
- useEffect(() => {
- const code = searchParams.get('code');
+ const saveSession = (params: {
+ accessToken: string | null;
+ refreshToken: string | null;
+ email: string;
+ userId: string;
+ hasJob?: boolean;
+ }) => {
+ const { accessToken, refreshToken, email, userId, hasJob } = params;
- if (!code) {
- alert('로그인 실패. 다시 시도해주세요.');
- navigate('/onboarding?step=SOCIAL_LOGIN');
- return;
+ authStorage.setUserIdentity(email, userId);
+
+ if (accessToken) {
+ authStorage.setAccessToken(accessToken);
+ extensionBridge.syncToken(accessToken);
}
- loginWithCode(code);
- }, []);
+ if (refreshToken) {
+ authStorage.setRefreshToken(refreshToken);
+ }
- const handleUserLogin = (
- isUser: boolean,
- accessToken: string | null,
- refreshToken: string | null,
- hasJob?: boolean
- ) => {
- if (isUser) {
- if (accessToken) {
- authStorage.setAccessToken(accessToken);
- extensionBridge.syncToken(accessToken);
- }
-
- if (refreshToken) {
- authStorage.setRefreshToken(refreshToken);
- }
-
- if (typeof hasJob === 'boolean') {
- authStorage.setHasJob(hasJob);
- }
- navigate('/');
- } else {
- navigate('/onboarding?step=JOB');
+ if (typeof hasJob === 'boolean') {
+ authStorage.setHasJob(hasJob);
}
};
- const redirectUri = import.meta.env.VITE_GOOGLE_REDIRECT_URI;
-
const loginWithCode = async (code: string) => {
try {
const res = await apiRequest.post(
'/api/v3/auth/google',
- {
- code,
- uri: redirectUri,
- },
- {
- withCredentials: true,
- }
+ { code, uri: REDIRECT_URI },
+ { withCredentials: true }
);
const { isUser, userId, email, accessToken, refreshToken, hasJob } =
res.data.data;
- authStorage.setUserIdentity(email, userId);
+ saveSession({ accessToken, refreshToken, email, userId, hasJob });
queryClient.invalidateQueries({ queryKey: ['amplitudeUserProperties'] });
- handleUserLogin(isUser, accessToken, refreshToken, hasJob);
+ navigate(isUser ? '/' : '/onboarding?step=JOB');
} catch (error) {
console.error('로그인 오류:', error);
navigate('/onboarding?step=SOCIAL_LOGIN');
}
};
+ useEffect(() => {
+ const code = searchParams.get('code');
+
+ if (!code) {
+ alert('로그인 실패. 다시 시도해주세요.');
+ navigate('/onboarding?step=SOCIAL_LOGIN');
+ return;
+ }
+
+ loginWithCode(code);
+ }, []);
+
return (
diff --git a/apps/client/src/providers/AmplitudeProvider.tsx b/apps/client/src/providers/AmplitudeProvider.tsx
new file mode 100644
index 00000000..2cf66bf1
--- /dev/null
+++ b/apps/client/src/providers/AmplitudeProvider.tsx
@@ -0,0 +1,19 @@
+import { analytics } from '@pinback/analytics';
+import { useGetAmplitudeUserProperties } from '@shared/apis/queries';
+import { useEffect, type PropsWithChildren } from 'react';
+
+const AmplitudeProvider = ({ children }: PropsWithChildren) => {
+ const { data: userProperties } = useGetAmplitudeUserProperties();
+
+ useEffect(() => {
+ if (!userProperties) return;
+ analytics.identify(
+ String(userProperties.userId),
+ userProperties.jobRole ? { job_role: userProperties.jobRole } : undefined
+ );
+ }, [userProperties]);
+
+ return <>{children}>;
+};
+
+export default AmplitudeProvider;
diff --git a/apps/client/src/shared/apis/queries.ts b/apps/client/src/shared/apis/queries.ts
index 7498dbb3..7e9d699f 100644
--- a/apps/client/src/shared/apis/queries.ts
+++ b/apps/client/src/shared/apis/queries.ts
@@ -229,6 +229,7 @@ export const useGetAmplitudeUserProperties =
queryFn: getAmplitudeUserProperties,
staleTime: Infinity,
retry: false,
+ enabled: authStorage.hasAccessToken(),
});
};
diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts
index 8cd853a0..76f814ed 100644
--- a/apps/client/src/shared/apis/setting/axiosInstance.ts
+++ b/apps/client/src/shared/apis/setting/axiosInstance.ts
@@ -76,7 +76,7 @@ apiRequest.interceptors.response.use(
if (
error.response &&
- (error.response.status === 401 || error.response.status === 403) &&
+ error.response.status === 401 &&
!originalRequest._retry &&
!isNoAuth &&
!isLoginPage
diff --git a/packages/analytics/index.ts b/packages/analytics/index.ts
index e940f80d..ad59b9ab 100644
--- a/packages/analytics/index.ts
+++ b/packages/analytics/index.ts
@@ -1,6 +1,6 @@
import { analytics } from './src/analytics';
-import { amplitudeProvider } from './src/providers/amplitude';
-import { consoleProvider } from './src/providers/console';
+import { amplitudeAdapter } from './src/adapters/amplitude';
+import { consoleAdapter } from './src/adapters/console';
export type { AnalyticsProvider, UserProperties } from './src/types';
export type * from './src/ampli';
@@ -13,16 +13,16 @@ interface InitAnalyticsOptions {
export const initAnalytics = ({ apiKey, isDev }: InitAnalyticsOptions): void => {
if (isDev || !apiKey) {
- analytics.setProvider(consoleProvider);
+ analytics.setProvider(consoleAdapter);
return;
}
try {
- amplitudeProvider.init(apiKey);
- analytics.setProvider(amplitudeProvider);
+ amplitudeAdapter.init(apiKey);
+ analytics.setProvider(amplitudeAdapter);
} catch (error) {
- console.error('[Analytics] Failed to initialize Amplitude, falling back to console provider', error);
- analytics.setProvider(consoleProvider);
+ console.error('[Analytics] Failed to initialize Amplitude, falling back to console adapter', error);
+ analytics.setProvider(consoleAdapter);
}
};
diff --git a/packages/analytics/src/providers/amplitude.ts b/packages/analytics/src/adapters/amplitude.ts
similarity index 95%
rename from packages/analytics/src/providers/amplitude.ts
rename to packages/analytics/src/adapters/amplitude.ts
index 37a785fa..18009f6d 100644
--- a/packages/analytics/src/providers/amplitude.ts
+++ b/packages/analytics/src/adapters/amplitude.ts
@@ -2,7 +2,7 @@ import { Identify, identify, setUserId, reset, track, initAll } from '@amplitude
import type { AnalyticsProvider, UserProperties } from '../types';
-export const amplitudeProvider: AnalyticsProvider = {
+export const amplitudeAdapter: AnalyticsProvider = {
init(apiKey: string) {
initAll(apiKey, {
analytics: {
diff --git a/packages/analytics/src/providers/console.ts b/packages/analytics/src/adapters/console.ts
similarity index 86%
rename from packages/analytics/src/providers/console.ts
rename to packages/analytics/src/adapters/console.ts
index 5bf131a8..81ffc850 100644
--- a/packages/analytics/src/providers/console.ts
+++ b/packages/analytics/src/adapters/console.ts
@@ -1,6 +1,6 @@
import type { AnalyticsProvider } from '../types';
-export const consoleProvider: AnalyticsProvider = {
+export const consoleAdapter: AnalyticsProvider = {
init: (_apiKey) => console.log('[Analytics] init'),
track: (name, props) => console.log('[Analytics] track', name, props ?? {}),
identify: (userId, userProperties) => console.log('[Analytics] identify', { userId, ...userProperties }),
diff --git a/packages/analytics/src/providers/noop.ts b/packages/analytics/src/adapters/noop.ts
similarity index 75%
rename from packages/analytics/src/providers/noop.ts
rename to packages/analytics/src/adapters/noop.ts
index 52b0062f..59007fe5 100644
--- a/packages/analytics/src/providers/noop.ts
+++ b/packages/analytics/src/adapters/noop.ts
@@ -1,6 +1,6 @@
import type { AnalyticsProvider } from '../types';
-export const noopProvider: AnalyticsProvider = {
+export const noopAdapter: AnalyticsProvider = {
init: () => {},
track: () => {},
identify: (_userId: string) => {},
diff --git a/packages/analytics/src/analytics.ts b/packages/analytics/src/analytics.ts
index e49b2090..611c28f6 100644
--- a/packages/analytics/src/analytics.ts
+++ b/packages/analytics/src/analytics.ts
@@ -1,7 +1,7 @@
-import { noopProvider } from './providers/noop';
+import { noopAdapter } from './adapters/noop';
import type { AnalyticsProvider, UserProperties } from './types';
-let provider: AnalyticsProvider = noopProvider;
+let provider: AnalyticsProvider = noopAdapter;
export const analytics = {
setProvider(newProvider: AnalyticsProvider): void {