Skip to content

Commit 6206aef

Browse files
authored
Merge pull request #382 from boostcampwm-2024/develop
[Refactor] 프로젝트 구조, 코드 품질 및 인증 시스템 개선 (FSD, SonarQube, Socket.IO)
2 parents 8cbbfe9 + 632446f commit 6206aef

File tree

180 files changed

+2831
-2218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+2831
-2218
lines changed

apps/chat/src/auth/jwt-auth.guard.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import { ErrorStatus } from 'src/common/responses/exceptions/errorStatus';
88
export class JWTAuthGuard extends AuthGuard('jwt') {
99
getRequest(context: ExecutionContext) {
1010
const client = context.switchToWs().getClient<Socket>();
11+
const authorization = client.handshake.auth.accessToken || client.handshake.headers.accesstoken;
1112

1213
return {
1314
headers: {
14-
authorization: client.handshake.auth.accessToken,
15+
authorization,
1516
},
1617
};
1718
}

apps/client/.eslintignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# shadcn/ui 컴포넌트 폴더 무시
2+
src/shared/ui/shadcn/*
3+
4+
# node_modules는 기본적으로 무시되지만, 명시적으로 추가할 수도 있습니다
5+
node_modules/
6+
7+
# 다른 무시하고 싶은 파일/폴더들
8+
dist/
9+
build/

apps/client/.eslintrc

+36-9
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,45 @@
11
{
22
"parser": "@typescript-eslint/parser",
3+
34
"parserOptions": {
4-
"project": ["./apps/client/tsconfig.json"],
5+
"project": ["./tsconfig.json"],
56
"ecmaVersion": 12,
67
"sourceType": "module",
78
"ecmaFeatures": {
89
"jsx": true
910
}
1011
},
12+
1113
"env": {
1214
"browser": true,
1315
"es2021": true
1416
},
15-
"extends": [
16-
"eslint:recommended",
17-
"plugin:react/recommended",
18-
"plugin:react-hooks/recommended",
19-
"plugin:@typescript-eslint/recommended",
20-
"prettier"
21-
],
17+
18+
"extends": ["airbnb", "airbnb/hooks", "plugin:@typescript-eslint/recommended", "prettier"],
19+
2220
"settings": {
2321
"react": {
2422
"version": "detect"
2523
}
2624
},
25+
2726
"plugins": ["prettier"],
27+
2828
"rules": {
29+
// React 관련 규칙
2930
"react/react-in-jsx-scope": "off",
3031
"react/no-unescaped-entities": "off",
3132
"react/prop-types": "off",
32-
"react-hooks/exhaustive-deps": "warn",
33+
"react/jsx-filename-extension": [
34+
"warn",
35+
{
36+
"extensions": [".js", ".jsx", ".ts", ".tsx"]
37+
}
38+
],
39+
"react/require-default-props": "off",
40+
"react/jsx-props-no-spreading": "off",
41+
42+
// TypeScript 관련 규칙
3343
"@typescript-eslint/no-explicit-any": "warn",
3444
"@typescript-eslint/no-unused-vars": [
3545
"error",
@@ -38,6 +48,23 @@
3848
"varsIgnorePattern": "^_", // _ 로 시작하는 변수는 무시
3949
"ignoreRestSiblings": true
4050
}
51+
],
52+
53+
// Import/Export 관련 규칙
54+
"import/no-unresolved": "off",
55+
"import/extensions": ["off"],
56+
"import/prefer-default-export": "off",
57+
"no-restricted-exports": "warn",
58+
59+
// 접근성 관련 규칙
60+
"jsx-a11y/media-has-caption": "off",
61+
62+
// 기타 규칙
63+
"no-param-reassign": [
64+
"warn",
65+
{
66+
"props": false
67+
}
4168
]
4269
}
4370
}

apps/client/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
26+
# Sonar
27+
.sonar/
28+
.scannerwork/

apps/client/package.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"dev": "vite",
88
"build": "tsc -b && vite build",
99
"lint": "eslint",
10-
"preview": "vite preview"
10+
"preview": "vite preview",
11+
"sonar": "sonar-scanner"
1112
},
1213
"dependencies": {
1314
"@radix-ui/react-avatar": "^1.1.1",
@@ -33,17 +34,25 @@
3334
"@types/node": "^20.3.1",
3435
"@types/react": "^18.3.12",
3536
"@types/react-dom": "^18.3.1",
37+
"@typescript-eslint/eslint-plugin": "^7.18.0",
38+
"@typescript-eslint/parser": "^7.18.0",
3639
"@vitejs/plugin-react-swc": "^3.5.0",
3740
"autoprefixer": "^10.4.20",
3841
"eslint": "*",
42+
"eslint-config-airbnb": "^19.0.4",
43+
"eslint-config-airbnb-typescript": "^18.0.0",
3944
"eslint-config-prettier": "*",
45+
"eslint-plugin-import": "^2.31.0",
46+
"eslint-plugin-jsx-a11y": "^6.10.2",
4047
"eslint-plugin-prettier": "*",
4148
"eslint-plugin-react": "^7.37.2",
4249
"eslint-plugin-react-hooks": "^5.0.0",
4350
"eslint-plugin-react-refresh": "^0.4.14",
4451
"postcss": "^8.4.47",
4552
"prettier": "*",
53+
"sonarqube-scanner": "^4.2.6",
4654
"tailwindcss": "^3.4.14",
55+
"typescript": "*",
4756
"vite": "^5.4.10"
4857
}
4958
}

apps/client/sonar-project.properties

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sonar.projectKey=CamOn
2+
sonar.sources=.
3+
sonar.host.url=http://localhost:9000

apps/client/src/App.css

-4
This file was deleted.

apps/client/src/App.tsx

-24
This file was deleted.

apps/client/src/Router.tsx

-71
This file was deleted.
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Outlet } from 'react-router-dom';
2+
import { Toaster } from '@/shared/ui/shadcn/toaster';
3+
import { Header } from '@/widgets';
4+
import { FloatingButton } from '@/shared/ui';
5+
import { Providers } from '../providers';
6+
7+
export function Layout() {
8+
return (
9+
<Providers>
10+
<Header />
11+
<main className="pt-[74px] h-full">
12+
<Outlet />
13+
</main>
14+
<Toaster />
15+
<FloatingButton />
16+
</Providers>
17+
);
18+
}

apps/client/src/app/layouts/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Layout } from './Layout';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useMemo, useState } from 'react';
2+
import { AuthContext } from '@/shared/contexts';
3+
import { ProviderProps } from './types';
4+
5+
export function AuthProvider({ children }: ProviderProps) {
6+
const [isLoggedIn, setIsLoggedIn] = useState(() => !!localStorage.getItem('accessToken'));
7+
const value = useMemo(() => ({ isLoggedIn, setIsLoggedIn }), [isLoggedIn, setIsLoggedIn]);
8+
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { ThemeProvider } from '@/app/providers/ThemeProvider';
2+
import { AuthProvider } from '@/app/providers/AuthProvider';
3+
import { ProviderProps } from './types';
4+
5+
export function Providers({ children }: ProviderProps) {
6+
return (
7+
<AuthProvider>
8+
<ThemeProvider>{children}</ThemeProvider>
9+
</AuthProvider>
10+
);
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { useMemo, useState } from 'react';
2+
import { ThemeContext } from '@/shared/contexts';
3+
import { ProviderProps } from './types';
4+
5+
type Theme = 'light' | 'dark' | null;
6+
7+
export function ThemeProvider({ children }: ProviderProps) {
8+
const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem('theme') as Theme) ?? null);
9+
const value = useMemo(() => ({ theme, setTheme }), [theme, setTheme]);
10+
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
11+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Providers } from './Providers';
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type ProviderProps = Readonly<{ children: React.ReactNode }>;

apps/client/src/ProtectedRoute.tsx renamed to apps/client/src/app/routes/ProtectedRoute.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useContext } from 'react';
2-
import { AuthContext } from '@contexts/AuthContext';
32
import { Navigate, Outlet } from 'react-router-dom';
3+
import { AuthContext } from '@/features/auth/model/AuthContext';
44

55
function ProtectedRoute() {
66
const { isLoggedIn } = useContext(AuthContext);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { routerOptions } from './options';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const routerOptions = {
2+
future: {
3+
v7_startTransition: true,
4+
v7_relativeSplatPath: true,
5+
v7_fetcherPersist: true,
6+
v7_normalizeFormMethod: true,
7+
v7_partialHydration: true,
8+
v7_skipActionErrorRevalidation: true,
9+
},
10+
};

apps/client/src/app/routes/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { router } from './router';

0 commit comments

Comments
 (0)