diff --git a/src/constants/columnMapping.js b/src/constants/columnMapping.js new file mode 100644 index 0000000000000000000000000000000000000000..9997dea9bf69e56c2345401dbe8259a5ffb456a8 --- /dev/null +++ b/src/constants/columnMapping.js @@ -0,0 +1,58 @@ +export const columnMapping = { + cpu: { + family_type: 'CPU 종류', + socket_type: '소켓 구분', + core_count: '코어 수', + thread_count: '스레드 수', + base_clock: '기본 클럭', + max_clock: '최대 클럭', + mem_type: '메모리 규격', + tdp: 'TDP', + }, + gpu: { + chipset_manufacturer: '칩셋 제조사', + family_type: '제품 시리즈', + chipset: '칩셋', + vram_type: '메모리 종류', + vram_size: '메모리 용량', + interface: '인터페이스', + max_monitor_count: '모니터 지원', + power_consumption: '사용 전력', + }, + ram: { + usage_type: '사용 장치', + form_factor: '메모리 규격', + size: '메모리 용량', + generation: '제품 분류', + base_clock: '동작 클럭(대역폭)', + package_count: '램 개수', + }, + mb: { + board_type: '제품 분류', + cpu_socket: 'CPU 소켓', + cpu_chipset: '세부 칩셋', + power_phase: '전원부', + ram_type: '메모리 종류', + ram_speed: '메모리 속도', + ram_slot_count: '메모리 슬롯 수', + form_factor: '폼팩터', + }, + ssd: { + interface: '인터페이스', + size: '용량', + form_factor: '폼팩터', + nand_type: '메모리 타입', + dram_type_size: 'DRAM (유형과 용량)', + protocol: '프로토콜', + }, + hdd: { + usage_type: '제품 분류', + disk_standard_size: '디스크 크기', + disk_size: '디스크 용량', + interface: '인터페이스', + buffer_size: '버퍼 용량', + rpm: '회전 수', + max_speed: '전송 속도', + access_method: '기록방식', + }, +}; diff --git a/src/services/partService.js b/src/services/partService.js index d9dbe0183acb05c10f0ecaa0d2cd2ed5af11b3c1..2e8d58c9c5f0b8413bdfd189af3e424196e573be 100644 --- a/src/services/partService.js +++ b/src/services/partService.js @@ -1,3 +1,4 @@ +import { columnMapping } from '../constants/columnMapping.js'; import { ReportableError } from '../errors.js'; import PartRepository from '../repositories/partRepository.js'; @@ -24,6 +25,55 @@ const PartService = { return this.cleanEntity(part); }, + async getFilters() { + const types = Object.keys(columnMapping); + const filters = {}; + + for (const type of types) { + const columns = await PartRepository.getColumnsByType(type); + + filters[type.toUpperCase()] = {}; + for (const column of columns) { + const koreanName = columnMapping[type]?.[column]; + if (koreanName) { + const filterValues = + await PartRepository.getFilterDataByTypeAndColumn(type, column); + + filters[type.toUpperCase()][koreanName] = { + column, + values: filterValues, + }; + } + } + } + + return filters; + }, + + async getParts(partType, filters) { + if (!partType) { + throw new Error('파트 타입이 필요합니다.'); + } + + let parsedFilters; + try { + parsedFilters = filters ? JSON.parse(filters) : {}; + } catch { + throw new ReportableError(400, '잘못된 JSON 형태입니다.'); + } + + const whereClauses = Object.entries(parsedFilters) + .map(([key], index) => `${key} = $${index + 1}`) + .join(' AND '); + const queryValues = Object.values(parsedFilters); + + const parts = await PartRepository.getPartsByFilters( + partType, + whereClauses, + queryValues + ); + return parts; + }, }; export default PartService;