Skip to content

Commit

Permalink
Merge pull request #23 from lemoncloud-capstone/BE_day
Browse files Browse the repository at this point in the history
Be day
  • Loading branch information
Yeeun411 authored May 13, 2024
2 parents df57569 + 1f7e96c commit 05d4ce4
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 30 deletions.
39 changes: 32 additions & 7 deletions apps/server/src/controllers/project.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ import { z } from 'zod';

import { ImageService } from '../services/image.service';
import { ProjectService } from '../services/project.service';
import { ProjectType } from '../types/project.types';
import { ProjectType, workerType } from '../types/project.types';
import { BaseResponseCode, BaseResponseMessages } from '../utils/errors';
import { sendResponse } from '../utils/response';

//Zod를 사용한 코드 검증
const WorkerSchema = z.object({
id: z.string(),
nickname: z.string(),
});

const ProjectInputSchema = z.object({
imgUrls: z.array(z.string()),
title: z.string(),
category: z.string(),
labels: z.array(z.string()),
workers: z.array(z.string()),
workers: z.array(WorkerSchema).optional().default([]),
});

const lastEvaluatedKeySchema = z.object({
Expand All @@ -31,6 +36,11 @@ const GetImagesInputSchema = z.object({
lastEvaluatedKey: z.string().optional(),
});

const AssignWorkersSchema = z.object({
workers: z.array(WorkerSchema),
title: z.string(),
});

export class ProjectController {
public static async createProject(req: Request, res: Response): Promise<void> {
try {
Expand All @@ -43,11 +53,11 @@ export class ProjectController {
const { imgUrls, title, category, labels, workers } = validationResult.data;

const projectType: ProjectType = {
imgUrls: imgUrls,
pkey: 'P' + title,
category: category,
labels: labels,
workers: workers,
imgUrls,
pkey: title,
category,
labels,
workers: workers as workerType[],
progress: 0,
};

Expand Down Expand Up @@ -81,4 +91,19 @@ export class ProjectController {
sendResponse(res, BaseResponseCode.FAIL_TO_GET_PROJECTS, error.message);
}
}

public static async assignWorkers(req: Request, res: Response): Promise<void> {
const validationResult = AssignWorkersSchema.safeParse(req.body);
if (!validationResult.success) {
sendResponse(res, BaseResponseCode.ValidationError);
return;
}
const { workers, title } = validationResult.data;
try {
await ProjectService.assignWorkers('P' + title, workers);
sendResponse(res, BaseResponseCode.SUCCESS);
} catch (error) {
sendResponse(res, BaseResponseCode.FAIL_TO_ASSIGN_WORKERS, error.message);
}
}
}
20 changes: 6 additions & 14 deletions apps/server/src/repositories/image.repository.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { PutCommand } from '@aws-sdk/lib-dynamodb';

import { ddbDocumentClient } from './index';
import { ImageType, Status } from '../types/image.types';
import { ImageType } from '../types/image.types';

export class ImageRepository {
public async addImage(imageUrl: string, title: string, status: Status, labels: string[]): Promise<any> {
const newImageType: ImageType = {
pkey: 'I' + title,
skey: imageUrl,
status: status,
latestTimestamp: Date.now(),
labels: labels,
};

public async addImage(image: ImageType): Promise<void> {
try {
await ddbDocumentClient.send(
new PutCommand({
TableName: 'LemonSandbox', // 이미지 테이블 이름
Item: newImageType,
TableName: 'LemonSandbox',
Item: image,
})
);
console.log('Image added to DynamoDB:', newImageType);
console.log('Image added to DynamoDB:', image);
return;
} catch (error) {
console.error('Error adding Image to DynamoDB:', error);
console.error('Error adding image to DynamoDB:', error);
throw error;
}
}
Expand Down
13 changes: 13 additions & 0 deletions apps/server/src/repositories/project.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ export class ProjectRepository {
category: item.category,
}));
}

public async assignWorkers(title: string, workers: Record<string, string>[]) {
await this.ddbClient.send(
new PutCommand({
TableName: this.tableName,
Item: {
pkey: title,
skey: 'PROJECT',
workers: workers,
},
})
);
}
}

export const projectRepository = new ProjectRepository(ddbDocumentClient);
4 changes: 2 additions & 2 deletions apps/server/src/routers/project.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { Router } from 'express';

import { ImgController } from '../controllers/img.controller';
import { ProjectController } from '../controllers/project.controller';
import { authenticateMiddleware } from '../middleware/accessToken.middleware';

export function projectsRouter(): Router {
const router: Router = Router();

router.post('/', authenticateMiddleware, ProjectController.createProject);
router.post('/', ProjectController.createProject);
router.post('/fetchProjects', ProjectController.getProjects);
router.post('/:title/images', ImgController.getProjectImages);
router.post('/:title/images/:imgURL', ImgController.updateStatus);
router.post('/workers', ProjectController.assignWorkers);
// router.post('/:title/images', authenticateMiddleware, ImgController.getProjectImages);
// router.post('/:title/images/:imgURL', authenticateMiddleware, ImgController.updateStatus);

Expand Down
38 changes: 34 additions & 4 deletions apps/server/src/services/image.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,54 @@ import dotenv from 'dotenv';

import { imageRepository } from '../repositories/image.repository';
import { s3 } from '../s3/s3Config';
import { Status } from '../types/image.types';
import { ImageType, LabelPoints, Status } from '../types/image.types';

dotenv.config();

export class ImageService {
// db에 이미지 저장
public static async addImageList(imageUrls: string[], title: string, labels: string[] = null): Promise<any> {
// Service.ts
public static async addImageList(imageUrls: string[], title: string, labels: string[] = []): Promise<any> {
try {
const labelsData = this.initializeLabelData(labels);
const modifiedTitle = 'I' + title.slice(0);

for (const imageUrl of imageUrls) {
await imageRepository.addImage(imageUrl, title, Status.Available, labels);
const newImageType: ImageType = {
pkey: modifiedTitle,
skey: imageUrl,
status: Status.Available,
latestTimestamp: Date.now(),
labelPoints: labelsData,
};
await imageRepository.addImage(newImageType);
}
return;
} catch (error) {
console.error('Error in service while add images:', error);
console.error('Error in service while adding images:', error);
throw error;
}
}

// 라벨데이터 초기화
private static initializeLabelData(labels: string[]): LabelPoints {
const labelStructure = {
leftTop: { x: null, y: null },
rightTop: { x: null, y: null },
leftBottom: { x: null, y: null },
rightBottom: { x: null, y: null },
};

const labelsData: LabelPoints = {};
for (const label of labels) {
labelsData[label] = [
JSON.parse(JSON.stringify(labelStructure)),
JSON.parse(JSON.stringify(labelStructure)),
];
}
return labelsData;
}

// s3에서 이미지 가져오기
public static async getS3Images(pageSize: number, continuationToken: string): Promise<any> {
if (continuationToken === 'null') {
Expand Down
8 changes: 8 additions & 0 deletions apps/server/src/services/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@ export class ProjectService {
throw new Error('Failed to get projects');
}
}
//work 리스트 받아서 저장
static async assignWorkers(title: string, workers: Record<string, string>[]) {
try {
return await projectRepository.assignWorkers(title, workers);
} catch (error) {
throw new Error('Failed to assign workers');
}
}
}
18 changes: 17 additions & 1 deletion apps/server/src/types/image.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,28 @@ export enum Status {
Rework = 'rework',
}

export type Point = {
x: number | null;
y: number | null;
};

export type LabelData = {
leftTop: Point;
rightTop: Point;
leftBottom: Point;
rightBottom: Point;
};

export type LabelPoints = {
[label: string]: LabelData[];
};

export type ImageType = {
pkey?: string;
skey?: string;
title?: string;
imageURL?: string;
status?: Status;
latestTimestamp: number;
labels: string[];
labelPoints: LabelPoints;
};
7 changes: 5 additions & 2 deletions apps/server/src/types/project.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ export enum status {
completed = 'completed',
rework = 'rework',
}

export type workerType = {
id: string;
nickname: string;
};
export type ProjectType = {
imgUrls: string[];
title?: string;
Expand All @@ -15,7 +18,7 @@ export type ProjectType = {
category: string;
labels: string[];
progress: number;
workers: string[];
workers?: workerType[];
};

export type ProjectListType = {
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/utils/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export enum BaseResponseCode {
* 5XXX : ProjectImage
*/
FAIL_TO_GET_S3_IMAGES = 5000,
FAIL_TO_ASSIGN_WORKERS = 5001,
/**
* 6XXX : Websocket
*/
Expand Down Expand Up @@ -76,6 +77,7 @@ export const BaseResponseMessages: Record<BaseResponseCode, string> = {
* 5XXX : ProjectImage
*/
[BaseResponseCode.FAIL_TO_GET_S3_IMAGES]: 'S3 이미지 조회에 실패했습니다.',
[BaseResponseCode.FAIL_TO_ASSIGN_WORKERS]: '작업자 할당에 실패했습니다.',
/**
* 6XXX : Websocket
*/
Expand Down

0 comments on commit 05d4ce4

Please sign in to comment.