From 613d8e4bebc0089423c8a1536c14945a2bcb38b2 Mon Sep 17 00:00:00 2001
From: LeeWxx <dnckd0903@naver.com>
Date: Wed, 4 Dec 2024 15:33:42 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20combination=20=EB=B0=98=ED=99=98=20api?=
 =?UTF-8?q?=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/repositories/partRepository.js | 30 ++++++++++++++++++++++++++++
 src/routes/parts.js                | 19 ++++++++++++++++++
 src/services/partService.js        | 32 ++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/src/repositories/partRepository.js b/src/repositories/partRepository.js
index 4e453fa..e93675b 100644
--- a/src/repositories/partRepository.js
+++ b/src/repositories/partRepository.js
@@ -57,6 +57,36 @@ const PartRepository = {
     const result = await pool.query(query, queryValues);
     return result.rows;
   },
+
+  async getAllCombinations() {
+    const query = `
+    SELECT array_agg(r.part_id) AS partIds
+    FROM combinations c
+    LEFT JOIN relations r ON c.id = r.combination_id
+    GROUP BY c.id;
+  `;
+
+    const result = await pool.query(query);
+    return result.rows;
+  },
+
+  async getFilteredCombinations(queryValues) {
+    const query = `
+    SELECT 
+      c.id AS combination_id,
+      array_agg(r.part_id) AS partIds
+    FROM combinations c
+    LEFT JOIN relations r ON c.id = r.combination_id
+    WHERE r.combination_id IN (
+      SELECT DISTINCT combination_id
+      FROM relations
+      WHERE part_id = ANY($1::int[])
+    )
+    GROUP BY c.id;
+  `;
+    const result = await pool.query(query, queryValues);
+    return result.rows;
+  },
 };
 
 export default PartRepository;
diff --git a/src/routes/parts.js b/src/routes/parts.js
index b995962..f8d6d9a 100644
--- a/src/routes/parts.js
+++ b/src/routes/parts.js
@@ -33,4 +33,23 @@ partRouter.get(
   })
 );
 
+partRouter.get(
+  '/combination/all',
+  wrapAsync(async (req, res) => {
+    const allCombinations = await PartService.getCombinations();
+    res.sendResponse('', 200, { combination: allCombinations });
+  })
+);
+
+partRouter.get(
+  '/combination/filtered',
+  wrapAsync(async (req, res) => {
+    const filters = req.query;
+    const filteredCombinations =
+      await PartService.getFilteredCombinations(filters);
+
+    res.sendResponse('', 200, { combination: filteredCombinations });
+  })
+);
+
 export default partRouter;
diff --git a/src/services/partService.js b/src/services/partService.js
index 0fa797d..e85f690 100644
--- a/src/services/partService.js
+++ b/src/services/partService.js
@@ -74,6 +74,38 @@ const PartService = {
     );
     return parts;
   },
+
+  async getCombinations() {
+    const allCombinations = await PartRepository.getAllCombinations();
+    return allCombinations;
+  },
+
+  async getFilteredCombinations(filters) {
+    if (typeof filters.partId === 'string') {
+      filters.partId = filters.partId.split(',').map((id) => id.trim());
+    }
+
+    if (
+      !filters ||
+      !Array.isArray(filters.partId) ||
+      filters.partId.length === 0
+    ) {
+      throw new ReportableError(400, '유효한 partId 값이 필요합니다.');
+    }
+
+    const validFilters = filters.partId.filter((value) => value != null);
+    if (validFilters.length === 0) {
+      throw new ReportableError(400, '유효한 partId 값이 없습니다.');
+    }
+
+    const queryValues = [validFilters];
+    const filteredCombinations =
+      await PartRepository.getFilteredCombinations(queryValues);
+
+    return filteredCombinations.map((combination) => ({
+      partIds: combination.partids,
+    }));
+  },
 };
 
 export default PartService;
-- 
GitLab