Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
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
1718414
feat: add notification
Jerang2 Nov 12, 2025
f7a3dc3
feat: send notification
Jerang2 Nov 12, 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
6 changes: 6 additions & 0 deletions .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
}
90 changes: 0 additions & 90 deletions ArticleService.js

This file was deleted.

110 changes: 0 additions & 110 deletions ProductService.js

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
스프린트 미션2
스프린트 미션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;
39 changes: 39 additions & 0 deletions dist/CommentService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class CommentService {
constructor(commentRepository, articleRepository, notificationService) {
this.commentRepository = commentRepository;
this.articleRepository = articleRepository;
this.notificationService = notificationService;
}
async createComment(data) {
const { userId, productId, articleId, ...rest } = data;
const createdComment = await this.commentRepository.createComment({
...rest,
user: { connect: { id: userId } },
...(productId && { product: { connect: { id: productId } } }),
...(articleId && { article: { connect: { id: articleId } } }),
});
if (articleId) {
const article = await this.articleRepository.findArticleById(articleId);
if (article && article.userId !== userId) {
const message = `'${article.title}' 게시글에 새로운 댓글이 달렸습니다.`;
await this.notificationService.create(article.userId, 'NEW_COMMENT', message, articleId);
}
}
return createdComment;
}
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;
53 changes: 53 additions & 0 deletions dist/ProductService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ProductService {
constructor(productRepository, likeRepository, notificationService) {
this.productRepository = productRepository;
this.likeRepository = likeRepository;
this.notificationService = notificationService;
}
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, userId) {
const originalProduct = await this.productRepository.findProductById(id);
if (!originalProduct) {
throw new Error('Product not found');
}
if (originalProduct.userId !== userId) {
throw new Error('You do not have permission to update this product.');
}
const { description, ...restOfData } = data;
const updateData = { ...restOfData };
if (description) {
updateData.content = description;
}
const updatedProduct = await this.productRepository.updateProduct(id, updateData);
if (data.price && originalProduct.price !== updatedProduct.price) {
const likes = await this.likeRepository.findLikes({ where: { productId: id } });
for (const like of likes) {
// Skip notification for the user who updated the product
if (like.userId === userId) {
continue;
}
const message = `'${originalProduct.name}' 상품의 가격이 ${originalProduct.price}원에서 ${updatedProduct.price}원으로 변경되었습니다.`;
await this.notificationService.create(like.userId, 'PRICE_CHANGE', message, id);
}
}
return updatedProduct;
}
async deleteProduct(id) {
return this.productRepository.deleteProduct(id);
}
}
exports.default = ProductService;
Loading