Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: lendings에 v2 kysely 적용 #792

Draft
wants to merge 39 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
fa9559c
ci: 타입오류 메시지 상대경로 명시적으로 해소 (#643)
scarf005 Sep 7, 2023
93fc7b4
feat: v2 book api (#746)
JeongJiHwan Sep 7, 2023
8b7c07f
style: prettier 적용 (#761)
scarf005 Sep 7, 2023
c88ca8d
[fix] backend dockerfile error (#764)
weg901127 Sep 8, 2023
1565441
fix: `positiveInt` -> `nonNegativeInt` (#766)
scarf005 Sep 11, 2023
6cbb823
refactor: v2 라우트 정리 적용 (#771)
scarf005 Sep 14, 2023
1ac5b23
feat: add mydata service
jimin52 Sep 21, 2023
7094331
feat: 유저 search 할 때 id 가 undefined 인 경우 핸들링
jimin52 Sep 21, 2023
1c8b49b
feat: add swagger && /me endpoint && apply authValidate
jimin52 Sep 21, 2023
71c1216
Merge branch 'develop' into 778-auth-관련-api-무조건-200-리턴-버그
jimin52 Sep 21, 2023
5754bef
fix: searchUsersById 타입을 이전과 같이 리턴하도록 변경
jimin52 Sep 21, 2023
7fbfa10
Merge branch '778-auth-관련-api-무조건-200-리턴-버그' of https://github.com/ji…
jimin52 Sep 21, 2023
1449028
fix: add librarian validate in search endpoint
jimin52 Sep 21, 2023
cda9990
feat: 로그인한 유저만 본인 정보를 찾을 수 있도록 middleware 에서 권한 체크
jimin52 Sep 26, 2023
7b7ad82
chore: console.log 제거
jimin52 Sep 26, 2023
c5bd7ae
Merge pull request #779 from jiphyeonjeon-42/778-auth-관련-api-무조건-200-…
jimin52 Oct 1, 2023
cf970dd
User API 경로 정리 (#777)
nyj001012 Oct 23, 2023
d7bca34
fix(cursus): Access-Control-Allow-Origin 설정 (#790)
nyj001012 Oct 25, 2023
d8c7972
style(v2): 불필요한 import 삭제
nyj001012 Oct 28, 2023
3699ae0
feat(contracts): kysely generator에서 만들어준 스키마와 타입 동일하게 함
nyj001012 Oct 28, 2023
0b068bb
refactor(v2): 마이페이지 대출기록 함수에 kysely 적용
nyj001012 Oct 28, 2023
9e60d43
refactor(v2): 사용자 대출기록 함수에 kysely 적용
nyj001012 Oct 28, 2023
e4a0ea0
refactor(v2): 반환 데이터를 리스트에서 오브젝트로 변경
nyj001012 Oct 28, 2023
5545881
refactor(reviews): 불필요한 import 삭제
nyj001012 Oct 30, 2023
a41757f
chore(deps): dependencies에 ts-rest/core, zod 추가
nyj001012 Oct 30, 2023
eb4a6d4
chore(deps): dev dependencies에 ts-rest/core, zod 추가
nyj001012 Oct 30, 2023
e92db3c
Revert "chore(deps): dev dependencies에 ts-rest/core, zod 추가"
nyj001012 Oct 30, 2023
8922c38
chore(deps): npm-pre-gyp 설치
nyj001012 Oct 30, 2023
f1e20c3
chore(deps): 패키지 일괄 update
nyj001012 Oct 30, 2023
ffc45ad
Revert "chore(deps): dev dependencies에 ts-rest/core, zod 추가"
nyj001012 Oct 30, 2023
53da6fd
chore: dependencies 업데이트 (#796)
nyj001012 Nov 6, 2023
ce78720
Merge branch 'develop' into 783-v2-kysely-시범-사용
nyj001012 Nov 6, 2023
2f30aaf
chore(deps): pnpm-lock 업데이트
nyj001012 Nov 6, 2023
2fee63a
fix(lendings): AllSelection import 경로 수정
nyj001012 Nov 6, 2023
4583ed1
chore(deps): 의존성 수정
nyj001012 Nov 6, 2023
a3a17ce
Revert "fix(lendings): AllSelection import 경로 수정"
nyj001012 Nov 6, 2023
5d1f614
chore(deps): 의존성 동기화
nyj001012 Nov 6, 2023
c31ae31
Revert "chore(deps): pnpm-lock 업데이트"
nyj001012 Nov 6, 2023
daec465
chore(deps): 의존성 동기화
nyj001012 Nov 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"jest": true
},
"root": true,
"extends": ["airbnb-base", "plugin:@typescript-eslint/recommended"],
"extends": ["airbnb-base", "plugin:@typescript-eslint/recommended", "prettier"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "import"],
"parserOptions": {
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ name: Test
on:
pull_request:

defaults:
run:
shell: bash

jobs:
test:
name: Test PR
runs-on: ubuntu-latest
environment: development

steps:
- uses: reviewdog/action-setup@v1

- name: Checkout
uses: actions/checkout@v3

Expand Down Expand Up @@ -40,12 +46,7 @@ jobs:
pnpm install --frozen-lockfile
pnpm --filter='@jiphyeonjeon-42/contracts' build

- if: always()
name: check types (backend)
working-directory: backend
run: pnpm check

- if: always()
name: check types (contracts)
working-directory: contracts
run: pnpm check
- name: check types
if: always()
run: |
pnpm -r --no-bail --parallel run check | sed -r 's|(.*)( check: )(.*)|\1/\3|'
7 changes: 7 additions & 0 deletions .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
semi: true
singleQuote: true
useTabs: false
tabWidth: 2
trailingComma: all
printWidth: 100
arrowParens: always
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ FROM node:18-alpine as pnpm-installed
# https://github.com/pnpm/pnpm/issues/4495#issuecomment-1317831712
ENV PNPM_HOME="/root/.local/share/pnpm"
ENV PATH="${PATH}:${PNPM_HOME}"
ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
RUN python3 -m ensurepip
RUN pip3 install --no-cache --upgrade pip setuptools
RUN apk add --no-cache make
RUN apk add build-base
RUN npm install --global pnpm
RUN pnpm config set store-dir .pnpm-store
RUN pnpm install --global node-pre-gyp
Expand Down
82 changes: 42 additions & 40 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,72 @@
"schema": ". ./.env && DATABASE_URL=mysql://$RDS_USERNAME:$RDS_PASSWORD@$RDS_HOSTNAME:3306/$RDS_DB_NAME kysely-codegen --dialect=mysql --out-file=src/kysely/generated.ts"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/cookie-parser": "^1.4.3",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/http-errors": "^2.0.1",
"@types/jest": "^29.5.2",
"@types/jsonwebtoken": "^9.0.2",
"@types/morgan": "^1.9.4",
"@types/node-schedule": "^2.1.0",
"@types/passport": "^1.0.12",
"@types/passport-jwt": "^3.0.8",
"@types/swagger-jsdoc": "^6.0.1",
"@types/swagger-ui-express": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"eslint": "^8.45.0",
"@types/bcrypt": "^5.0.1",
"@types/cookie-parser": "^1.4.5",
"@types/cors": "^2.8.15",
"@types/express": "^4.17.20",
"@types/http-errors": "^2.0.3",
"@types/jest": "^29.5.6",
"@types/jsonwebtoken": "^9.0.4",
"@types/morgan": "^1.9.7",
"@types/node-schedule": "^2.1.2",
"@types/passport": "^1.0.14",
"@types/passport-jwt": "^3.0.12",
"@types/swagger-jsdoc": "^6.0.2",
"@types/swagger-ui-express": "^4.1.5",
"@typescript-eslint/eslint-plugin": "^6.9.0",
"@typescript-eslint/parser": "^6.9.0",
"eslint": "^8.52.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"jest": "^29.5.0",
"jest-mock-extended": "^3.0.4",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.0",
"jest": "^29.7.0",
"jest-mock-extended": "^3.0.5",
"kysely-codegen": "^0.10.1",
"nodemon": "^3.0.1",
"prettier": "^2.8.8",
"ts-jest": "^29.1.0",
"ts-jest": "^29.1.1",
"typeorm-model-generator": "^0.4.6"
},
"dependencies": {
"@jiphyeonjeon-42/contracts": "workspace:*",
"@mapbox/node-pre-gyp": "^1.0.11",
"@slack/web-api": "^6.7.1",
"@ts-rest/express": "^3.28.0",
"@ts-rest/open-api": "^3.28.0",
"axios": "^0.27.2",
"bcrypt": "^5.0.1",
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"date-fns": "^2.29.3",
"dotenv": "^16.0.0",
"express": "^4.17.2",
"express-rate-limit": "^6.9.0",
"date-fns": "^2.30.0",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-rate-limit": "^6.11.2",
"hangul-js": "^0.2.6",
"http-errors": "^2.0.0",
"http-status": "^1.5.0",
"http-status": "^1.7.3",
"http-terminator": "^3.2.0",
"jsonwebtoken": "^8.5.1",
"kysely": "^0.26.1",
"kysely": "^0.26.3",
"kysely-paginate": "^0.2.0",
"morgan": "^1.10.0",
"mysql2": "^2.3.3",
"node-schedule": "^2.1.0",
"passport": "^0.5.2",
"node-pre-gyp": "^0.17.0",
"node-schedule": "^2.1.1",
"passport": "^0.5.3",
"passport-42": "^1.2.6",
"passport-jwt": "^4.0.0",
"passport-jwt": "^4.0.1",
"passport-strategy": "^1.0.0",
"password-validator": "^5.3.0",
"reflect-metadata": "^0.1.13",
"swagger-jsdoc": "^6.1.0",
"swagger-ui-express": "^4.3.0",
"ts-pattern": "^5.0.1",
"typeorm": "^0.3.11",
"vite": "^4.4.7",
"vite-node": "^0.34.1",
"vite-tsconfig-paths": "^4.2.0",
"winston": "^3.6.0",
"winston-daily-rotate-file": "^4.6.1"
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^4.6.3",
"ts-pattern": "^5.0.5",
"typeorm": "^0.3.17",
"vite": "^4.5.0",
"vite-node": "^0.34.6",
"vite-tsconfig-paths": "^4.2.1",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1"
}
}
12 changes: 6 additions & 6 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ app.use(
// dev route
app.use('/api', router);

// dev/v2 route
createExpressEndpoints(contract, routerV2, app, {
logInitialization: true,
responseValidation: true,
jsonQuery: true,
});
// // dev/v2 route
// createExpressEndpoints(contract, routerV2, app, {
// logInitialization: true,
// responseValidation: true,
// jsonQuery: true,
// });

// 에러 핸들러
app.use(errorConverter);
Expand Down
24 changes: 13 additions & 11 deletions backend/src/config/JwtOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import { Mode } from './modeOption';
import { match } from 'ts-pattern';

type getJwtOption = (mode: Mode) => (option: OauthUrlOption) => JwtOption;
export const getJwtOption: getJwtOption = (mode) => ({ redirectURL, clientURL }) => {
const redirectDomain = new URL(redirectURL).hostname;
const clientDomain = new URL(clientURL).hostname;
const secure = mode === 'prod' || mode === 'https';
export const getJwtOption: getJwtOption =
(mode) =>
({ redirectURL, clientURL }) => {
const redirectDomain = new URL(redirectURL).hostname;
const clientDomain = new URL(clientURL).hostname;
const secure = mode === 'prod' || mode === 'https';

const issuer = secure ? redirectDomain : 'localhost';
const domain = match(mode)
.with('prod', () => clientDomain)
.with('https', () => undefined)
.otherwise(() => 'localhost');
const issuer = secure ? redirectDomain : 'localhost';
const domain = match(mode)
.with('prod', () => clientDomain)
.with('https', () => undefined)
.otherwise(() => 'localhost');

return { issuer, domain, secure };
};
return { issuer, domain, secure };
};

export const jwtSecretSchema = z.object({ JWT_SECRET: nonempty }).transform((v) => v.JWT_SECRET);

Expand Down
10 changes: 5 additions & 5 deletions backend/src/config/config.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type NaverBookApiOption = {

/** 네이버 도서 검색 API 시크릿 */
secret: string;
}
};

/** DB 연결 옵션 */
export type ConnectOption = {
Expand All @@ -34,7 +34,7 @@ export type ConnectOption = {

/** DB 이름 */
database: string;
}
};

/** OAuth URL 옵션 */
export type OauthUrlOption = {
Expand All @@ -43,7 +43,7 @@ export type OauthUrlOption = {

/** 집현전 프론트엔드 URL */
clientURL: string;
}
};

/** 42 API OAuth 클라이언트 인증 정보 */
export type Oauth42ApiOption = {
Expand All @@ -52,7 +52,7 @@ export type Oauth42ApiOption = {

/** 42 API OAuth 클라이언트 시크릿 */
secret: string;
}
};

/** npm 로깅 레벨 */
export type LogLevel = keyof typeof levels;
Expand All @@ -64,4 +64,4 @@ export type LogLevelOption = {

/** 콘솔 로깅 레벨 */
readonly consoleLogLevel: 'error' | 'debug';
}
};
18 changes: 11 additions & 7 deletions backend/src/config/dbSchema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { envObject, nonempty } from './envObject';

/** RDS 연결 옵션 파싱을 위한 스키마 */
export const rdsSchema = envObject('RDS_HOSTNAME', 'RDS_USERNAME', 'RDS_PASSWORD', 'RDS_DB_NAME')
.transform((v) => ({
host: v.RDS_HOSTNAME,
username: v.RDS_USERNAME,
password: v.RDS_PASSWORD,
database: v.RDS_DB_NAME,
}));
export const rdsSchema = envObject(
'RDS_HOSTNAME',
'RDS_USERNAME',
'RDS_PASSWORD',
'RDS_DB_NAME',
).transform((v) => ({
host: v.RDS_HOSTNAME,
username: v.RDS_USERNAME,
password: v.RDS_PASSWORD,
database: v.RDS_DB_NAME,
}));

/** MYSQL 연결 옵션 파싱을 위한 스키마 */
const mysqlSchema = envObject('MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE')
Expand Down
2 changes: 1 addition & 1 deletion backend/src/config/envObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const url = z.string().trim().url();
* @param keys 환경변수 키 목록
*/
export const envObject = <T extends readonly string[]>(...keys: T) => {
type Keys = T[ number ];
type Keys = T[number];
const env = Object.fromEntries(keys.map((key) => [key, nonempty]));

return z.object(env as Record<Keys, typeof nonempty>);
Expand Down
10 changes: 6 additions & 4 deletions backend/src/config/getConnectOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ const getConnectOptionSchema = (mode: Mode) => {
/**
* 환경변수에서 DB 연결 옵션을 파싱하는 함수
*/
export const getConnectOption = (mode: Mode) => (processEnv: NodeJS.ProcessEnv): ConnectOption => {
const connectOptionSchema = getConnectOptionSchema(mode);
export const getConnectOption =
(mode: Mode) =>
(processEnv: NodeJS.ProcessEnv): ConnectOption => {
const connectOptionSchema = getConnectOptionSchema(mode);

return connectOptionSchema.parse(processEnv);
};
return connectOptionSchema.parse(processEnv);
};
4 changes: 2 additions & 2 deletions backend/src/config/logOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export const colors: Record<LogLevel, string> = {
} as const;

export const getLogLevelOption = (mode: RuntimeMode): LogLevelOption => {
const logLevel = (mode === 'production' ? 'http' : 'debug');
const consoleLogLevel = (mode === 'production' ? 'error' : 'debug');
const logLevel = mode === 'production' ? 'http' : 'debug';
const consoleLogLevel = mode === 'production' ? 'error' : 'debug';

return { logLevel, consoleLogLevel } as const;
};
12 changes: 7 additions & 5 deletions backend/src/config/naverBookApiOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import { NaverBookApiOption } from './config.type';
import { envObject } from './envObject';

const naverBookApiSchema = envObject('NAVER_BOOK_SEARCH_CLIENT_ID', 'NAVER_BOOK_SEARCH_SECRET')
.transform((v) => ({
client: v.NAVER_BOOK_SEARCH_CLIENT_ID,
secret: v.NAVER_BOOK_SEARCH_SECRET,
}));
const naverBookApiSchema = envObject(
'NAVER_BOOK_SEARCH_CLIENT_ID',
'NAVER_BOOK_SEARCH_SECRET',
).transform((v) => ({
client: v.NAVER_BOOK_SEARCH_CLIENT_ID,
secret: v.NAVER_BOOK_SEARCH_SECRET,
}));

export const getNaverBookApiOption = (processEnv: NodeJS.ProcessEnv): NaverBookApiOption => {
const option = naverBookApiSchema.parse(processEnv);
Expand Down
24 changes: 14 additions & 10 deletions backend/src/config/oauthOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ export const oauth42Schema = z.object({
CLIENT_SECRET: nonempty,
});

export const getOauthUrlOption = (processEnv: NodeJS.ProcessEnv): OauthUrlOption => oauthUrlSchema
.transform((v) => ({
redirectURL: v.REDIRECT_URL,
clientURL: v.CLIENT_URL,
})).parse(processEnv);
export const getOauthUrlOption = (processEnv: NodeJS.ProcessEnv): OauthUrlOption =>
oauthUrlSchema
.transform((v) => ({
redirectURL: v.REDIRECT_URL,
clientURL: v.CLIENT_URL,
}))
.parse(processEnv);

// eslint-disable-next-line max-len
export const getOauth42ApiOption = (processEnv: NodeJS.ProcessEnv): Oauth42ApiOption => oauth42Schema
.transform((v) => ({
id: v.CLIENT_ID,
secret: v.CLIENT_SECRET,
})).parse(processEnv);
export const getOauth42ApiOption = (processEnv: NodeJS.ProcessEnv): Oauth42ApiOption =>
oauth42Schema
.transform((v) => ({
id: v.CLIENT_ID,
secret: v.CLIENT_SECRET,
}))
.parse(processEnv);
Loading
Loading