import { ok, err } from "@tailor-platform/erp-kit/core"; import { currencyLifecycle } from "../db/currency.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { CannotDeactivateBaseCurrencyError, CurrencyNotFoundError } from "../lib/errors.generated"; export interface DeactivateCurrencyInput { currencyId: string; } /** * Function: deactivateCurrency * * Disables a currency from being used in new transactions while preserving * historical data. Base currency cannot be deactivated. */ export async function run(db: Transaction, input: DeactivateCurrencyInput) { // 1. Find currency by ID const currency = await db .selectFrom("Currency") .selectAll() .where("id", "=", input.currencyId) .forUpdate() .executeTakeFirst(); // 2. If not found, throw error if (!currency) { return err(new CurrencyNotFoundError(input.currencyId)); } // 3. Check if base currency if (currency.isBaseCurrency) { return err(new CannotDeactivateBaseCurrencyError(input.currencyId)); } // 4. If already inactive, return currency (idempotent) const nextStatus = currencyLifecycle.tryTransition(currency.status, "deactivate"); if (!nextStatus) { return ok({ currency }); } // 5. Update status to INACTIVE const updatedCurrency = await db .updateTable("Currency") .set({ status: nextStatus, }) .where("id", "=", input.currencyId) .returningAll() .executeTakeFirstOrThrow(); // 6. Return updated currency return ok({ currency: updatedCurrency }); }