From 193efb2f5097fc68bd7ca7c25ff5797943119daf Mon Sep 17 00:00:00 2001
From: LeeWxx <dnckd0903@naver.com>
Date: Mon, 2 Dec 2024 00:15:03 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20part=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?=
 =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/constants/columnMapping.js | 58 ++++++++++++++++++++++++++++++++++
 src/services/partService.js    | 50 +++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 src/constants/columnMapping.js

diff --git a/src/constants/columnMapping.js b/src/constants/columnMapping.js
new file mode 100644
index 0000000..9997dea
--- /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 d9dbe01..2e8d58c 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;
-- 
GitLab