Skip to content
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {authRouter} from './routers/auth.routers.js';
import {userRouter} from './routers/user.router.js';
import {tagRouter} from './routers/tag.router.js';
import {myPageRouter} from './routers/mypage.routers.js';

import {trustRouter} from './routers/trust.router.js';
dotenv.config();

const app = express();
Expand Down Expand Up @@ -115,6 +115,7 @@ app.use('/memo', memoFolderRouter);
app.use('/challenge', challengeRouter);
app.use('/user/mypage',myPageRouter);
app.use('/tag', tagRouter);
app.use('/trust',trustRouter);
app.post('/image/ai', labelDetectionController);

RegisterRoutes(app);
Expand Down
198 changes: 55 additions & 143 deletions src/controllers/trust.controller.ts
Original file line number Diff line number Diff line change
@@ -1,149 +1,61 @@
import {Request, Response} from 'express';
import {Request, Response, NextFunction} from 'express';
import * as trustService from '../services/trust.service.js';
import {SearchNoResultsError,ServerError,DataValidationError} from 'src/errors.js';
import {StatusCodes} from 'http-status-codes';

import {imageStatusUpdate, imageDelete} from '../services/trust.service.js';
import {bodyToImage} from '../dtos/image.dto.js';

async function handleImageStatus(req: Request, res: Response): Promise<void> {
/*
#swagger.tags = ['trust-controller']
#swagger.summary = '이미지 상태 변화 API';
#swagger.description = '이미지를 활성화(1) 또는 비활성화(0) 시키는 API입니다. 유저나 이미지 고유 id를 통해 이미지 상태를 변경할 수 있습니다.'
#swagger.requestBody = {
required: true,
content: {
"multipart/form-data": {
schema: {
type: "object",
required: ['userId', 'imageId'],
properties: {
userId: { type: "interger", description: "사용자 ID" },
imageId: { type: "integer", description: "이미지 고유 ID" , example: 1000100124}
}
}
export const handleImageStatus = async (req: Request, res: Response, next:NextFunction): Promise<void> => {
try {
const {mediaId} = req.body;
const parsedMediaId = parseInt(mediaId);
if (isNaN(parsedMediaId)) {
throw new SearchNoResultsError({searchKeyword: 'mediaId가 올바르지 않습니다'});
}
}
const updatedImage = await trustService.deactivateImages(mediaId);
if (!updatedImage) {
throw new SearchNoResultsError({ searchKeyword: '해당 mediaId에 대한 이미지가 존재하지 않습니다' });
}
const result = {
mediaId: updatedImage.mediaId,
status: updatedImage.status
};
#swagger.responses[200] = {
description: "이미지 상태 변화 성공 응답",
content: {
"application/json": {
schema: {
type: "object",
properties: {
resultType: { type: "string", example: "SUCCESS" },
error: { type: "object", nullable: true, example: null },
success: {
type: "object",
properties: {
id: { type: "string", example: "1" },
mediaId: { type: "string", example: "1000100124" },
userId: { type: "string", example: "1" },
createdAt: { type: "string", example: "2021-08-31T07:00:00.000Z" },
updatedAt: { type: "string", example: "2021-08-31T07:00:00.000Z" },
status: { type: "number", example: 1 }
}
}
}
}
}
}
};
#swagger.responses[400] = {
description: "이미지 상태 변화 실패 응답",
content: {
"application/json": {
schema: {
type: "object",
properties: {
resultType: { type: "string", example: "FAIL" },
error: {
type: "object",
properties: {
errorCode: { type: "string", example: "U400" },
reason: { type: "string", example: "이미지 조회 에러" },
data: {
type: "object",
example: null
}
}
},
success: { type: "object", nullable: true, example: null }
}
}
}
}
}
};
*/
const updateImageStatus = await imageStatusUpdate(bodyToImage(req.body));
res.status(StatusCodes.OK).success(updateImageStatus);
}
res.status(StatusCodes.OK).success(result);
} catch (error) {
next(error);
}
};

async function handleImageDelete(req: Request, res: Response): Promise<void> {
/*
#swagger.tags = ['trust-controller']
#swagger.summary = '휴지통 비우기 API';
#swagger.description = '비활성화(0)된 이미지를 일괄 삭제시키는 API입니다. 유저 상태를 이용하여 변경할 수 있습니다.'
#swagger.requestBody = {
required: true,
content: {
"multipart/form-data": {
schema: {
type: "object",
required: ['userId', 'imageId'],
properties: {
userId: { type: "interger", description: "사용자 ID" },
}
}
}
}
};
#swagger.responses[200] = {
description: "휴지통 비우기 성공 응답",
content: {
"application/json": {
schema: {
type: "object",
properties: {
resultType: { type: "string", example: "SUCCESS" },
error: { type: "object", nullable: true, example: null },
success: { type: "boolean", example: "true" }
}
}
}
}
}
};
#swagger.responses[400] = {
description: "휴지통 비우기 실패 응답",
content: {
"application/json": {
schema: {
type: "object",
properties: {
resultType: { type: "string", example: "FAIL" },
error: {
type: "object",
properties: {
errorCode: { type: "string", example: "U400" },
reason: { type: "string", example: "유저 조회 에러" },
data: {
type: "object",
example: null
}
}
},
success: { type: "object", nullable: true, example: null }
}
}
}
}
}
};
*/
const deleteImage = await imageDelete(req.body.userId);
res.status(StatusCodes.OK).success(deleteImage);
}
export const handleImageRestore = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const {mediaIds} = req.body;
if (!Array.isArray(mediaIds)) {
throw new SearchNoResultsError({searchKeyword: 'mediaIds가 올바르지 않습니다'});
}
const restoredImages = await trustService.restoreImages(mediaIds);
if (!restoredImages.length) {
throw new SearchNoResultsError({ searchKeyword: '해당 mediaIds에 대한 이미지가 존재하지 않습니다' });
}
const result = restoredImages.map(image => ({
mediaId: image.mediaId,
status: image.status
}));
res.status(StatusCodes.OK).success(result);
} catch (error) {
next(error);
}
};

export {handleImageStatus, handleImageDelete};
export const handleImageDelete = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const { mediaIds } = req.body;
if (!Array.isArray(mediaIds)) {
throw new SearchNoResultsError({searchKeyword: 'mediaIds가 올바르지 않습니다'});
}
const deleteable = await trustService.deleteImages(mediaIds);
if(!deleteable) {
throw new DataValidationError({reason: '해당 사진이 휴지통에 존재하지 않습니다'});
}
res.status(StatusCodes.OK).success(deleteable);
} catch (error) {
next(error);
}
};
107 changes: 22 additions & 85 deletions src/repositories/trust.repositories.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,25 @@
import {prisma} from '../db.config.js';
import {BodyToImage, ResponseFromImage} from '../models/image.model.js';

export async function updateStatusImage(image: BodyToImage): Promise<bigint> {
const {mediaId, userId} = image;
let imageStatus: 0 | 1 = 0;

const user = await prisma.user.findFirst({
where: {
id: userId,
},
});

if (user === null) {
throw new Error('유저 조회 에러');
}

const imageData = await prisma.image.findFirst({
where: {
mediaId: mediaId,
userId: userId,
},
});

if (imageData === null) {
throw new Error('이미지 조회 에러');
}

if (imageData.status === 0) {
imageStatus = 1;
} else {
imageStatus = 0;
}

const updated = await prisma.image.update({
where: {
id: imageData.id,
},
data: {
status: imageStatus,
},
});

if (updated === null) {
throw new Error('이미지 상태 변경 에러');
}

return updated.id;
}

export async function deleteImage(userId: bigint): Promise<boolean> {
const user = await prisma.user.findFirst({
where: {
id: userId,
},
});

if (user === null) {
throw new Error('유저 조회 에러');
}

const deleted = await prisma.image.deleteMany({
where: {
userId,
status: 0,
},
export const updateImageStatus = async (mediaIds: number[], status: number): Promise<void> => {
await prisma.image.updateMany({
where: { mediaId: { in: mediaIds } },
data: { status }
});
};

export const removeImages = async (mediaIds: number[]): Promise<void> => {
await prisma.image.deleteMany({
where: { mediaId: { in: mediaIds }, status: 0 }
});
};

export const getImagesByIds = async (mediaIds: number[]): Promise<{ mediaId: number; status: number }[]> => {
const images = await prisma.image.findMany({
where: { mediaId: { in: mediaIds } },
select: { mediaId: true, status: true }
});

if (deleted === null) {
throw new Error('이미지 삭제 에러');
}

return true;
}

export async function getImage(imageId: bigint): Promise<ResponseFromImage> {
const image = await prisma.image.findFirst({
where: {
id: imageId,
},
}); // 이미지 조회

if (image === null) {
throw new Error('이미지 조회 에러');
} // 이미지 조회 실패 시 null 반환

return image;
}
return images.map(({ mediaId, status }) => ({
mediaId: Number(mediaId), // 변환 적용
status
}));
};
5 changes: 1 addition & 4 deletions src/routers/mypage.routers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import express from 'express';
export const myPageRouter = express.Router();
import { updateUserNameController, updateUserGoalCountController } from '../controllers/user.controller.js';
import {getUser, logOutUser, deleteUser} from '../controllers/user.mypage.controllers.js';

myPageRouter.get('/', getUser);
myPageRouter.patch('/name', updateUserNameController);
myPageRouter.patch('/goal', updateUserGoalCountController);
myPageRouter.get('/', getUser
myPageRouter.get('/logout', logOutUser);
myPageRouter.patch('/', deleteUser);
2 changes: 2 additions & 0 deletions src/routers/trust.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import express from 'express';
export const trustRouter = express.Router();
import {
handleImageStatus,
handleImageRestore,
handleImageDelete,
} from '../controllers/trust.controller.js';

trustRouter.patch('/active', handleImageStatus); // 이미지 비활성화
trustRouter.patch('/restore', handleImageRestore); //이미지 복구
trustRouter.delete('/', handleImageDelete); // 비활성화된 이미지 삭제
Loading
Loading