Skip to content

Commit 10b6da7

Browse files
DayifourricashtransYaishaa
authored
Put develop and main at the same level of code (#17)
* Update docker-build.yml * Merge the branch main on the branch develop (#14) * Update docker-build.yml (#10) * Update docker-build.yml * README.md explicitement bien détaillé --------- Co-authored-by: Manager Dayif <sekoudayifourouk@gmail.com> * Notification-Service Fonctionnel ✅ (#13) * Refactor OTP service to publish notifications with updated message structure and routing key * Refactor RabbitMQ configuration and health route for improved readability and consistency * Refactor notification controller and server initialization for improved structure and readability * Add user contact service and update notification handling for email and phone * Refactor code structure for improved readability in Otp, NotificationService, and UserContactService * Update Docker Compose configuration, refactor Notification entity imports, enhance OTP service with user contact retrieval * Update Docker Compose to use external network and enhance external notification consumer logging * Update dependencies: body-parser to 2.2.1 and nodemailer to 6.10.1 * Enhance OTP generation to validate email and phone inputs, and retrieve user contacts if not provided * Refactor InterServices and NotificationService to include optional email and phone fields, enhancing contact retrieval logic for notifications * Add Zod validation library and enhance notification service with multi-channel support for email and SMS * Enhance notification and OTP generation with Zod validation for request bodies * feat: Implement notification and OTP services with RabbitMQ integration - Added RabbitMQ configuration and channel management in `rabbitmq.js`. - Created notification controller to handle sending notifications and retrieving them. - Developed OTP controller for generating and verifying OTPs. - Introduced data source configuration for PostgreSQL using TypeORM. - Defined Notification and Otp entities with appropriate fields and relationships. - Implemented notification service for sending notifications via SMS and email. - Created OTP service for generating and verifying OTPs, including publishing events to RabbitMQ. - Added user contact service for retrieving user contact information. - Implemented mail service for sending emails using Nodemailer. - Developed message templates for generating notification messages based on type. - Created health check route for service status. - Set up consumers for processing notifications from RabbitMQ. - Added external consumer for handling inter-service notifications. * feat: notifications inter-service et robustesse consumer Co-authored-by: Aissata Traore <traoreaissata423@gmail.com> * fix: messages de transfert sender/receiver Co-authored-by: Aissata Traore <traoreaissata423@gmail.com> --------- Co-authored-by: Aissata Traore <traoreaissata423@gmail.com> --------- Co-authored-by: ricashtrans <ricashtrans@gmail.com> Co-authored-by: Aissata Traore <traoreaissata423@gmail.com> --------- Co-authored-by: ricashtrans <ricashtrans@gmail.com> Co-authored-by: Aissata Traore <traoreaissata423@gmail.com>
1 parent ebcdfb0 commit 10b6da7

File tree

2 files changed

+85
-69
lines changed

2 files changed

+85
-69
lines changed

dist/routes/health.js

Lines changed: 84 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"use strict";
2-
var __importDefault = (this && this.__importDefault) || function (mod) {
3-
return (mod && mod.__esModule) ? mod : { "default": mod };
4-
};
2+
var __importDefault =
3+
(this && this.__importDefault) ||
4+
function (mod) {
5+
return mod && mod.__esModule ? mod : { default: mod };
6+
};
57
Object.defineProperty(exports, "__esModule", { value: true });
68
const express_1 = __importDefault(require("express"));
79
const fs_1 = __importDefault(require("fs"));
@@ -10,87 +12,100 @@ const rabbitmq_1 = require("../config/rabbitmq");
1012
const data_source_1 = require("../data-source");
1113
const router = express_1.default.Router();
1214
// Configurable via env
13-
const HEALTH_TIMEOUT_MS = parseInt(process.env.HEALTH_CHECK_TIMEOUT_MS || "1000", 10);
14-
const HEALTH_CACHE_TTL_MS = parseInt(process.env.HEALTH_CACHE_TTL_MS || "5000", 10);
15+
const HEALTH_TIMEOUT_MS = parseInt(
16+
process.env.HEALTH_CHECK_TIMEOUT_MS || "1000",
17+
10,
18+
);
19+
const HEALTH_CACHE_TTL_MS = parseInt(
20+
process.env.HEALTH_CACHE_TTL_MS || "5000",
21+
10,
22+
);
1523
const EXPOSE_ERRORS = process.env.HEALTH_EXPOSE_ERRORS === "true";
1624
// Read package.json for version fallback
1725
let pkgVersion;
1826
let pkgName;
1927
try {
20-
const pkgPath = path_1.default.join(__dirname, "..", "..", "package.json");
21-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
22-
const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, "utf8"));
23-
pkgVersion = pkg.version;
24-
pkgName = pkg.name;
25-
}
26-
catch {
27-
// ignore
28+
const pkgPath = path_1.default.join(__dirname, "..", "..", "package.json");
29+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
30+
const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, "utf8"));
31+
pkgVersion = pkg.version;
32+
pkgName = pkg.name;
33+
} catch {
34+
// ignore
2835
}
2936
// Simple cache to avoid expensive repeated checks
3037
let readinessCache = null;
3138
function withTimeout(p, ms, name) {
32-
return Promise.race([
33-
p,
34-
new Promise((_, rej) => setTimeout(() => rej(new Error(`timeout:${name || "op"}`)), ms)),
35-
]);
39+
return Promise.race([
40+
p,
41+
new Promise((_, rej) =>
42+
setTimeout(() => rej(new Error(`timeout:${name || "op"}`)), ms),
43+
),
44+
]);
3645
}
3746
// Simple liveness probe
3847
router.get("/health", (req, res) => {
39-
res.status(200).json({ status: "OK", uptime: process.uptime() });
48+
res.status(200).json({ status: "OK", uptime: process.uptime() });
4049
});
4150
// Readiness probe: checks PostgreSQL connection and RabbitMQ channel
4251
router.get("/health/ready", async (req, res) => {
43-
const now = Date.now();
44-
if (readinessCache && now - readinessCache.ts < HEALTH_CACHE_TTL_MS) {
45-
return res.status(readinessCache.code).json(readinessCache.result);
46-
}
47-
const result = {
48-
status: "OK",
49-
uptime: process.uptime(),
50-
timestamp: new Date().toISOString(),
51-
version: process.env.SERVICE_VERSION || pkgVersion,
52-
commit: process.env.COMMIT_SHA,
53-
components: {
54-
db: { status: "UNKNOWN" },
55-
rabbitmq: { status: "UNKNOWN" },
56-
},
57-
};
58-
// Check DB with timeout
59-
try {
60-
if (!data_source_1.AppDataSource.isInitialized) {
61-
throw new Error("DataSource not initialized");
62-
}
63-
// lightweight query with timeout
64-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
65-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
66-
await withTimeout(data_source_1.AppDataSource.query("SELECT 1"), HEALTH_TIMEOUT_MS, "db");
67-
result.components.db.status = "OK";
68-
}
69-
catch (err) {
70-
result.status = "NOT_OK";
71-
result.components.db.status = "DOWN";
72-
result.components.db.error = EXPOSE_ERRORS
73-
? err instanceof Error
74-
? err.message
75-
: String(err)
76-
: "unavailable";
77-
}
78-
// Check RabbitMQ with timeout
79-
try {
80-
await withTimeout(Promise.resolve((0, rabbitmq_1.getRabbitChannel)()), HEALTH_TIMEOUT_MS, "rabbitmq");
81-
result.components.rabbitmq.status = "OK";
82-
}
83-
catch (err) {
84-
result.status = "NOT_OK";
85-
result.components.rabbitmq.status = "DOWN";
86-
result.components.rabbitmq.error = EXPOSE_ERRORS
87-
? err instanceof Error
88-
? err.message
89-
: String(err)
90-
: "unavailable";
52+
const now = Date.now();
53+
if (readinessCache && now - readinessCache.ts < HEALTH_CACHE_TTL_MS) {
54+
return res.status(readinessCache.code).json(readinessCache.result);
55+
}
56+
const result = {
57+
status: "OK",
58+
uptime: process.uptime(),
59+
timestamp: new Date().toISOString(),
60+
version: process.env.SERVICE_VERSION || pkgVersion,
61+
commit: process.env.COMMIT_SHA,
62+
components: {
63+
db: { status: "UNKNOWN" },
64+
rabbitmq: { status: "UNKNOWN" },
65+
},
66+
};
67+
// Check DB with timeout
68+
try {
69+
if (!data_source_1.AppDataSource.isInitialized) {
70+
throw new Error("DataSource not initialized");
9171
}
92-
const code = result.status === "OK" ? 200 : 503;
93-
readinessCache = { ts: now, result, code };
94-
res.status(code).json(result);
72+
// lightweight query with timeout
73+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
74+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
75+
await withTimeout(
76+
data_source_1.AppDataSource.query("SELECT 1"),
77+
HEALTH_TIMEOUT_MS,
78+
"db",
79+
);
80+
result.components.db.status = "OK";
81+
} catch (err) {
82+
result.status = "NOT_OK";
83+
result.components.db.status = "DOWN";
84+
result.components.db.error = EXPOSE_ERRORS
85+
? err instanceof Error
86+
? err.message
87+
: String(err)
88+
: "unavailable";
89+
}
90+
// Check RabbitMQ with timeout
91+
try {
92+
await withTimeout(
93+
Promise.resolve((0, rabbitmq_1.getRabbitChannel)()),
94+
HEALTH_TIMEOUT_MS,
95+
"rabbitmq",
96+
);
97+
result.components.rabbitmq.status = "OK";
98+
} catch (err) {
99+
result.status = "NOT_OK";
100+
result.components.rabbitmq.status = "DOWN";
101+
result.components.rabbitmq.error = EXPOSE_ERRORS
102+
? err instanceof Error
103+
? err.message
104+
: String(err)
105+
: "unavailable";
106+
}
107+
const code = result.status === "OK" ? 200 : 503;
108+
readinessCache = { ts: now, result, code };
109+
res.status(code).json(result);
95110
});
96111
exports.default = router;

src/routes/health.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import express, { type Request, type Response } from "express";
2+
23
import fs from "fs";
34
import path from "path";
45
import { getRabbitChannel } from "../config/rabbitmq";

0 commit comments

Comments
 (0)