From 464a098e76294e96ae0b3af89a7f77fde009f980 Mon Sep 17 00:00:00 2001 From: Giovanni Baratta Date: Mon, 19 Feb 2024 21:23:13 +0000 Subject: [PATCH] wip --- .../libs/external/src/db/run.repository.ts | 44 ++++++++++++++++ service/libs/external/src/external.module.ts | 17 +++++- .../service/src/interfaces/run.interfaces.ts | 14 +++++ service/libs/service/src/run.service.ts | 52 +++++++++++++++++++ service/libs/service/src/service.module.ts | 5 +- 5 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 service/libs/external/src/db/run.repository.ts create mode 100644 service/libs/service/src/interfaces/run.interfaces.ts create mode 100644 service/libs/service/src/run.service.ts diff --git a/service/libs/external/src/db/run.repository.ts b/service/libs/external/src/db/run.repository.ts new file mode 100644 index 0000000..848d00c --- /dev/null +++ b/service/libs/external/src/db/run.repository.ts @@ -0,0 +1,44 @@ +import {Injectable, Logger} from "@nestjs/common" +import {DatabaseClient} from "./database-client" +import {CreateRun, RunRepository} from "@libs/service/interfaces/run.interfaces" +import {TaskEither} from "fp-ts/lib/TaskEither" +import {pipe} from "fp-ts/lib/function" +import * as TE from "fp-ts/lib/TaskEither" + +@Injectable() +export class RunDbRepository implements RunRepository { + constructor(private readonly dbClient: DatabaseClient) {} + + createRun(request: CreateRun): TaskEither { + const result = pipe(request, TE.right, TE.chainW(this.persistObjectTask())) + return result + } + + private persistObjectTask(): ( + request: CreateRun + ) => TaskEither { + return request => + TE.tryCatchK( + () => + this.dbClient.run + .create({ + data: { + createdAt: request.baseRun.createdAt, + state: request.baseRun.state, + sourceCodeId: request.sourceCodeId, + planId: request.planId, + id: request.baseRun.id, + updatedAt: request.baseRun.updatedAt + }, + select: { + id: true + } + }) + .then(result => result.id), + error => { + Logger.error("Error while creating run") + throw error + } + )() + } +} diff --git a/service/libs/external/src/external.module.ts b/service/libs/external/src/external.module.ts index 6452e74..2d843d5 100644 --- a/service/libs/external/src/external.module.ts +++ b/service/libs/external/src/external.module.ts @@ -5,6 +5,8 @@ import {SourceCodeDbRepository} from "./db/source-code.repository" import {PLAN_REPOSITORY_TOKEN} from "@libs/service/interfaces/plan.interfaces" import {PlanDbRepository} from "./db/plan.repository" import {Config} from "./config/config" +import {RUN_REPOSITORY_TOKEN} from "@libs/service/interfaces/run.interfaces" +import {RunDbRepository} from "./db/run.repository" const sourceCodeRepository = { provide: SOURCE_CODE_REPOSITORY_TOKEN, @@ -16,9 +18,20 @@ const planRepository = { useClass: PlanDbRepository } +const runRepository = { + provide: RUN_REPOSITORY_TOKEN, + useClass: RunDbRepository +} + @Module({ imports: [], - providers: [sourceCodeRepository, planRepository, DatabaseClient, Config], - exports: [sourceCodeRepository, planRepository] + providers: [ + sourceCodeRepository, + planRepository, + runRepository, + DatabaseClient, + Config + ], + exports: [sourceCodeRepository, planRepository, runRepository] }) export class ExternalModule {} diff --git a/service/libs/service/src/interfaces/run.interfaces.ts b/service/libs/service/src/interfaces/run.interfaces.ts new file mode 100644 index 0000000..66f96ec --- /dev/null +++ b/service/libs/service/src/interfaces/run.interfaces.ts @@ -0,0 +1,14 @@ +import {BaseRun} from "@libs/domain" +import {TaskEither} from "fp-ts/lib/TaskEither" + +export interface RunRepository { + createRun(request: CreateRun): TaskEither +} + +export interface CreateRun { + baseRun: BaseRun + sourceCodeId: string + planId: string +} + +export const RUN_REPOSITORY_TOKEN = "RUN_REPOSITORY_TOKEN" diff --git a/service/libs/service/src/run.service.ts b/service/libs/service/src/run.service.ts new file mode 100644 index 0000000..b9ab6a1 --- /dev/null +++ b/service/libs/service/src/run.service.ts @@ -0,0 +1,52 @@ +import {RunDbRepository} from "@libs/external/db/run.repository" +import {Inject, Injectable, Logger} from "@nestjs/common" +import {randomUUID} from "crypto" +import {Either} from "fp-ts/lib/Either" +import {pipe} from "fp-ts/lib/function" +import * as TE from "fp-ts/lib/TaskEither" + +@Injectable() +export class RunService { + constructor( + @Inject("RUN_REPOSITORY_TOKEN") + private readonly runRepository: RunDbRepository + ) {} + + async createRun(request: CreateRun): Promise> { + const createdAt = new Date() + + // Wrap in a lambda to preserve the "this" context + const persistRun = (req: CreateRun) => + this.runRepository.createRun({ + sourceCodeId: req.sourceCodeId, + planId: req.planId, + baseRun: { + createdAt, + updatedAt: createdAt, + state: "pending_validation", + id: randomUUID() + } + }) + + const result = await pipe( + request, + TE.right, + TE.chainW(persistRun), + TE.chainW((result: string) => logCreateResult(result, request)) + )() + + return result + } +} + +const logCreateResult = (result: string, conxtext: CreateRun) => { + Logger.log( + `Created run with id ${result} for source code ${conxtext.sourceCodeId} and plan ${conxtext.planId}` + ) + return TE.right(result) +} + +export interface CreateRun { + sourceCodeId: string + planId: string +} diff --git a/service/libs/service/src/service.module.ts b/service/libs/service/src/service.module.ts index 6825f9a..d99751c 100644 --- a/service/libs/service/src/service.module.ts +++ b/service/libs/service/src/service.module.ts @@ -2,10 +2,11 @@ import {Module} from "@nestjs/common" import {SourceCodeService} from "./source-code.service" import {ExternalModule} from "@libs/external/external.module" import {PlanService} from "./plan.service" +import {RunService} from "./run.service" @Module({ imports: [ExternalModule], - providers: [SourceCodeService, PlanService], - exports: [SourceCodeService, PlanService] + providers: [SourceCodeService, PlanService, RunService], + exports: [SourceCodeService, PlanService, RunService] }) export class ServiceModule {}