Skip to content

Commit

Permalink
Merge pull request #70 from boostcampwm2023/feat/64-save-default-shap…
Browse files Browse the repository at this point in the history
…e-to-db

[Feat] 기본 모양 객체 응답 및 uuid에 해당하는 모양 스트림 반환 API 구현
  • Loading branch information
mingxoxo authored Nov 21, 2023
2 parents b566c3e + 40bde26 commit 4db272a
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 2 deletions.
24 changes: 23 additions & 1 deletion BE/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { UsersModule } from "./users/users.module";
import { DiariesModule } from "./diaries/diaries.module";
import { AuthModule } from "./auth/auth.module";
import { IntroduceModule } from "./introduce/introduce.module";
import { ShapesModule } from "./shapes/shapes.module";
import { ShapesRepository } from "./shapes/shapes.repository";
import { UsersRepository } from "./users/users.repository";

@Module({
imports: [
Expand All @@ -13,6 +16,25 @@ import { IntroduceModule } from "./introduce/introduce.module";
DiariesModule,
AuthModule,
IntroduceModule,
ShapesModule,
],
providers: [ShapesRepository, UsersRepository],
})
export class AppModule {}
export class AppModule {
constructor(
private shapesRepository: ShapesRepository,
private usersRepository: UsersRepository,
) {}

async onModuleInit() {
const commonUser =
(await this.usersRepository.getUserByUserId("commonUser")) ||
(await this.usersRepository.createUser({
userId: "commonUser",
password: process.env.COMMON_USER_PASS,
nickname: "commonUser",
}));

await this.shapesRepository.createDefaultShapes(commonUser);
}
}
9 changes: 9 additions & 0 deletions BE/src/auth/get-user.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
import { User } from "src/users/users.entity";

export const GetUser = createParamDecorator(
(_: unknown, ctx: ExecutionContext): User => {
const req = ctx.switchToHttp().getRequest();
return req.user;
},
);
25 changes: 25 additions & 0 deletions BE/src/shapes/shapes.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller, Get, Param, UseGuards } from "@nestjs/common";
import { ShapesService } from "./shapes.service";
import { AuthGuard } from "@nestjs/passport";
import { Shape } from "./shapes.entity";
import { GetUser } from "src/auth/get-user.decorator";
import { User } from "src/users/users.entity";

@Controller("shapes")
export class ShapesController {
constructor(private shapesService: ShapesService) {}

@Get("/default")
async getDefaultShapeFiles(): Promise<Shape[]> {
return this.shapesService.getDefaultShapeFiles();
}

@Get("/:uuid")
@UseGuards(AuthGuard())
async getShapeFilesByUuid(
@Param("uuid") uuid: string,
@GetUser() user: User,
): Promise<object> {
return this.shapesService.getShapeFileByUuid(uuid, user);
}
}
7 changes: 7 additions & 0 deletions BE/src/shapes/shapes.default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Shape } from "./shapes.entity";

export const defaultShapes: Partial<Shape>[] = [
{ shapePath: "test-basic-shape-1.png" },
{ shapePath: "test-basic-shape-2.png" },
{ shapePath: "test-basic-shape-3.png" },
];
2 changes: 1 addition & 1 deletion BE/src/shapes/shapes.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Shape extends BaseEntity {
uuid: string;

@ManyToOne(() => User, (user) => user.userId, { nullable: false })
user: User;
user: Promise<User>;

@Column()
shapePath: string;
Expand Down
15 changes: 15 additions & 0 deletions BE/src/shapes/shapes.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { UsersModule } from "src/users/users.module";
import { Shape } from "./shapes.entity";
import { ShapesController } from "./shapes.controller";
import { ShapesService } from "./shapes.service";
import { ShapesRepository } from "./shapes.repository";
import { AuthModule } from "src/auth/auth.module";

@Module({
imports: [TypeOrmModule.forFeature([Shape]), UsersModule, AuthModule],
controllers: [ShapesController],
providers: [ShapesService, ShapesRepository],
})
export class ShapesModule {}
34 changes: 34 additions & 0 deletions BE/src/shapes/shapes.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defaultShapes } from "./shapes.default";
import { User } from "src/users/users.entity";
import { Shape } from "./shapes.entity";
import { NotFoundException } from "@nestjs/common";

export class ShapesRepository {
async createDefaultShapes(commonUser: User) {
await Promise.all(
defaultShapes.map(async (defaultShape) => {
const existingShape = await this.getShapeByShapePath(
defaultShape.shapePath,
);

if (existingShape) return;

defaultShape.user = Promise.resolve(commonUser);
const shape = Shape.create(defaultShape);
await shape.save();
}),
);
}

async getShapeByShapePath(shapePath: string): Promise<Shape | null> {
return Shape.findOne({ where: { shapePath } });
}

async getShapeByUuid(uuid: string): Promise<Shape> {
const found = await Shape.findOne({ where: { uuid } });
if (!found) {
throw new NotFoundException(`Can't find Shape with uuid: [${uuid}]`);
}
return found;
}
}
30 changes: 30 additions & 0 deletions BE/src/shapes/shapes.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable, UnauthorizedException } from "@nestjs/common";
import { ShapesRepository } from "./shapes.repository";
import { getFileFromS3 } from "src/utils/e3";
import { defaultShapes } from "./shapes.default";
import { Shape } from "./shapes.entity";
import { User } from "src/users/users.entity";

@Injectable()
export class ShapesService {
constructor(private shapesRepository: ShapesRepository) {}

async getDefaultShapeFiles(): Promise<Shape[]> {
const promises = defaultShapes.map(async (defaultShape) => {
return this.shapesRepository.getShapeByShapePath(defaultShape.shapePath);
});

const shapeFiles = await Promise.all(promises);
return shapeFiles;
}

async getShapeFileByUuid(uuid: string, user: User): Promise<object> {
const shape = await this.shapesRepository.getShapeByUuid(uuid);
const { userId, id } = await shape.user;

if (userId !== "commonUser" && id !== user.id) {
throw new UnauthorizedException();
}
return getFileFromS3(shape.shapePath);
}
}

0 comments on commit 4db272a

Please sign in to comment.