dev: refactor the structure and add database integration to the app

This commit is contained in:
pablohashescobar
2023-12-15 14:27:19 +05:30
parent 1c390db493
commit 91cbc8e56f
8 changed files with 1193 additions and 21 deletions

View File

@@ -1,4 +1,5 @@
APP_ENV=local
SERVER_PORT=9000
DATABASE_URL=""
RABBITMQ_URL=""
SENTRY_DSN=""

View File

@@ -17,6 +17,7 @@
"amqplib": "^0.10.3",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"drizzle-orm": "^0.29.1",
"express": "^4.18.2",
"postgres": "^3.4.1",
"uuid": "^9.0.1",
@@ -28,7 +29,9 @@
"@types/cors": "^2.8.14",
"@types/express": "^4.17.18",
"@types/node": "^20.8.3",
"@types/pg": "^8.10.9",
"concurrently": "^8.2.1",
"drizzle-kit": "^0.20.6",
"nodemon": "^3.0.1",
"typescript": "^5.2.2"
}

View File

@@ -1,8 +1,9 @@
// overnight js
import { Request, Response } from "express";
import { Controller, Post, Middleware } from "@overnightjs/core";
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
// mq
import { MQSingleton } from "../queue/mq.singleton";
import { MQSingleton } from "../mq/singleton";
// middleware
import AuthKeyMiddlware from "../middleware/authkey.middleware";
@@ -11,8 +12,12 @@ export class JiraController {
/**
* This controller houses all routes for the Jira Importer
*/
// Initialize database and mq
db: PostgresJsDatabase;
mq: MQSingleton;
constructor(mq: MQSingleton) {
constructor(db: PostgresJsDatabase, mq: MQSingleton) {
this.db = db;
this.mq = mq;
}

View File

@@ -0,0 +1,33 @@
import { drizzle, PostgresJsDatabase } from "drizzle-orm/postgres-js";
import postgres from "postgres";
// logger
import { logger } from "../utils/logger"
export class DatabaseSingleton {
private static instance: DatabaseSingleton;
public db: PostgresJsDatabase | null = null;
private constructor() {
try {
// Ensure the DATABASE_URL is provided
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL environment variable is not set.");
}
const queryClient = postgres(process.env.DATABASE_URL);
this.db = drizzle(queryClient);
logger.info("🛢️ Connected to Database")
} catch (error) {
logger.error("Failed to initialize database connection:", error);
throw new Error("Could not connect to Database")
}
}
public static getInstance(): DatabaseSingleton {
if (!DatabaseSingleton.instance) {
DatabaseSingleton.instance = new DatabaseSingleton();
}
return DatabaseSingleton.instance;
}
}

View File

@@ -5,18 +5,22 @@ import { Server } from "@overnightjs/core";
import cors from "cors";
import * as Sentry from "@sentry/node";
import * as Tracing from "@sentry/tracing";
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
// controllers
import * as controllers from "./controller";
// middlewares
import loggerMiddleware from "./middleware/logger.middleware";
// utils
import { logger } from "./utils/logger";
// db
import { DatabaseSingleton } from "./db/singleton";
// mq
import { MQSingleton } from "./queue/mq.singleton";
import { MQSingleton } from "./mq/singleton";
class ApiServer extends Server {
private readonly SERVER_STARTED = "🚀 Api server started on port: ";
SERVER_PORT: number;
db: PostgresJsDatabase | null = null;
mq: MQSingleton | null = null; // Declare the channel property
constructor() {
@@ -51,6 +55,8 @@ class ApiServer extends Server {
// setting up error logging and tracing.
this.setupSentryInit();
}
// setting up db
this.setupDatabase();
// setting up controllers
this.setupControllers();
// not found page
@@ -64,16 +70,9 @@ class ApiServer extends Server {
return this.app;
}
// setup all the controllers
private setupControllers(): void {
const controllerInstances = [];
for (const name in controllers) {
if (Object.prototype.hasOwnProperty.call(controllers, name)) {
const Controller = (controllers as any)[name];
controllerInstances.push(new Controller(this.mq));
}
}
super.addControllers(controllerInstances);
// Setup the database
private setupDatabase(): void {
this.db = DatabaseSingleton.getInstance().db;
}
// Setup MQ and initialize channel
@@ -93,6 +92,20 @@ class ApiServer extends Server {
}
}
// setup all the controllers
private setupControllers(): void {
const controllerInstances = [];
for (const name in controllers) {
if (Object.prototype.hasOwnProperty.call(controllers, name)) {
const Controller = (controllers as any)[name];
controllerInstances.push(new Controller(this.db, this.mq));
}
}
super.addControllers(controllerInstances);
}
// This controller will return 404 for not found pages
private setupNotFoundHandler(): void {
this.app.use((req, res) => {

View File

@@ -1,7 +1,7 @@
// mq
import { ConsumeMessage } from "amqplib";
// mq single ton
import { MQSingleton } from "../queue/mq.singleton";
import { MQSingleton } from "../mq/singleton";
// logger
import { logger } from "../utils/logger";

File diff suppressed because it is too large Load Diff