Skip to content

Commit d64fe3a

Browse files
authored
feat: 어시스턴트 봇 생성 api 연동
2 parents f0ed679 + 9283dea commit d64fe3a

File tree

16 files changed

+596
-164
lines changed

16 files changed

+596
-164
lines changed

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"tabWidth": 4,
3+
"useTabs": false,
4+
"singleQuote": true,
5+
"semi": true
6+
}

eslint.config.js

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,30 @@
1-
import react from 'eslint-plugin-react';
1+
import eslintPluginReact from 'eslint-plugin-react';
2+
import babelParser from '@babel/eslint-parser';
23

34
export default [
4-
{
5-
ignores: ['dist'],
6-
languageOptions: {
7-
parserOptions: {
8-
ecmaVersion: 'latest',
9-
ecmaFeatures: { jsx: true },
10-
sourceType: 'module',
11-
requireConfigFile: false,
12-
},
5+
{
6+
ignores: ['dist'],
7+
languageOptions: {
8+
parser: babelParser,
9+
parserOptions: {
10+
ecmaVersion: 'latest',
11+
ecmaFeatures: { jsx: true },
12+
sourceType: 'module',
13+
requireConfigFile: false,
14+
},
15+
},
16+
plugins: {
17+
react: eslintPluginReact,
18+
},
19+
settings: {
20+
react: { version: 'detect' },
21+
},
22+
rules: {
23+
indent: ['error', 4],
24+
'react/jsx-indent': ['error', 4],
25+
'react/jsx-indent-props': ['error', 4],
26+
quotes: ['error', 'single'],
27+
'no-console': 'off',
28+
},
1329
},
14-
rules: {
15-
quotes: ['error', 'single'],
16-
'no-console': 'off',
17-
},
18-
},
19-
// .js 파일 전용 설정
20-
{
21-
files: ['**/*.js'],
22-
rules: {
23-
'no-console': 'warn',
24-
},
25-
},
26-
// .jsx 파일 전용 설정
27-
{
28-
files: ['**/*.jsx'],
29-
plugins: { react },
30-
settings: {
31-
react: { version: 'detect' },
32-
},
33-
rules: {
34-
'react/prop-types': 'off',
35-
},
36-
},
3730
];

package-lock.json

Lines changed: 91 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"@emotion/react": "^11.13.3",
1515
"@emotion/styled": "^11.13.0",
1616
"@reduxjs/toolkit": "^2.3.0",
17+
"@tanstack/react-query": "^5.66.0",
1718
"axios": "^1.7.7",
1819
"branchify": "file:",
1920
"framer-motion": "^11.11.17",
@@ -24,6 +25,7 @@
2425
"redux": "^5.0.1"
2526
},
2627
"devDependencies": {
28+
"@babel/eslint-parser": "^7.26.8",
2729
"@eslint/eslintrc": "^3.1.0",
2830
"@eslint/js": "^9.13.0",
2931
"@types/react": "^18.3.12",

src/App.jsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
12
import { RouterProvider } from 'react-router-dom';
23
import router from './routes';
34
import { Provider } from 'react-redux';
45
import store from './stores/store';
56

7+
const queryClient = new QueryClient();
8+
69
function App() {
7-
return (
8-
<Provider store={store}>
9-
<RouterProvider router={router} />
10-
</Provider>
11-
);
10+
return (
11+
<QueryClientProvider client={queryClient}>
12+
<Provider store={store}>
13+
<RouterProvider router={router} />
14+
</Provider>
15+
</QueryClientProvider>
16+
);
1217
}
1318

1419
export default App;

src/api/api.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import axios from 'axios';
33
// API 인스턴스 생성
44
const API = axios.create({
55
baseURL: 'https://www.branchify.site/api/',
6-
withCredentials: true // 모든 요청에 쿠키 포함 (refreshToken 자동 전송)
6+
withCredentials: true, // 모든 요청에 쿠키 포함 (refreshToken 자동 전송)
77
});
88

99
// access token 갱신 함수
1010
const refreshAccessToken = async () => {
1111
try {
1212
const response = await axios.post(
13-
'/user/refresh-token',
14-
{},
13+
'/user/refresh-token',
14+
{},
1515
{ withCredentials: true } // 서버에 refreshToken 쿠키 자동 전송
1616
);
1717

@@ -23,26 +23,32 @@ const refreshAccessToken = async () => {
2323
throw new Error('새로운 access token을 받지 못했습니다.');
2424
}
2525
} catch (error) {
26-
console.error('access token 갱신 실패:', error.response?.data || error.message);
26+
console.error(
27+
'access token 갱신 실패:',
28+
error.response?.data || error.message
29+
);
2730
return null;
2831
}
2932
};
3033

3134
// 요청 인터셉터 (모든 API 요청에 자동으로 access_token 추가)
32-
API.interceptors.request.use(async (config) => {
33-
let accessToken = localStorage.getItem('access_token');
35+
API.interceptors.request.use(
36+
async (config) => {
37+
let accessToken = localStorage.getItem('access_token');
3438

35-
if (!accessToken) {
36-
accessToken = await refreshAccessToken(); // 토큰 갱신 요청
37-
}
39+
if (!accessToken) {
40+
accessToken = await refreshAccessToken(); // 토큰 갱신 요청
41+
}
3842

39-
if (accessToken) {
40-
config.headers.Authorization = `Bearer ${accessToken}`;
41-
}
43+
if (accessToken) {
44+
config.headers.Authorization = `Bearer ${accessToken}`;
45+
}
4246

43-
return config;
44-
}, (error) => {
45-
return Promise.reject(error);
46-
});
47+
return config;
48+
},
49+
(error) => {
50+
return Promise.reject(error);
51+
}
52+
);
4753

4854
export default API;

src/api/assistantAPI.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import axios from 'axios';
2+
3+
const API_BASE_URL = 'https://www.branchify.site/api';
4+
5+
// 어시스턴트 생성 API (POST 요청)
6+
export const createAssistant = async ({
7+
modelName,
8+
openaiApiKey,
9+
assistantName,
10+
prompt,
11+
}) => {
12+
const accessToken = localStorage.getItem('access_token');
13+
14+
const response = await axios.post(
15+
`${API_BASE_URL}/assistantlist`,
16+
{ modelName, openaiApiKey, assistantName, prompt },
17+
{
18+
headers: {
19+
Authorization: `Bearer ${accessToken}`,
20+
'Content-Type': 'application/json',
21+
},
22+
}
23+
);
24+
25+
return response.data;
26+
};
27+
28+
//어시스턴트 업데이트 (Step 3에서 호출)
29+
export const updateAssistant = async ({ assistantName, actionTags }) => {
30+
if (
31+
!assistantName ||
32+
typeof assistantName !== 'string' ||
33+
assistantName.trim() === ''
34+
) {
35+
throw new Error(
36+
'유효하지 않은 assistantName입니다. 요청을 보낼 수 없습니다.'
37+
);
38+
}
39+
40+
const accessToken = localStorage.getItem('access_token');
41+
42+
try {
43+
console.log(
44+
'최종 PATCH URL:',
45+
`${API_BASE_URL}/assistantlist/${assistantName}`
46+
);
47+
console.log('보낼 데이터:', { actionTags });
48+
49+
const response = await axios.patch(
50+
`${API_BASE_URL}/assistantlist/${assistantName}`,
51+
{ actionTag: actionTags },
52+
{
53+
headers: {
54+
Authorization: `Bearer ${accessToken}`,
55+
'Content-Type': 'application/json',
56+
},
57+
}
58+
);
59+
return response.data;
60+
} catch (error) {
61+
console.error(
62+
'Error updating assistant:',
63+
error.response?.data || error.message
64+
);
65+
throw error;
66+
}
67+
};

0 commit comments

Comments
 (0)