Skip to content

Commit 3944ff6

Browse files
authored
Merge pull request #34 from DevKor-github/feat/restaurants
feat: restaurant endpoint
2 parents dc40bd7 + acb28a6 commit 3944ff6

12 files changed

Lines changed: 179 additions & 18 deletions

File tree

src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { FirebaseModule } from './firebase.module';
1414
import { ImagesModule } from './images/module';
1515
import { LoggerMiddleware } from './logger.middleware';
1616
import { SettingsModule } from './settings/module';
17+
import { RestaurantModule } from './restaurant/module';
1718

1819
@Module({
1920
imports: [
@@ -30,6 +31,7 @@ import { SettingsModule } from './settings/module';
3031
SearchModule,
3132
NotificationModule,
3233
ImagesModule,
34+
RestaurantModule,
3335
SettingsModule,
3436
],
3537
controllers: [AppController],

src/notification/dto/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './notification.response.dto';
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
3+
export class NotificationResponseDto {
4+
@ApiProperty({
5+
description: '알림 ID',
6+
example: 'notification-id-123',
7+
})
8+
id: string;
9+
10+
@ApiProperty({
11+
description: '사용자 ID',
12+
example: 'user-id-123',
13+
})
14+
userId: string;
15+
16+
@ApiProperty({
17+
description: '썸네일 URL',
18+
example: 'https://example.com/thumbnail.jpg',
19+
required: false,
20+
})
21+
thumbnailUrl?: string;
22+
23+
@ApiProperty({
24+
description: '알림 타입',
25+
example: 'FOLLOW_REQUEST',
26+
})
27+
type: string;
28+
29+
@ApiProperty({
30+
description: '표시할 내용',
31+
example: '새로운 팔로우 요청이 있습니다.',
32+
})
33+
displayContent: string;
34+
35+
@ApiProperty({
36+
description: '생성 시간',
37+
example: '2024-01-01T00:00:00.000Z',
38+
})
39+
createdAt: Date;
40+
}
41+
42+
export class NotificationListResponseDto {
43+
@ApiProperty({
44+
description: '알림 목록',
45+
type: [NotificationResponseDto],
46+
})
47+
notifications: NotificationResponseDto[];
48+
49+
@ApiProperty({
50+
description: '총 알림 개수',
51+
example: 10,
52+
})
53+
totalCount: number;
54+
55+
@ApiProperty({
56+
description: '현재 페이지',
57+
example: 1,
58+
})
59+
currentPage: number;
60+
61+
@ApiProperty({
62+
description: '페이지당 항목 수',
63+
example: 10,
64+
})
65+
perPage: number;
66+
}

src/restaurant/controller.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
Controller,
3+
Get,
4+
HttpStatus,
5+
Injectable,
6+
Param,
7+
Res,
8+
} from '@nestjs/common';
9+
import { RestaurantRepository } from './repositories/restaurant';
10+
import { ApiResponse, ApiTags } from '@nestjs/swagger';
11+
import { Response } from 'express';
12+
import { RestaurantResponse } from '@/user/dto';
13+
14+
@ApiTags('restaurant')
15+
@Injectable()
16+
@Controller('restaurant')
17+
export class RestaurantController {
18+
constructor(private readonly repo: RestaurantRepository) {}
19+
20+
@Get(':restaurantId')
21+
@ApiResponse({
22+
status: 200,
23+
description: 'Get Restaurant information',
24+
type: RestaurantResponse,
25+
})
26+
async getRestaurant(
27+
@Param('restaurantId') restaurantId: string,
28+
@Res() res: Response,
29+
) {
30+
const resp = await this.repo.findById(restaurantId);
31+
32+
if (!resp) {
33+
return res.status(HttpStatus.NOT_FOUND).json({
34+
message: 'Restaurant not found',
35+
});
36+
}
37+
38+
return RestaurantResponse.fromEntity(resp);
39+
}
40+
}

src/restaurant/entity.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
export interface RestaurantEntity {
1+
import { ApiProperty } from '@nestjs/swagger';
2+
3+
export class RestaurantEntity {
24
id: string;
35
placeId: string;
46
name: string;

src/restaurant/module.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Module } from '@nestjs/common';
2+
import { PrismaService } from 'src/prisma/prisma.service';
3+
import { AuthModule } from '../auth/module';
4+
import { RestaurantRepository } from './repositories/restaurant';
5+
import { RestaurantController } from './controller';
6+
7+
@Module({
8+
imports: [AuthModule],
9+
controllers: [RestaurantController],
10+
providers: [PrismaService, RestaurantRepository],
11+
exports: [],
12+
})
13+
export class RestaurantModule {}

src/tree/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class TreeController {
9595
return res.status(HttpStatus.OK).json(result);
9696
}
9797

98-
@Get(':restaurantId')
98+
@Get('restaurants/:restaurantId')
9999
@ApiOperation({ summary: '식당에 대한 나무 목록 반환' })
100100
@ApiParam({
101101
name: 'restaurantId',

src/user/dto.ts

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { Restaurant, FollowerStatus, Tag, $Enums, SavedRestaurant } from '@prisma/client';
1+
import {
2+
Restaurant,
3+
FollowerStatus,
4+
Tag,
5+
$Enums,
6+
SavedRestaurant,
7+
} from '@prisma/client';
28
import { Type } from 'class-transformer';
39
import {
410
IsArray,
@@ -13,6 +19,7 @@ import {
1319
IsOptional,
1420
} from 'class-validator';
1521
import { ApiProperty } from '@nestjs/swagger';
22+
import { RestaurantEntity } from '@/restaurant/entity';
1623

1724
export class RestaurantResponse {
1825
@ApiProperty({
@@ -82,6 +89,18 @@ export class RestaurantResponse {
8289
response.createdAt = restaurant.createdAt;
8390
return response;
8491
}
92+
93+
static fromEntity(restaurant: RestaurantEntity): RestaurantResponse {
94+
return {
95+
id: restaurant.id,
96+
placeId: restaurant.placeId,
97+
name: restaurant.name,
98+
address: restaurant.address,
99+
latitude: restaurant.latitude,
100+
longitude: restaurant.longitude,
101+
createdAt: restaurant.createdAt,
102+
};
103+
}
85104
}
86105

87106
export class RestaurantListResponse {
@@ -353,7 +372,7 @@ export class MypageTreeResponse {
353372

354373
@ApiProperty({
355374
description: '나무 높이',
356-
example: 38
375+
example: 38,
357376
})
358377
@IsNumber()
359378
@IsNotEmpty()
@@ -367,18 +386,34 @@ export class MypageTreeResponse {
367386
@IsNotEmpty()
368387
location: string;
369388

370-
constructor(savedRestaurant: (SavedRestaurant & { restaurant: Restaurant })){
371-
this.restaurantId = savedRestaurant.restaurant.id
372-
this.restaurantName = savedRestaurant.restaurant.name
373-
this.recommendationCount = savedRestaurant.recommendedByUsers.length
374-
this.location = savedRestaurant.restaurant.address
389+
@ApiProperty({
390+
description: '사용자가 보유한 전체 나무 개수에 따른 종합 요약 메시지',
391+
example: '뒷산이 부럽지 않을 만큼 풍성해졌어요',
392+
})
393+
@IsString()
394+
@IsNotEmpty()
395+
recapMessage: string;
396+
397+
@ApiProperty({
398+
description: '사용자가 보유한 전체 트리 개수에 따른 종합 요약 이미지 URL',
399+
example: 'https://example.com/images/level_2.png',
400+
})
401+
@IsString()
402+
@IsNotEmpty()
403+
recapImageUrl: string | null;
404+
405+
constructor(savedRestaurant: SavedRestaurant & { restaurant: Restaurant }) {
406+
this.restaurantId = savedRestaurant.restaurant.id;
407+
this.restaurantName = savedRestaurant.restaurant.name;
408+
this.recommendationCount = savedRestaurant.recommendedByUsers.length;
409+
this.location = savedRestaurant.restaurant.address;
375410
}
376411
}
377412

378413
export class MypageResponse {
379414
@ApiProperty({
380415
description: '유저 고유 ID',
381-
example: 'user-uuid-1234'
416+
example: 'user-uuid-1234',
382417
})
383418
@IsString()
384419
@IsNotEmpty()
@@ -406,23 +441,23 @@ export class MypageResponse {
406441
})
407442
@IsNumber()
408443
@IsNotEmpty()
409-
followerCount: number
444+
followerCount: number;
410445

411446
@ApiProperty({
412447
description: '팔로잉 수',
413448
example: 100,
414449
})
415450
@IsNumber()
416451
@IsNotEmpty()
417-
followingCount: number
452+
followingCount: number;
418453

419454
@ApiProperty({
420455
description: '내가 심은 나무 수',
421-
example: 30
456+
example: 30,
422457
})
423458
@IsNumber()
424459
@IsNotEmpty()
425-
treeCount: number
460+
treeCount: number;
426461

427462
@ApiProperty({
428463
description: '프로필 이미지',
@@ -440,7 +475,7 @@ export class MypageResponse {
440475
@IsOptional()
441476
@ValidateNested({ each: true })
442477
tags: Tag[];
443-
478+
444479
@ApiProperty({
445480
description: 'MBTI',
446481
example: 'ENFP',
@@ -469,7 +504,7 @@ export class MypageResponse {
469504
})
470505
@IsNotEmpty()
471506
biggestTrees: MypageTreeResponse[];
472-
507+
473508
@ApiProperty({
474509
description: '내 트리 목록',
475510
type: [MypageTreeResponse],
@@ -504,4 +539,4 @@ export class CheckFollowingStatusDto {
504539
example: FollowerStatus.PENDING,
505540
})
506541
followRequestStatus: FollowerStatus;
507-
}
542+
}

src/user/usecases/updateMbtiAndTags.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,4 @@ describe('UpdateMbtiAndTagsUseCase', () => {
7272
});
7373
});
7474

75+

src/user/usecases/updateMbtiAndTags.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@ export class UpdateMbtiAndTagsUseCase {
1717
return this.userRepository.updatePartial(userId, param);
1818
}
1919
}
20-

0 commit comments

Comments
 (0)