Skip to content

Commit e61ec09

Browse files
authored
[FEATURE] (홈 화면) 추천 알바공고 API 개발
[FEATURE] (홈 화면) 추천 알바공고 API 개발
2 parents 04c21be + d68d016 commit e61ec09

5 files changed

Lines changed: 110 additions & 0 deletions

File tree

prisma/schema.prisma

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ model alba_posting {
1515
main_task String? @db.Text
1616
requirement String? @db.Text
1717
notification String? @db.Text
18+
region_id Int?
19+
region region? @relation(fields: [region_id], references: [region_id], onDelete: NoAction, onUpdate: NoAction, map: "FK_region_TO_posting")
1820
store store @relation(fields: [store_id], references: [store_id], onDelete: Cascade, onUpdate: NoAction, map: "FK_store_TO_posting")
1921
user_alba user_alba[]
2022
user_work_log user_work_log[]
2123
work_schedule work_schedule?
2224
2325
@@index([store_id], map: "FK_store_TO_posting")
26+
@@index([region_id], map: "FK_region_TO_posting")
2427
}
2528

2629
model category {
@@ -65,6 +68,7 @@ model region {
6568
region_id Int @id
6669
city String? @db.VarChar(10)
6770
district String? @db.VarChar(10)
71+
alba_posting alba_posting[]
6872
user_preferred_region user_preferred_region[]
6973
}
7074

src/DTO/alba_recommend_dto.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface RecommendedAlbaDto {
2+
albaId: string;
3+
storeName: string | null;
4+
storeAddress: string | null;
5+
hourlyRate: number | null;
6+
totalWage: number | null;
7+
mainTask: string | null;
8+
regionCity: string | null;
9+
regionDistrict: string | null;
10+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Controller, Route, Get, Security, Request, SuccessResponse, Response, Tags } from 'tsoa';
2+
import { Request as ExpressRequest } from 'express';
3+
import AlbaRecommendService from '../service/alba_recommend_service';
4+
import { TsoaSuccessResponse } from '../config/response_interface';
5+
import { RecommendedAlbaDto } from '../DTO/alba_recommend_dto';
6+
import { uuidToBuffer } from '../util/uuid_util';
7+
8+
@Route('api/alba/recommend')
9+
@Tags('Alba Recommend')
10+
export class AlbaRecommendController extends Controller {
11+
/**
12+
* 홈 화면 추천 알바공고 조회 API
13+
* 유저의 선호 지역과 일치하는 알바공고를 최대 3개 추천
14+
*/
15+
@Get('')
16+
@Security('jwt')
17+
@SuccessResponse('200', '조회 성공')
18+
@Response(401, 'Unauthorized')
19+
public async getRecommendedAlba(
20+
@Request() req: ExpressRequest,
21+
): Promise<TsoaSuccessResponse<RecommendedAlbaDto[]>> {
22+
const userId = (req.user as unknown as { id: string }).id;
23+
const userIdBuffer = uuidToBuffer(userId);
24+
25+
const result = await AlbaRecommendService.getRecommendedPostings(userIdBuffer);
26+
return new TsoaSuccessResponse(result);
27+
}
28+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import prisma from '../config/prisma';
2+
3+
class AlbaRecommendRepository {
4+
/**
5+
* 유저의 선호 지역에 해당하는 알바 공고 최대 3개 조회
6+
*/
7+
async findRecommendedPostings(userId: Uint8Array) {
8+
// 1. 유저의 선호 region_id 목록 조회
9+
const preferredRegions = await prisma.user_preferred_region.findMany({
10+
where: { user_id: userId as Uint8Array<ArrayBuffer> },
11+
select: { region_id: true },
12+
});
13+
14+
if (preferredRegions.length === 0) {
15+
return [];
16+
}
17+
18+
const regionIds = preferredRegions.map((r) => r.region_id);
19+
20+
// 2. 해당 region_id에 매칭되는 alba_posting 3개 조회
21+
const postings = await prisma.alba_posting.findMany({
22+
where: {
23+
region_id: { in: regionIds },
24+
},
25+
include: {
26+
store: {
27+
select: {
28+
store_name: true,
29+
store_address: true,
30+
},
31+
},
32+
region: {
33+
select: {
34+
city: true,
35+
district: true,
36+
},
37+
},
38+
},
39+
take: 3,
40+
});
41+
42+
return postings;
43+
}
44+
}
45+
46+
export default new AlbaRecommendRepository();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import AlbaRecommendRepository from '../repository/alba_recommend_repository';
2+
import { RecommendedAlbaDto } from '../DTO/alba_recommend_dto';
3+
import { bufferToUuid } from '../util/uuid_util';
4+
5+
class AlbaRecommendService {
6+
async getRecommendedPostings(userId: Uint8Array): Promise<RecommendedAlbaDto[]> {
7+
const postings = await AlbaRecommendRepository.findRecommendedPostings(userId);
8+
9+
return postings.map((posting) => ({
10+
albaId: bufferToUuid(posting.alba_id),
11+
storeName: posting.store.store_name,
12+
storeAddress: posting.store.store_address,
13+
hourlyRate: posting.hourly_rate,
14+
totalWage: posting.total_wage,
15+
mainTask: posting.main_task,
16+
regionCity: posting.region?.city ?? null,
17+
regionDistrict: posting.region?.district ?? null,
18+
}));
19+
}
20+
}
21+
22+
export default new AlbaRecommendService();

0 commit comments

Comments
 (0)