126 lines · 3.8 KB · TypeScript
RawDownload
import * as SqlClient from "effect/unstable/sql/SqlClient";import * as SqlSchema from "effect/unstable/sql/SqlSchema";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer"; import { toPersistenceSqlError } from "../Errors.ts"; import {  GetByCommandIdInput,  OrchestrationCommandReceipt,  OrchestrationCommandReceiptRepository,  type OrchestrationCommandReceiptRepositoryShape,} from "../Services/OrchestrationCommandReceipts.ts"; const makeOrchestrationCommandReceiptRepository = Effect.gen(function* () {  const sql = yield* SqlClient.SqlClient;   const upsertReceiptRow = SqlSchema.void({    Request: OrchestrationCommandReceipt,    execute: (receipt) =>      sql`        INSERT INTO orchestration_command_receipts (          command_id,          aggregate_kind,          aggregate_id,          command_type,          accepted_at,          result_sequence,          status,          error        )        VALUES (          ${receipt.commandId},          ${receipt.aggregateKind},          ${receipt.aggregateId},          ${receipt.commandType},          ${receipt.acceptedAt},          ${receipt.resultSequence},          ${receipt.status},          ${receipt.error}        )        ON CONFLICT (command_id)        DO UPDATE SET          aggregate_kind = excluded.aggregate_kind,            aggregate_id = excluded.aggregate_id,            command_type = excluded.command_type,          accepted_at = excluded.accepted_at,          result_sequence = excluded.result_sequence,          status = excluded.status,          error = excluded.error      `,  });   const findReceiptByCommandId = SqlSchema.findOneOption({    Request: GetByCommandIdInput,    Result: OrchestrationCommandReceipt,    execute: ({ commandId }) =>      sql`        SELECT          command_id AS "commandId",          aggregate_kind AS "aggregateKind",          aggregate_id AS "aggregateId",          command_type AS "commandType",          accepted_at AS "acceptedAt",          result_sequence AS "resultSequence",          status,          error        FROM orchestration_command_receipts        WHERE command_id = ${commandId}      `,  });   const upsert: OrchestrationCommandReceiptRepositoryShape["upsert"] = (receipt) =>    upsertReceiptRow(receipt).pipe(      Effect.mapError(toPersistenceSqlError("OrchestrationCommandReceiptRepository.upsert:query")),    );   const insertIfAbsent: OrchestrationCommandReceiptRepositoryShape["insertIfAbsent"] = (receipt) =>    sql<{ readonly command_id: string }>`      INSERT INTO orchestration_command_receipts (        command_id,        aggregate_kind,        aggregate_id,        command_type,        accepted_at,        result_sequence,        status,        error      )      VALUES (        ${receipt.commandId},        ${receipt.aggregateKind},        ${receipt.aggregateId},        ${receipt.commandType},        ${receipt.acceptedAt},        ${receipt.resultSequence},        ${receipt.status},        ${receipt.error}      )      ON CONFLICT(command_id) DO NOTHING      RETURNING command_id    `.pipe(      Effect.map((rows) => rows.length === 1),      Effect.mapError(        toPersistenceSqlError("OrchestrationCommandReceiptRepository.insertIfAbsent:query"),      ),    );   const getByCommandId: OrchestrationCommandReceiptRepositoryShape["getByCommandId"] = (input) =>    findReceiptByCommandId(input).pipe(      Effect.mapError(        toPersistenceSqlError("OrchestrationCommandReceiptRepository.getByCommandId:query"),      ),    );   return {    insertIfAbsent,    upsert,    getByCommandId,  } satisfies OrchestrationCommandReceiptRepositoryShape;}); export const OrchestrationCommandReceiptRepositoryLive = Layer.effect(  OrchestrationCommandReceiptRepository,  makeOrchestrationCommandReceiptRepository,);