Skip to content

Commit

Permalink
AB#143 feat: return BaseRun when creating a new run
Browse files Browse the repository at this point in the history
  • Loading branch information
giovannibaratta committed Feb 25, 2024
1 parent f227894 commit d5d075f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 25 deletions.
1 change: 1 addition & 0 deletions service/libs/domain/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface BaseRun {
| "rejected"
createdAt: Date
updatedAt: Date
revision: bigint
}

export interface Run extends BaseRun {
Expand Down
75 changes: 56 additions & 19 deletions service/libs/external/src/db/run.repository.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,82 @@
import {Injectable, Logger} from "@nestjs/common"
import {DatabaseClient} from "./database-client"
import {Run as PrismaRun} from "@prisma/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"
import {BaseRun} from "@libs/domain"
import {Either, isLeft} from "fp-ts/lib/Either"
import {either} from "fp-ts"

@Injectable()
export class RunDbRepository implements RunRepository {
constructor(private readonly dbClient: DatabaseClient) {}

createRun(request: CreateRun): TaskEither<never, string> {
const result = pipe(request, TE.right, TE.chainW(this.persistObjectTask()))
createRun(request: CreateRun): TaskEither<"unknown_run_state", BaseRun> {
const result = pipe(
request,
TE.right,
TE.chainW(this.persistObjectTask()),
TE.chainW(mapToDomain)
)
return result
}

private persistObjectTask(): (
request: CreateRun
) => TaskEither<never, string> {
) => TaskEither<never, PrismaRun> {
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,
revision: 0
},
select: {
id: true
}
})
.then(result => result.id),
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,
revision: request.baseRun.revision
}
}),
error => {
Logger.error("Error while creating run")
throw error
}
)()
}
}

function mapToDomain(run: PrismaRun): TaskEither<"unknown_run_state", BaseRun> {
const eitherState = mapState(run.state)

if (isLeft(eitherState)) {
return TE.left(eitherState.left)
}

return TE.right({
id: run.id,
state: eitherState.right,
createdAt: run.createdAt,
updatedAt: run.updatedAt,
revision: run.revision
})
}

function mapState(
rawState: string
): Either<"unknown_run_state", BaseRun["state"]> {
switch (rawState) {
case "pending_validation":
return either.right("pending_validation")
case "pending_approval":
return either.right("pending_approval")
case "approved":
return either.right("approved")
case "rejected":
return either.right("rejected")
default:
return either.left("unknown_run_state")
}
}
2 changes: 1 addition & 1 deletion service/libs/service/src/interfaces/run.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {BaseRun} from "@libs/domain"
import {TaskEither} from "fp-ts/lib/TaskEither"

export interface RunRepository {
createRun(request: CreateRun): TaskEither<never, string>
createRun(request: CreateRun): TaskEither<"unknown_run_state", BaseRun>
}

export interface CreateRun {
Expand Down
13 changes: 9 additions & 4 deletions service/libs/service/src/run.service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {BaseRun} from "@libs/domain"
import {RunDbRepository} from "@libs/external/db/run.repository"
import {Inject, Injectable, Logger} from "@nestjs/common"
import {randomUUID} from "crypto"
Expand All @@ -12,7 +13,9 @@ export class RunService {
private readonly runRepository: RunDbRepository
) {}

async createRun(request: CreateRun): Promise<Either<never, string>> {
async createRun(
request: CreateRun
): Promise<Either<"unknown_run_state", string>> {
const createdAt = new Date()

// Wrap in a lambda to preserve the "this" context
Expand All @@ -24,22 +27,24 @@ export class RunService {
createdAt,
updatedAt: createdAt,
state: "pending_validation",
id: randomUUID()
id: randomUUID(),
revision: 0n
}
})

const result = await pipe(
request,
TE.right,
TE.chainW(persistRun),
TE.chainW((result: string) => logCreateResult(result, request))
TE.chainW((result: BaseRun) => logCreateResult(result, request)),
TE.map(result => result.id)
)()

return result
}
}

const logCreateResult = (result: string, conxtext: CreateRun) => {
const logCreateResult = (result: BaseRun, conxtext: CreateRun) => {
Logger.log(
`Created run with id ${result} for source code ${conxtext.sourceCodeId} and plan ${conxtext.planId}`
)
Expand Down
1 change: 1 addition & 0 deletions service/libs/testing/src/mocks/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function generateMockRun(overrides: Partial<BaseRun>): BaseRun {
]),
createdAt: new Date(),
updatedAt: new Date(),
revision: BigInt(random.integer()),
...overrides
}

Expand Down
5 changes: 4 additions & 1 deletion service/main/src/controller/run.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export class RunController {
})

if (isLeft(eitherRun)) {
throw new InternalServerErrorException()
throw new InternalServerErrorException({
message: "Unkwon error",
error: eitherRun.left.toUpperCase()
})
}

const run = eitherRun.right
Expand Down

0 comments on commit d5d075f

Please sign in to comment.