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
186 changes: 42 additions & 144 deletions src/controllers/trust.controller.ts
Original file line number Diff line number Diff line change
@@ -1,149 +1,47 @@
import {Request, Response} from 'express';
import {StatusCodes} from 'http-status-codes';
import * as trustService from '../services/trust.service.js';
import { SearchNoResultsError,ServerError } 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}
}
}
}
}
};
#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 }
}
}
}
export const handleImageStatus = async (req: Request, res: Response): Promise<void> => {
try {
const {imageId} = req.body;
const parsedImageId = parseInt(imageId);
if (isNaN(parsedImageId)) {
throw new SearchNoResultsError({searchKeyword: 'impageId가 올바르지 않습니다'});
Copy link
Contributor

Choose a reason for hiding this comment

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

[P1] 오타: -> mediaId

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

수정완료했습니다.

응답에 status도 포함되도록 했습니다
trust_restore

}
}
};
*/
const updateImageStatus = await imageStatusUpdate(bodyToImage(req.body));
res.status(StatusCodes.OK).success(updateImageStatus);
}
await trustService.deactivateImages(imageId);
res.status(StatusCodes.OK).success(imageId);
} catch (error) {
throw new ServerError();
}
};

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): Promise<void> => {
try {
const { imageIds } = req.body;
if (!Array.isArray(imageIds)) {
throw new SearchNoResultsError({searchKeyword: 'impageId가 올바르지 않습니다'});
}
await trustService.restoreImages(imageIds);
res.status(StatusCodes.OK).success(imageIds);
} catch (error) {
throw new ServerError();
}
};

export {handleImageStatus, handleImageDelete};
export const handleImageDelete = async (req: Request, res: Response): Promise<void> => {
try {
const { imageIds } = req.body;
if (!Array.isArray(imageIds)) {
throw new SearchNoResultsError({searchKeyword: 'impageId가 올바르지 않습니다'});
}
const deleteable = await trustService.deleteImages(imageIds);
if(!deleteable) {
throw new SearchNoResultsError({searchKeyword: '이미지가 휴지통에 없습니다'});
}
res.status(StatusCodes.OK).success(deleteable);
} catch (error) {
throw new ServerError();
}
};
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 (imageIds: number[], status: number) => {
return prisma.image.updateMany({
where: { id: { in: imageIds } },
data: { status }
});
};

export const removeImages = async (imageIds: number[]) => {
return prisma.image.deleteMany({
where: { id: { in: imageIds }, status: 0 }
});
};

export const getImagesByIds = async (imageIds: number[]): Promise<{ id: number; status: number }[]> => {
const images = await prisma.image.findMany({
where: { id: { in: imageIds } },
select: { id: 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(({ id, status }) => ({
id: Number(id), // 변환 적용
status
}));
};
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); // 비활성화된 이미지 삭제
42 changes: 15 additions & 27 deletions src/services/trust.service.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
import {BodyToImage, ResponseFromImage} from '../models/image.model.js';
import {responseFromImage} from '../dtos/image.dto.js';
import {
updateStatusImage,
getImage,
deleteImage,
} from '../repositories/trust.repositories.js';
import * as trustRepository from '../repositories/trust.repositories.js';

async function imageStatusUpdate(
image: BodyToImage,
): Promise<ResponseFromImage> {
console.log('imageStatusUpdate 실행');
console.log('image: ', image);
export const deactivateImages = async (imageId: number): Promise <void> => {
await trustRepository.updateImageStatus([imageId], 0);
};

const newImageId = await updateStatusImage(image);
const imageData = await getImage(newImageId);
export const restoreImages = async (imageIds: number[]): Promise<void> => {
await trustRepository.updateImageStatus(imageIds, 1);
};

return responseFromImage(imageData);
}

async function imageDelete(userId: bigint): Promise<boolean> {
console.log('imageDelete 실행');
console.log('userId: ', userId);

const deleted = await deleteImage(userId);

return deleted;
}

export {imageStatusUpdate, imageDelete};
export const deleteImages = async (imageIds: number[]): Promise<boolean> => {
const images = await trustRepository.getImagesByIds(imageIds);
if (images.some(({ status }) => status ===1)){
return false;
}
await trustRepository.removeImages(imageIds);
return true;
};