import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import { storageLocationLifecycle } from "../db/storageLocation.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { StorageLocationNotFoundError, StorageLocationNotInactiveError, SiteInactiveError, } from "../lib/errors.generated"; import type { OrganizationQueries } from "../module"; export interface ReactivateStorageLocationInput { id: string; } /** * Function: reactivateStorageLocation * * Transitions a storage location from INACTIVE back to ACTIVE status. * The parent site must still be in ACTIVE status. */ export async function run( db: Transaction, input: ReactivateStorageLocationInput, ctx: CommandContext, organizationQueries: Pick, ) { const { id } = input; // 1. Check storage location exists const location = await db .selectFrom("StorageLocation") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!location) { return err(new StorageLocationNotFoundError(id)); } // 2. Check transition is allowed const nextStatus = storageLocationLifecycle.tryTransition(location.status, "reactivate"); if (!nextStatus) { return err(new StorageLocationNotInactiveError(id)); } // 3. Validate parent site is ACTIVE const { site } = (await organizationQueries.getSite(db, { id: location.siteId }, ctx)).value; if (site?.status !== "ACTIVE") { return err(new SiteInactiveError(location.siteId)); } // 4. Update status to ACTIVE const reactivatedLocation = await db .updateTable("StorageLocation") .set({ status: nextStatus }) .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow(); return ok({ storageLocation: reactivatedLocation }); }