From c898e7195b11022aa61209d92c523230b1ccb20a Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 19 Dec 2024 20:53:23 +0100 Subject: [PATCH 1/5] Add MeiliSearch service to Docker Compose configuration --- api/docker-compose.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/docker-compose.yml b/api/docker-compose.yml index b6cb8bfd..2ea8fba8 100644 --- a/api/docker-compose.yml +++ b/api/docker-compose.yml @@ -9,3 +9,12 @@ services: environment: POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_DB: db + + meilisearch: + image: getmeili/meilisearch:latest + ports: + - "7700:7700" + volumes: + - ./meilisearch_db:/data.ms + environment: + MEILI_NO_ANALYTICS: true From 575b3faec94aafd7bd7f4fb080464e7376fd6654 Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 19 Dec 2024 21:45:06 +0100 Subject: [PATCH 2/5] Add MeiliSearch integration with search functionality --- api/docker-compose.yml | 1 + api/package.json | 1 + api/src/app/index.ts | 19 +++++++++++++------ api/src/config/types.ts | 17 +++++++++++++++-- api/src/search/controller.ts | 19 +++++++++++++++++++ api/src/search/service.ts | 31 +++++++++++++++++++++++++++++++ api/src/search/types.ts | 13 +++++++++++++ package-lock.json | 6 ++++++ 8 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 api/src/search/controller.ts create mode 100644 api/src/search/service.ts create mode 100644 api/src/search/types.ts diff --git a/api/docker-compose.yml b/api/docker-compose.yml index 2ea8fba8..5608a938 100644 --- a/api/docker-compose.yml +++ b/api/docker-compose.yml @@ -18,3 +18,4 @@ services: - ./meilisearch_db:/data.ms environment: MEILI_NO_ANALYTICS: true + MEILI_MASTER_KEY: "default" diff --git a/api/package.json b/api/package.json index 8f8f0d8d..06686b19 100644 --- a/api/package.json +++ b/api/package.json @@ -25,6 +25,7 @@ "helmet": "^7.1.0", "lodash": "^4.17.21", "make-fetch-happen": "^13.0.1", + "meilisearch": "^0.46.0", "morgan": "^1.10.0", "postgres": "^3.4.4", "reflect-metadata": "^0.2.2", diff --git a/api/src/app/index.ts b/api/src/app/index.ts index 60795975..b6b0a15b 100644 --- a/api/src/app/index.ts +++ b/api/src/app/index.ts @@ -3,24 +3,30 @@ import "reflect-metadata"; import "src/_utils/setup-sentry"; -import { fsConfig } from "@dzcode.io/utils/dist/config"; import * as Sentry from "@sentry/node"; + +import { + RoutingControllersOptions, + createExpressServer, + useContainer, +} from "routing-controllers"; + import { Application } from "express"; -import { createExpressServer, RoutingControllersOptions, useContainer } from "routing-controllers"; import { ConfigService } from "src/config/service"; +import Container from "typedi"; import { ContributionController } from "src/contribution/controller"; import { ContributorController } from "src/contributor/controller"; import { DigestCron } from "src/digest/cron"; import { GithubController } from "src/github/controller"; +import { LoggerMiddleware } from "./middlewares/logger"; import { LoggerService } from "src/logger/service"; import { MilestoneController } from "src/milestone/controller"; -import { ProjectController } from "src/project/controller"; import { PostgresService } from "src/postgres/service"; -import Container from "typedi"; - -import { LoggerMiddleware } from "./middlewares/logger"; +import { ProjectController } from "src/project/controller"; import { RobotsController } from "./middlewares/robots"; +import { SearchController } from "src/search/controller"; import { SecurityMiddleware } from "./middlewares/security"; +import { fsConfig } from "@dzcode.io/utils/dist/config"; // Use typedi container useContainer(Container); // eslint-disable-line react-hooks/rules-of-hooks @@ -45,6 +51,7 @@ useContainer(Container); // eslint-disable-line react-hooks/rules-of-hooks ProjectController, ContributorController, RobotsController, + SearchController, ], middlewares: [SecurityMiddleware, LoggerMiddleware], cors: Container.get(SecurityMiddleware).cors(), diff --git a/api/src/config/types.ts b/api/src/config/types.ts index 93870e8c..2fae1101 100644 --- a/api/src/config/types.ts +++ b/api/src/config/types.ts @@ -1,6 +1,10 @@ -import { Environment, environments } from "@dzcode.io/utils/dist/config/environment"; -import { Expose } from "class-transformer"; +import { + Environment, + environments, +} from "@dzcode.io/utils/dist/config/environment"; import { IsOptional, IsString, Matches } from "class-validator"; + +import { Expose } from "class-transformer"; import { readFileSync } from "fs-extra"; let bundleInfo = { version: require("../../package.json").version }; // eslint-disable-line @typescript-eslint/no-require-imports @@ -32,4 +36,13 @@ export class EnvRecord { @IsOptional() BUNDLE_INFO: { version: string } = bundleInfo; + + @Expose() + get MEILISEARCH_URL() { + return this.NODE_ENV === "development" + ? "http://localhost:7700/" + : "http://meilisearch:7700/"; + } + + MEILISEARCH_MASTER_KEY = "default"; } diff --git a/api/src/search/controller.ts b/api/src/search/controller.ts new file mode 100644 index 00000000..44dc60c5 --- /dev/null +++ b/api/src/search/controller.ts @@ -0,0 +1,19 @@ +import { Controller, Get } from "routing-controllers"; + +import { GetSearchResponse } from "./types"; +import { SearchService } from "./service"; +import { Service } from "typedi"; + +@Service() +@Controller("/Search") +export class SearchController { + constructor(private readonly searchService: SearchService) {} + + @Get("/") + public async search(): Promise { + const searchResults = await this.searchService.search("project", "test"); + return { + searchResults, + }; + } +} diff --git a/api/src/search/service.ts b/api/src/search/service.ts new file mode 100644 index 00000000..4ae3e44b --- /dev/null +++ b/api/src/search/service.ts @@ -0,0 +1,31 @@ +import { SearchItem, SearchType } from "./types"; + +import { ConfigService } from "src/config/service"; +import { LoggerService } from "src/logger/service"; +import { MeiliSearch } from "meilisearch"; +import { Service } from "typedi"; + +@Service() +export class SearchService { + private readonly meilisearch: MeiliSearch; + constructor( + private readonly configService: ConfigService, + private readonly logger: LoggerService, + ) { + const { MEILISEARCH_URL, MEILISEARCH_MASTER_KEY } = + this.configService.env(); + + this.meilisearch = new MeiliSearch({ + host: MEILISEARCH_URL, + apiKey: MEILISEARCH_MASTER_KEY, + }); + } + + public search = async ( + index: SearchType, + query: string, + ): Promise => { + this.logger.info({ message: `Searching ${index} for ${query}` }); + return []; + }; +} diff --git a/api/src/search/types.ts b/api/src/search/types.ts new file mode 100644 index 00000000..4c34e538 --- /dev/null +++ b/api/src/search/types.ts @@ -0,0 +1,13 @@ +import { GeneralResponse } from "src/app/types"; + +export interface GetSearchResponse extends GeneralResponse { + searchResults: Array; +} + +export interface SearchItem { + id: string; + title: string; + type: SearchType; +} + +export type SearchType = "project" | "contribution" | "contributor"; diff --git a/package-lock.json b/package-lock.json index b07cbc3e..a6b5ed53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,7 @@ "helmet": "^7.1.0", "lodash": "^4.17.21", "make-fetch-happen": "^13.0.1", + "meilisearch": "^0.46.0", "morgan": "^1.10.0", "postgres": "^3.4.4", "reflect-metadata": "^0.2.2", @@ -18363,6 +18364,11 @@ "node": ">= 0.6" } }, + "node_modules/meilisearch": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.46.0.tgz", + "integrity": "sha512-bx0tei1B+Ke0Y02pCoqmcwfpkwuDf+/ZkQDVDvb+ZfGDpWaxq9Z7sE5kc3o8zWvP6wJE7e3PoU3Oy6WINqq5bw==" + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", From b5f43ae480dec94193d1b56c287c7a6a020ff815 Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 19 Dec 2024 21:45:26 +0100 Subject: [PATCH 3/5] Update README with API server URL and add NODE_ENV variable --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d2c6a73..1ca2c49b 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ npm run dev:api npm run dev:all ``` -- For api server go to +- For api server go to - For web server go to **Note** @@ -70,6 +70,7 @@ In [`./api`](./api), keep in mind that you have limited calls to Github Api (60 ```.env GITHUB_TOKEN=Paste_You_Token_Here +NODE_ENV=development ``` ### Run e2e locally From 0fced5bdb5c312f81ac5d2929ae31b908f7d5828 Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 19 Dec 2024 21:59:33 +0100 Subject: [PATCH 4/5] Refactor search functionality to simplify parameters --- api/src/search/controller.ts | 2 +- api/src/search/service.ts | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/api/src/search/controller.ts b/api/src/search/controller.ts index 44dc60c5..0bbb74e0 100644 --- a/api/src/search/controller.ts +++ b/api/src/search/controller.ts @@ -11,7 +11,7 @@ export class SearchController { @Get("/") public async search(): Promise { - const searchResults = await this.searchService.search("project", "test"); + const searchResults = await this.searchService.search("test"); return { searchResults, }; diff --git a/api/src/search/service.ts b/api/src/search/service.ts index 4ae3e44b..332fd4d2 100644 --- a/api/src/search/service.ts +++ b/api/src/search/service.ts @@ -1,8 +1,7 @@ -import { SearchItem, SearchType } from "./types"; - import { ConfigService } from "src/config/service"; import { LoggerService } from "src/logger/service"; import { MeiliSearch } from "meilisearch"; +import { SearchItem } from "./types"; import { Service } from "typedi"; @Service() @@ -21,11 +20,8 @@ export class SearchService { }); } - public search = async ( - index: SearchType, - query: string, - ): Promise => { - this.logger.info({ message: `Searching ${index} for ${query}` }); + public search = async (query: string): Promise => { + this.logger.info({ message: `Searching for ${query}` }); return []; }; } From 926fdde2dbffa0dbdf19242c915cec8d72d215ab Mon Sep 17 00:00:00 2001 From: omdxp Date: Thu, 19 Dec 2024 22:16:51 +0100 Subject: [PATCH 5/5] Refactor SearchType definition to improve type visibility --- api/src/search/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/search/types.ts b/api/src/search/types.ts index 4c34e538..0643ebab 100644 --- a/api/src/search/types.ts +++ b/api/src/search/types.ts @@ -10,4 +10,4 @@ export interface SearchItem { type: SearchType; } -export type SearchType = "project" | "contribution" | "contributor"; +type SearchType = "project" | "contribution" | "contributor";