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

Fix/#42/게시물 api 수정 #43

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const isAuthenticated = require("./middlewares/auth"); // 로그인 여부 미

app.use(
cors({
origin: ["localhost:5173", "modern9.netlify.app"],
origin: ["http://localhost:5173", "https://modonggu.site"],
credentials: true,
})
);
app.use(bodyParser.json());
Expand Down
40 changes: 25 additions & 15 deletions controllers/post.ctrl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use strict";

const Post = require("../models/Post");
const { uploadBase64ImageToS3 } = require("../s3/s3Uploader");
const Post = require("../models/Post");


// 공통 응답 헬퍼 함수
const sendResponse = (res, statusCode, success, message, data = null) => {
Expand All @@ -13,20 +14,20 @@ const sendResponse = (res, statusCode, success, message, data = null) => {
// 게시물 생성
const createPost = async (req, res) => {
try {
const { content, post_img } = req.body;
const { content, postImg } = req.body;
const userId = req.session.user.id;

// S3에 업로드하고, 업로드된 이미지 URL을 반환
if (!post_img) {
// postImg 없으면 오류
if (!postImg) {
return sendResponse(res, 400, false, "게시물 이미지는 필수입니다.");
}

const imageUrl = await uploadBase64ImageToS3(post_img);

const post = new Post({ content, post_img: imageUrl }, userId);
const postId = await post.createPost(); // createPost 호출 (Poststorage와 연결)

return sendResponse(res, 201, true, "게시물 생성 성공", { post_id: postId });
// S3에 이미지 업로드
const imageUrl = await uploadBase64ImageToS3(postImg);

const post = new Post({ content, postImg: imageUrl }, userId);
const postId = await post.createPost(); // createPost 호출 (Poststorage와 연결)
Copy link
Collaborator

Choose a reason for hiding this comment

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

createPost 호출은 const Post = require("../models/Post"); 여기서 하는 중인데
주석 오타가 난 것인가요 ?

return sendResponse(res, 201, true, "게시물 생성 성공", { postId });
} catch (err) {
console.error("Create post error:", err);
return sendResponse(res, 500, false, "서버 오류가 발생했습니다.");
Expand All @@ -48,16 +49,24 @@ const getAllPosts = async (req, res) => {
const updatePost = async (req, res) => {
try {
const { id } = req.params;
const { content, post_img } = req.body;
const { content, postImg } = req.body;
const userId = req.session.user.id;

if (!id) return sendResponse(res, 400, false, "post_id는 필수입니다.");
if (!post_img) return sendResponse(res, 400, false, "게시물 이미지는 필수입니다.");

// 이미지 업로드
const imageUrl = await uploadBase64ImageToS3(post_img);
const existingPost = await Post.getPost(id);

const result = await Post.updatePost(id, content, imageUrl, userId);
const existingImg = existingPost.postImg;

// 새로운 이미지 업로드
let imageUrl = existingImg;
if (postImg) {
imageUrl = await uploadBase64ImageToS3(postImg);
}

const post = new Post({ content, postImg: imageUrl }, userId);
Copy link
Collaborator

@gwgw123 gwgw123 Feb 27, 2025

Choose a reason for hiding this comment

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

@Ryu-02 님한테도 말씀 드렸지만
userId를 DB에 사용하기전 사용자를 검증하는 로직이 필요해보입니다 ~

나중에 확인했는데 명규님이 만들고 계시군요 ㅎㅎ..


const result = await post.updatePost(id);

if (result) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if (result) {
if (!result) {
return sendResponse(res, 403, false, "수정 권한이 없거나 게시물이 존재하지 않습니다.");

와 같이 early return 방식을 사용하면 불 필요한 조건문 하나를 없앨 수 있어서
코드 가독성이 더 올라갈 것 같습니다~

return sendResponse(res, 200, true, "게시물 수정 성공");
Expand All @@ -70,6 +79,7 @@ const updatePost = async (req, res) => {
}
};


// 게시물 삭제
const deletePost = async (req, res) => {
try {
Expand Down
12 changes: 5 additions & 7 deletions middlewares/validatePost.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
const validatePost = (action) => {
return (req, res, next) => {
const { post_img } = req.body;
const validatePost = (req, res, next) => {
const { postImg } = req.body;

// 이미지 URL 검증
if (post_img && !String(post_img).startsWith('http')) {
return res.status(400).json({ error: "유효하지 않은 이미지 URL입니다." });
// 이미지 인코딩 검증
if (postImg && !String(postImg).startsWith('data:image/')) {
return res.status(400).json({ error: "유효하지 않은 인코딩 이미지입니다." });
}

next();
};
};

module.exports = { validatePost };
29 changes: 18 additions & 11 deletions models/Post.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,39 @@
const PostStorage = require('../storages/postStorage');

class Post {
constructor({ content, post_img }, user_id) {
this.user_id = user_id;
constructor({ content, postImg }, userId, existingImg) {
this.userId = userId;
this.content = content;
this.post_img = post_img;
this.postImg = postImg || existingImg;
}

static async getAllPosts() {
return PostStorage.getAllPosts();
}


static async getPost(postId) {
return PostStorage.getPost(postId);
}

// 게시물 생성
async createPost() {
const postData = { user_id: this.user_id, content: this.content, post_img: this.post_img };
const postData = { userId: this.userId, content: this.content, postImg: this.postImg };
return PostStorage.createPost(postData);
}

// 게시물 수정
async updatePost(post_id) {
const postData = { post_id, content: this.content, post_img: this.post_img };
return PostStorage.updatePost(post_id, postData);
async updatePost(postId) {
const postData = { content: this.content, postImg: this.postImg };
return PostStorage.updatePost(postId, this.userId, postData);
}

// 게시물 삭제
static async deletePost(post_id) {
return PostStorage.deletePost(post_id);
static async deletePost(postId, userId) {
return PostStorage.deletePost(postId, userId);
}


}


module.exports = Post;
1 change: 0 additions & 1 deletion models/like.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class Like {

async toggleLike() {
try {
console.log("토글 시작:", this.postId, this.userId);
const isLiked = await LikeStorage.checkLike(this.postId, this.userId);

if (isLiked) {
Expand Down
6 changes: 4 additions & 2 deletions s3/s3Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ require('dotenv').config();

// AWS S3 설정
const s3 = new S3({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
region: process.env.AWS_REGION
});

Expand Down
14 changes: 9 additions & 5 deletions s3/s3Uploader.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
const s3 = require('./s3Config');
const { PutObjectCommand } = require('@aws-sdk/client-s3');
const { v4: uuidv4 } = require('uuid');
const s3 = require('./s3Config');

// base64 이미지를 S3에 업로드하는 함수
const uploadBase64ImageToS3 = async (base64Image) => {
const buffer = Buffer.from(base64Image, 'base64');
const fileName = `posts/${uuidv4()}.jpeg`;
const fileName = `posts/${new Date().toISOString().split('T')[0]}-${uuidv4()}.jpeg`;

const params = {
Bucket: process.env.S3_BUCKET_NAME,
Key: fileName, // 고유한 파일 이름을 생성
Body: buffer,
ContentType: 'image/jpeg',
ACL: 'public-read' // 공개 읽기 권한 설정
};

try {
const uploadResult = await s3.upload(params).promise();
return uploadResult.Location; // s3 url 반환
const command = new PutObjectCommand(params);
await s3.send(command);

const imageUrl = `https://${process.env.S3_BUCKET_NAME}.s3.amazonaws.com/${fileName}`;

return imageUrl;
} catch (error) {
throw new Error(`이미지 업로드 실패 ${error.message}`);
}
Expand Down
24 changes: 15 additions & 9 deletions storages/postStorage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
const db = require('../config/db');

class PostStorage {
static async getPost(postId) {
const query = 'SELECT * FROM posts WHERE id =?';
const [rows] = await db.execute(query, [postId]);
return rows[0];
}

// 게시물 생성
static async createPost({ user_id, content, post_img }) {
static async createPost({ userId, content, postImg }) {
try {
const query = `INSERT INTO posts (user_id, content, post_img, created_at) VALUES (?, ?, ?, NOW())`;
const [result] = await db.execute(query, [user_id, content, post_img]);
const query = `INSERT INTO posts (user_id, content, post_img) VALUES (?, ?, ?)`;
const [result] = await db.execute(query, [userId, content, postImg]);
return result.insertId;
} catch (err) {
console.error("Database insert error:", err);
Expand Down Expand Up @@ -34,7 +40,7 @@ class PostStorage {
}

// 게시물 수정
static async updatePost (post_id, user_id, updates) {
static async updatePost (postId, userId, updates) {
try {
const fields = [];
const values = [];
Expand All @@ -43,15 +49,15 @@ class PostStorage {
fields.push("content = ?");
values.push(updates.content);
}
if (updates.post_img) {
if (updates.postImg) {
fields.push("post_img = ?");
values.push(updates.post_img);
values.push(updates.postImg);
}
if (fields.length === 0) {
return true; // 아무 변경이 없어도 성공
}

values.push(post_id, user_id);
values.push(postId, userId);
const query = `UPDATE posts SET ${fields.join(", ")} WHERE id = ? AND user_id = ?`;
const [result] = await db.execute(query, values);

Expand All @@ -63,10 +69,10 @@ class PostStorage {
}

// 게시물 삭제
static async deletePost(post_id, user_id) {
static async deletePost(postId, userId) {
try {
const query = `DELETE FROM posts WHERE id = ? AND user_id = ?`;
const [result] = await db.execute(query, [post_id, user_id]);
const [result] = await db.execute(query, [postId, userId]);

return result.affectedRows > 0; // 삭제된 게시물 확인
} catch (err) {
Expand Down