Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
f8faf87
[이제창] sprint2 (#43)
Jerang2 Jul 29, 2025
2564887
feat: sprintmission3
Jerang2 Aug 17, 2025
1439346
feat: image resize
Jerang2 Aug 17, 2025
f9a48f6
Merge branch '이제창' into main
rdd9223 Aug 25, 2025
39cde28
prisma.schema 수정
Jerang2 Sep 14, 2025
ac96417
prisma migrate
Jerang2 Sep 14, 2025
59e7d84
bcrypt install
Jerang2 Sep 14, 2025
ae377b5
UserService.js 생성
Jerang2 Sep 14, 2025
3f4b18c
users.router.js 생성
Jerang2 Sep 14, 2025
37122cf
ESM 방식 -> CommonJs 방식으로 수정
Jerang2 Sep 14, 2025
33c6e2b
회원가입 API 완료?
Jerang2 Sep 14, 2025
dab8731
오타 수정
Jerang2 Sep 14, 2025
d19e9be
UserService에 로그인 로직 추가
Jerang2 Sep 14, 2025
48dceef
users.router.js 로그인 API 추가
Jerang2 Sep 14, 2025
b6b9d10
articles.router.js 인증 미들웨어, 소유자 확인 로직 추가
Jerang2 Sep 14, 2025
f8b9b45
products.router.js 인증, 로그인 로직 추가
Jerang2 Sep 14, 2025
e1cf603
prisma.schema modify T.T
Jerang2 Sep 14, 2025
9b8d94e
바뀐 prisma.schema에 맞춰서 수정
Jerang2 Sep 14, 2025
48fcfe4
변경된 prisma.schema model로 products.router.js 수정
Jerang2 Sep 14, 2025
cb17c18
user.router.js 내 정보 수정 API 구현
Jerang2 Sep 14, 2025
71ca614
users.router.js 비밀번호 변경 API 추가
Jerang2 Sep 14, 2025
f8efc37
users.router.js 작성 상품 목록 조회 API 추가
Jerang2 Sep 14, 2025
df167d3
products.router.js에 좋아요 API 추가
Jerang2 Sep 14, 2025
5a421b0
오타 수정
Jerang2 Sep 14, 2025
f2f75e7
articles.router.js 좋아요 기능 추가
Jerang2 Sep 14, 2025
23a0531
optionalAuth.middleware.js 파일 생성
Jerang2 Sep 14, 2025
641ca6d
articles.router.js에 선택적 인증 미들웨어 추가
Jerang2 Sep 14, 2025
c4996fd
products.router.js에 상품목록조회 isLiked 필드 추가
Jerang2 Sep 14, 2025
a70d66d
articles.router.js에 isLiked 필드 추가
Jerang2 Sep 14, 2025
3cc2400
UseService.js의 로그인 로직을 access, refresh token를 받는 형식으로 변경
Jerang2 Sep 14, 2025
d9b1629
index.js에 cookie 미들웨어 추가
Jerang2 Sep 14, 2025
1d25f6f
오탈자 수정 및 index.js 라우트 설정 추가
Jerang2 Sep 14, 2025
4dcee1a
토큰 재발급 API 추가
Jerang2 Sep 14, 2025
f97e999
타입스크립트 js -> ts 로 변경
Jerang2 Sep 21, 2025
f434962
import문으로 수정
Jerang2 Sep 21, 2025
ac533c8
json수정, ts-node설치
Jerang2 Sep 21, 2025
b4e01d9
main.ts 수정
Jerang2 Sep 21, 2025
b665206
articels.router updateAt추가
Jerang2 Sep 21, 2025
57dfa67
products.router 수정
Jerang2 Sep 21, 2025
ae34280
select문 수정
Jerang2 Sep 21, 2025
d1bff8f
서버 구현 o
Jerang2 Sep 21, 2025
2032cc2
src로 이동후 repository add
Jerang2 Sep 21, 2025
29c9305
Service 리팩토링
Jerang2 Sep 21, 2025
60f5d7f
Controller 구현
Jerang2 Sep 21, 2025
b29cb20
roter 리팩토링
Jerang2 Sep 21, 2025
fa86962
DTO 생성
Jerang2 Sep 21, 2025
b7f019b
dto 추가, 사용하도록 수정
Jerang2 Sep 21, 2025
9bb1d8d
Service DTO 사용하도록 수정
Jerang2 Sep 21, 2025
4555a12
CommentService, LikeService 추가
Jerang2 Sep 21, 2025
6d7c540
Comment, LikeService 로 리팩토링
Jerang2 Sep 21, 2025
9c3506a
prisma와 관계 연결
Jerang2 Sep 21, 2025
823e702
import문 수정
Jerang2 Sep 21, 2025
9b6f392
controller - select문 수정
Jerang2 Sep 21, 2025
9261f17
controller - select문 수정 2
Jerang2 Sep 21, 2025
72f1bf1
findlikes 추가
Jerang2 Sep 21, 2025
e460353
signUp 메서드 수정
Jerang2 Sep 21, 2025
b60f8e1
UserService import 수정
Jerang2 Sep 21, 2025
ba427c8
import문 수정
Jerang2 Sep 21, 2025
64f1a15
cursor, data 객체 수정
Jerang2 Sep 21, 2025
b73fd07
Prisma.Product -> Product로 수정
Jerang2 Sep 21, 2025
a1b0d28
Prisma.Like -> Like
Jerang2 Sep 21, 2025
6c306f9
Prisma.xxx -> xxx 로 수정
Jerang2 Sep 21, 2025
3d9c8ec
README.md
Jerang2 Sep 21, 2025
d24de79
prettier 추가 및 실행
Jerang2 Sep 21, 2025
4c89673
Merge branch 'sprintmission5' of https://github.com/Jerang2/4-sprint-…
Jerang2 Sep 21, 2025
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
21 changes: 0 additions & 21 deletions .github/PULL_REQUEST_TEMPLATE.md

This file was deleted.

6 changes: 6 additions & 0 deletions .gitignore
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dist 하위의 빌드 파일은 커밋할 필요 없습니다. .gitignore에 해당 디렉토리를 추가해주세요.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
# Keep environment variables out of version control
.env
node_modules
uploads
/generated/prisma
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
스프린트 미션5
27 changes: 27 additions & 0 deletions dist/ArticleService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ArticleService {
constructor(articleRepository) {
this.articleRepository = articleRepository;
}
async createArticle(data) {
const { userId, ...rest } = data;
return this.articleRepository.createArticle({
...rest,
user: { connect: { id: userId } },
});
}
async getArticleById(id) {
return this.articleRepository.findArticleById(id);
}
async getArticles(options) {
return this.articleRepository.findArticles(options);
}
async updateArticle(id, data) {
return this.articleRepository.updateArticle(id, data);
}
async deleteArticle(id) {
return this.articleRepository.deleteArticle(id);
}
}
exports.default = ArticleService;
29 changes: 29 additions & 0 deletions dist/CommentService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class CommentService {
constructor(commentRepository) {
this.commentRepository = commentRepository;
}
async createComment(data) {
const { userId, productId, articleId, ...rest } = data;
return this.commentRepository.createComment({
...rest,
user: { connect: { id: userId } },
...(productId && { product: { connect: { id: productId } } }),
...(articleId && { article: { connect: { id: articleId } } }),
});
}
async getCommentById(id) {
return this.commentRepository.findCommentById(id);
}
async getComments(options) {
return this.commentRepository.findComments(options);
}
async updateComment(id, data) {
return this.commentRepository.updateComment(id, data);
}
async deleteComment(id) {
return this.commentRepository.deleteComment(id);
}
}
exports.default = CommentService;
29 changes: 29 additions & 0 deletions dist/LikeService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class LikeService {
constructor(likeRepository) {
this.likeRepository = likeRepository;
}
async createLike(data) {
const { userId, productId, articleId, ...rest } = data;
return this.likeRepository.createLike({
...rest,
user: { connect: { id: userId } },
...(productId && { product: { connect: { id: productId } } }),
...(articleId && { article: { connect: { id: articleId } } }),
});
}
async deleteLike(id) {
return this.likeRepository.deleteLike(id);
}
async findLikeByUserIdAndProductId(userId, productId) {
return this.likeRepository.findLikeByUserIdAndProductId(userId, productId);
}
async findLikeByUserIdAndArticleId(userId, articleId) {
return this.likeRepository.findLikeByUserIdAndArticleId(userId, articleId);
}
async findLikes(options) {
return this.likeRepository.findLikes(options);
}
}
exports.default = LikeService;
27 changes: 27 additions & 0 deletions dist/ProductService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ProductService {
constructor(productRepository) {
this.productRepository = productRepository;
}
async createProduct(data) {
const { userId, ...rest } = data;
return this.productRepository.createProduct({
...rest,
user: { connect: { id: userId } },
});
}
async getProductById(id) {
return this.productRepository.findProductById(id);
}
async getProducts(options) {
return this.productRepository.findProducts(options);
}
async updateProduct(id, data) {
return this.productRepository.updateProduct(id, data);
}
async deleteProduct(id) {
return this.productRepository.deleteProduct(id);
}
}
exports.default = ProductService;
66 changes: 66 additions & 0 deletions dist/UserService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bcrypt_1 = __importDefault(require("bcrypt"));
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
class UserService {
constructor(userRepository) {
// 회원가입 로직
this.signUp = async (userData) => {
const { email, nickname, password } = userData;
// 이메일 중복 확인
const existingUser = await this.userRepository.findUserByEmail(email);
if (existingUser) {
throw new Error('이미 사용중인 이메일입니다.');
}
// 비밀번호 해싱
const hashedPassword = await bcrypt_1.default.hash(password, 10);
// 유저 생성
const user = await this.userRepository.createUser({
email,
nickname,
password: hashedPassword,
});
// 사용자 정보 반환
const { password: _, refreshToken: __, ...userWithoutPassword } = user;
return userWithoutPassword;
};
this.signIn = async (email, password) => {
// 이메일로 사용자 조회
const user = await this.userRepository.findUserByEmail(email);
if (!user) {
throw new Error('존재하지 않는 이메일입니다.');
}
// 비밀번호 확인
const isPasswordMatched = await bcrypt_1.default.compare(password, user.password);
if (!isPasswordMatched) {
throw new Error('비밀번호가 일치하지 않습니다.');
}
// Access Token 생성 (12시간)
const accessToken = jsonwebtoken_1.default.sign({ userId: user.id }, process.env.JWT_SECRET_KEY, { expiresIn: '12h' });
// Refresh Token 생성 (7일)
const refreshToken = jsonwebtoken_1.default.sign({ userId: user.id }, process.env.REFRESH_TOKEN_SECRET_KEY, { expiresIn: '7d' });
// Refresh Token을 해싱해서 DB에 저장
await this.userRepository.updateUser(user.id, {
refreshToken: await bcrypt_1.default.hash(refreshToken, 10),
});
return { accessToken, refreshToken };
};
this.getUserById = async (id) => {
return this.userRepository.findUserById(id);
};
this.updateUser = async (id, data) => {
return this.userRepository.updateUser(id, data);
};
this.updatePassword = async (id, newPasswordHash) => {
return this.userRepository.updateUser(id, { password: newPasswordHash });
};
this.getProductsByUserId = async (userId) => {
return this.userRepository.findProductsByUserId(userId);
};
this.userRepository = userRepository;
}
}
exports.default = UserService;
Loading