get backend from TezosLink

This commit is contained in:
Hugo Lextrait 2023-03-02 16:53:14 +01:00
parent 6ec76544e2
commit ad4f692732
29 changed files with 143 additions and 120 deletions

View File

@ -61,3 +61,4 @@ export default class ProjectController extends ApiController {
this.httpCreated(res, await this.projectService.create(projectEntity)); this.httpCreated(res, await this.projectService.create(projectEntity));
} }
} }

View File

@ -2,7 +2,7 @@ import { Container } from "typedi";
import ProjectController from "./ProjectController"; import ProjectController from "./ProjectController";
export default { export default {
start: () => { start: () => {
Container.get(ProjectController); Container.get(ProjectController);
}, }
}; }

View File

@ -10,7 +10,7 @@ export default function errorHandler(error: any, req: Request, response: Respons
if (error instanceof SyntaxError && errorStatus === 400 && "body" in error) { if (error instanceof SyntaxError && errorStatus === 400 && "body" in error) {
response.status(HttpCodes.BAD_REQUEST).send({ response.status(HttpCodes.BAD_REQUEST).send({
body: error["body"], body: error["body"],
type: error as any["type"], type: error as any ["type"],
}); });
return; return;
} }
@ -22,3 +22,4 @@ export default function errorHandler(error: any, req: Request, response: Respons
next(error); next(error);
} }

View File

@ -26,3 +26,4 @@ export default class TezosLink {
return name; return name;
} }
} }

View File

@ -64,7 +64,7 @@ export default class MetricRepository {
const data = { ...metricEntity }; const data = { ...metricEntity };
const result: MetricEntity[] = []; const result: MetricEntity[] = [];
this.instanceDb.$transaction(async (transaction: Prisma.TransactionClient) => { this.instanceDb.$transaction(async(transaction: Prisma.TransactionClient) => {
for (const item of data) { for (const item of data) {
if (!item) continue; if (!item) continue;
result.push( result.push(
@ -187,3 +187,4 @@ export default class MetricRepository {
} }
} }
} }

View File

@ -30,7 +30,8 @@ export default class ProjectRepository {
Metrics: true, Metrics: true,
_count: { _count: {
select: { Metrics: true }, select: { Metrics: true },
}, },
}, },
}); });
} catch (error) { } catch (error) {
@ -58,3 +59,4 @@ export default class ProjectRepository {
} }
} }
} }

View File

@ -5,27 +5,27 @@ export default class MetricEntity {
@IsNotEmpty() @IsNotEmpty()
public id!: number; public id!: number;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public path!: string; public path!: string;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public uuid!: string; public uuid!: string;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public remote_address!: string; public remote_address!: string;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public date_requested!: Date; public date_requested!: Date;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public projectId!: number; public projectId!: number;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty(({groups: ["create"]}))
public project!: ProjectEntity; public project!: ProjectEntity;
@IsDate() @IsDate()
public createdAt?: Date; public createdAt?: Date;
@IsDate() @IsDate()
public updatedAt?: Date; public updatedAt?: Date;
} }

View File

@ -5,19 +5,19 @@ export default class ProjectEntity {
@IsNotEmpty() @IsNotEmpty()
public id!: number; public id!: number;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty({groups: ["create"]})
public title!: string; public title!: string;
@IsNotEmpty() @IsNotEmpty()
public uuid!: string; public uuid!: string;
@IsDate() @IsDate()
public createdAt!: Date; public createdAt!: Date;
@IsDate() @IsDate()
public updatedAt!: Date; public updatedAt!: Date;
@IsNotEmpty({ groups: ["create"] }) @IsNotEmpty({groups: ["create"]})
public network!: string; public network!: string;
@IsOptional() @IsOptional()

View File

@ -1,4 +1,4 @@
import ProjectEntity from "./ProjectEntity"; import ProjectEntity from "./ProjectEntity";
import MetricEntity from "./MetricEntity"; import MetricEntity from "./MetricEntity";
export { ProjectEntity, MetricEntity }; export { ProjectEntity, MetricEntity};

View File

@ -1 +1,2 @@
export default class BaseService {} export default class BaseService {}

View File

@ -35,15 +35,15 @@ export default class MetricService {
} }
/** /**
* *
* @throws {Error} If metric is undefined * @throws {Error} If metric is undefined
* @returns * @returns
*/ */
public async getCountRpcPath(metricEntity: Partial<MetricEntity>, from: Date, to: Date) { public async getCountRpcPath(metricEntity: Partial<MetricEntity>, from: Date, to: Date) {
const pathsCount = await this.metricRepository.countRpcPathUsage(metricEntity.projectId!, from, to); const pathsCount = await this.metricRepository.countRpcPathUsage(metricEntity.projectId!,from,to);
if (!pathsCount) return null; if (!pathsCount) return null;
return pathsCount; return pathsCount;
} }
/** /**
* *
* @throws {Error} If metric is undefined * @throws {Error} If metric is undefined
@ -60,8 +60,8 @@ export default class MetricService {
* @throws {Error} If metric is undefined * @throws {Error} If metric is undefined
* @returns * @returns
*/ */
public async getLastMetrics(metricEntity: Partial<MetricEntity>, limit: number) { public async getLastMetrics(metricEntity: Partial<MetricEntity>, limit: number){
const lastMetric = await this.metricRepository.findLastRequests(metricEntity.projectId!, limit); const lastMetric = await this.metricRepository.findLastRequests(metricEntity.projectId!,limit);
return ObjectHydrate.hydrate<Partial<MetricEntity>>(new MetricEntity(), lastMetric); return ObjectHydrate.hydrate<Partial<MetricEntity>>(new MetricEntity(), lastMetric);
} }
@ -70,8 +70,8 @@ export default class MetricService {
* @throws {Error} If metric is undefined * @throws {Error} If metric is undefined
* @returns * @returns
*/ */
public async getRequestsByDay(metricEntity: Partial<MetricEntity>, from: Date, to: Date) { public async getRequestsByDay(metricEntity: Partial<MetricEntity>, from: Date, to: Date){
const requestByDay = await this.metricRepository.findRequestsByDay(metricEntity.projectId!, from, to); const requestByDay = await this.metricRepository.findRequestsByDay(metricEntity.projectId!,from,to);
return ObjectHydrate.hydrate<Partial<MetricEntity>>(new MetricEntity(), requestByDay); return ObjectHydrate.hydrate<Partial<MetricEntity>>(new MetricEntity(), requestByDay);
} }
@ -85,3 +85,4 @@ export default class MetricService {
await this.metricRepository.removeOldMetricsBymonths(months); await this.metricRepository.removeOldMetricsBymonths(months);
} }
} }

View File

@ -4,6 +4,8 @@ import { ProjectEntity } from "@Common/ressources";
import { type processFindManyQuery } from "prisma-query"; import { type processFindManyQuery } from "prisma-query";
import { Service } from "typedi"; import { Service } from "typedi";
@Service() @Service()
export default class ProjectService { export default class ProjectService {
constructor(private projectRepository: ProjectRepository) {} constructor(private projectRepository: ProjectRepository) {}
@ -15,7 +17,7 @@ export default class ProjectService {
const projects = await this.projectRepository.findMany(query); const projects = await this.projectRepository.findMany(query);
return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), projects); return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), projects);
} }
/** /**
* @throws {Error} If project is undefined * @throws {Error} If project is undefined
*/ */
public async getByUUID(projectEntity: Partial<ProjectEntity>) { public async getByUUID(projectEntity: Partial<ProjectEntity>) {
@ -23,14 +25,15 @@ export default class ProjectService {
if (!project) return null; if (!project) return null;
return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), project); return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), project);
} }
/** /**
* *
* @throws {Error} If project cannot be created * @throws {Error} If project cannot be created
* @returns * @returns
*/ */
public async create(projectEntity: Partial<ProjectEntity>) { public async create(projectEntity: Partial<ProjectEntity>) {
const project = await this.projectRepository.create(projectEntity); const project = await this.projectRepository.create(projectEntity);
if (!project) return null; if (!project) return null;
return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), project); return ObjectHydrate.hydrate<Partial<ProjectEntity>>(new ProjectEntity(), project);
} }
} }

View File

@ -31,3 +31,4 @@ export default class ExpressServer implements ServerInterface {
return this; return this;
} }
} }

View File

@ -14,3 +14,4 @@ export default interface ServerInterface {
init(config: IConfig): this; init(config: IConfig): this;
} }

View File

@ -6,3 +6,4 @@ import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
export default abstract class ApiController extends BaseController {} export default abstract class ApiController extends BaseController {}
export { HttpCodes as ResponseStatusCodes }; export { HttpCodes as ResponseStatusCodes };

View File

@ -2,8 +2,10 @@ import { StRoute } from "./StRoute";
import { Response } from "express"; import { Response } from "express";
import HttpCodes from "@Common/system/controller-pattern/HttpCodes"; import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
type IResponseData = {} | string | number | boolean | null | unknown; type IResponseData = {} | string | number | boolean | null | unknown;
export default abstract class BaseController { export default abstract class BaseController {
public expressRoutes!: StRoute[]; public expressRoutes!: StRoute[];
public httpCode: typeof HttpCodes = HttpCodes; public httpCode: typeof HttpCodes = HttpCodes;

View File

@ -34,3 +34,4 @@ function createRoute(controller: any, route: StRoute) {
} }
export default Controller; export default Controller;

View File

@ -12,3 +12,4 @@ export default class ErrorCatch {
next(args[args.length - 1] ?? "Unknown Error"); next(args[args.length - 1] ?? "Unknown Error");
} }
} }

View File

@ -1,12 +1,7 @@
import BaseController from "./BaseController"; import BaseController from "./BaseController";
import { StRoute } from "./StRoute"; import { StRoute } from "./StRoute";
function MethodsAny( function MethodsAny(type: StRoute["type"], path: string, frontMiddlewares: StRoute["frontMiddlewares"] = [], backMiddlewares: StRoute["backMiddlewares"] = []) {
type: StRoute["type"],
path: string,
frontMiddlewares: StRoute["frontMiddlewares"] = [],
backMiddlewares: StRoute["backMiddlewares"] = [],
) {
return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => { return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => {
const func = propertyDescriptor.value; const func = propertyDescriptor.value;
const constructor: typeof BaseController = target.constructor; const constructor: typeof BaseController = target.constructor;
@ -34,3 +29,4 @@ export const Delete = MethodsAny.bind(null, "delete");
* @description Decorator Method PUT * @description Decorator Method PUT
*/ */
export const Put = MethodsAny.bind(null, "put"); export const Put = MethodsAny.bind(null, "put");

View File

@ -7,3 +7,4 @@ export interface StRoute {
frontMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[]; frontMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[];
backMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[]; backMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[];
} }

View File

@ -1,6 +1,6 @@
import dotenv from "dotenv"; import dotenv from "dotenv";
import { PrismaClient } from "@prisma/client"; import { PrismaClient } from "@prisma/client";
import IDatabaseConfig from "../../config/IDatabaseConfig"; import IDatabaseConfig from "../../config/IDatabaseConfig";
dotenv.config(); dotenv.config();
@ -8,16 +8,17 @@ export default class DbProvider {
protected client = new PrismaClient({ protected client = new PrismaClient({
datasources: { datasources: {
db: { db: {
url: `postgres://${process.env["DATABASE_USER"]}:${process.env["DATABASE_PASSWORD"]}@${process.env["DATABASE_HOSTNAME"]}:${process.env["DATABASE_PORT"]}/${process.env["DATABASE_NAME"]}`, url: `postgres://${process.env["DATABASE_USER"]}:${process.env["DATABASE_PASSWORD"]}@${process.env["DATABASE_HOSTNAME"]}:${process.env["DATABASE_PORT"]}/${process.env["DATABASE_NAME"]}`,
}, },
}, },
}); });
constructor(protected config: IDatabaseConfig) {} constructor(protected config: IDatabaseConfig) {
}
public async connect(): Promise<void> { public async connect(): Promise<void> {
await this.client.$connect(); await this.client.$connect();
console.info(`⚡️[Prisma]: Connected to ${this.config.name}`); // A Logger middleware is to be added here console.info(`⚡️[Prisma]: Connected to ${this.config.name}`);// A Logger middleware is to be added here
} }
public getClient() { public getClient() {

View File

@ -22,8 +22,15 @@ Container.get(ExpressServer).init({
label, label,
port: parseInt(port), port: parseInt(port),
rootUrl, rootUrl,
middlwares: [cors({ origin: "*" }), bodyParser.urlencoded({ extended: true }), bodyParser.json()], middlwares: [
cors({ origin: "*" }),
bodyParser.urlencoded({ extended: true }),
bodyParser.json(),
],
errorHandler, errorHandler,
}); });
routes.start(); routes.start();

View File

@ -15,7 +15,7 @@ if (!rootUrl) throw new Error(`process.env RootUrl is undefined`);
Container.get(NextServer).init({ Container.get(NextServer).init({
label, label,
isDev: process.env.NODE_ENV !== "production", isDev: process.env.NODE_ENV !== 'production',
port: parseInt(port), port: parseInt(port),
rootUrl, rootUrl,
}); });