feat(server): add application layer to exchange rate service

This commit is contained in:
Ahmed Bouhuolia
2024-01-28 18:47:49 +02:00
parent ac7175d83b
commit 1b20d1b073
5 changed files with 54 additions and 50 deletions

View File

@@ -1,16 +1,16 @@
import { Service, Inject } from 'typedi';
import { Router, Request, Response, NextFunction } from 'express';
import { check, param, query } from 'express-validator';
import { query } from 'express-validator';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
import BaseController from './BaseController';
import { ServiceError } from '@/exceptions';
import { ExchangeRatesService } from '@/services/ExchangeRates/ExchangeRatesService';
import { EchangeRateErrors } from '@/lib/ExchangeRate/types';
import { ExchangeRateApplication } from '@/services/ExchangeRates/ExchangeRateApplication';
@Service()
export default class ExchangeRatesController extends BaseController {
@Inject()
private exchangeRatesService: ExchangeRatesService;
private exchangeRatesApp: ExchangeRateApplication;
/**
* Constructor method.
@@ -43,7 +43,7 @@ export default class ExchangeRatesController extends BaseController {
const exchangeRateQuery = this.matchedQueryData(req);
try {
const exchangeRate = await this.exchangeRatesService.latest(
const exchangeRate = await this.exchangeRatesApp.latest(
tenantId,
exchangeRateQuery
);

View File

@@ -1,36 +1,9 @@
import { IFilterRole } from './DynamicFilter';
export interface ExchangeRateLatestDTO {
toCurrency: string;
}
export interface IExchangeRate {
id: number,
currencyCode: string,
exchangeRate: number,
date: Date,
createdAt: Date,
updatedAt: Date,
};
export interface IExchangeRateDTO {
currencyCode: string,
exchangeRate: number,
date: Date,
};
export interface IExchangeRateEditDTO {
exchangeRate: number,
};
export interface IExchangeRateFilter {
page: number,
pageSize: number,
filterRoles?: IFilterRole[];
columnSortBy: string;
sortOrder: string;
};
export interface IExchangeRatesService {
newExchangeRate(tenantId: number, exchangeRateDTO: IExchangeRateDTO): Promise<IExchangeRate>;
editExchangeRate(tenantId: number, exchangeRateId: number, editExRateDTO: IExchangeRateEditDTO): Promise<void>;
deleteExchangeRate(tenantId: number, exchangeRateId: number): Promise<void>;
listExchangeRates(tenantId: number, exchangeRateFilter: IExchangeRateFilter): Promise<void>;
};
export interface EchangeRateLatestPOJO {
baseCurrency: string;
toCurrency: string;
exchangeRate: number;
}

View File

@@ -18,6 +18,9 @@ export class OpenExchangeRate implements IExchangeRateService {
baseCurrency: string,
toCurrency: string
): Promise<number> {
// Vaclidates the Open Exchange Rate api id early.
this.validateApiIdExistance();
try {
const result = await Axios.get(OPEN_EXCHANGE_RATE_LATEST_URL, {
params: {
@@ -32,9 +35,25 @@ export class OpenExchangeRate implements IExchangeRateService {
}
}
/**
* Validates the Open Exchange Rate api id.
* @throws {ServiceError}
*/
private validateApiIdExistance() {
const apiId = config.exchangeRate.openExchangeRate.appId;
if (!apiId) {
throw new ServiceError(
EchangeRateErrors.EX_RATE_SERVICE_API_KEY_REQUIRED,
'Invalid App ID provided. Please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org.'
);
}
}
/**
* Handles the latest errors.
* @param {any} error
* @throws {ServiceError}
*/
private handleLatestErrors(error: any) {
if (error.response.data?.message === 'missing_app_id') {

View File

@@ -0,0 +1,21 @@
import { Inject } from 'typedi';
import { ExchangeRatesService } from './ExchangeRatesService';
import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces';
export class ExchangeRateApplication {
@Inject()
private exchangeRateService: ExchangeRatesService;
/**
* Gets the latest exchange rate.
* @param {number} tenantId
* @param {ExchangeRateLatestDTO} exchangeRateLatestDTO
* @returns {Promise<EchangeRateLatestPOJO>}
*/
public latest(
tenantId: number,
exchangeRateLatestDTO: ExchangeRateLatestDTO
): Promise<EchangeRateLatestPOJO> {
return this.exchangeRateService.latest(tenantId, exchangeRateLatestDTO);
}
}

View File

@@ -1,16 +1,7 @@
import { Service, Inject } from 'typedi';
import { IExchangeRatesService } from '@/interfaces';
import { Service } from 'typedi';
import { ExchangeRate } from '@/lib/ExchangeRate/ExchangeRate';
import { ExchangeRateServiceType } from '@/lib/ExchangeRate/types';
interface ExchangeRateLatestDTO {
toCurrency: string;
}
interface EchangeRateLatestPOJO {
baseCurrency: string;
toCurrency: string;
exchangeRate: number;
}
import { EchangeRateLatestPOJO, ExchangeRateLatestDTO } from '@/interfaces';
@Service()
export class ExchangeRatesService {