import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import { companyLifecycle } from "../db/company.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { CompanyNotFoundError, InvalidStateError, MissingRequiredFieldsError, InvalidBaseCurrencyError, } from "../lib/errors.generated"; import type { PrimitivesQueries } from "../module"; export interface ActivateCompanyInput { companyId: string; } /** * Function: activateCompany * * Transitions a company from DRAFT to ACTIVE status, making it available for * transactional modules to reference. All required fields must be configured * before activation. */ export async function run( db: Transaction, input: ActivateCompanyInput, ctx: CommandContext, primitivesQueries?: Pick, ) { const { companyId } = input; // 1. Find company with forUpdate const existing = await db .selectFrom("Company") .selectAll() .where("id", "=", companyId) .forUpdate() .executeTakeFirst(); if (!existing) { return err(new CompanyNotFoundError(companyId)); } // 2. Must be DRAFT const nextStatus = companyLifecycle.tryTransition(existing.status, "activate"); if (!nextStatus) { return err(new InvalidStateError(companyId)); } // 3. Check required fields if ( !existing.legalName || (typeof existing.legalName === "string" && existing.legalName.trim() === "") ) { return err(new MissingRequiredFieldsError(companyId)); } if (!existing.baseCurrencyId) { return err(new MissingRequiredFieldsError(companyId)); } if (!existing.street) { return err(new MissingRequiredFieldsError(companyId)); } if (!existing.city) { return err(new MissingRequiredFieldsError(companyId)); } if (!existing.postalCode) { return err(new MissingRequiredFieldsError(companyId)); } if (!existing.country) { return err(new MissingRequiredFieldsError(companyId)); } // 4. Validate base currency exists and is active if (primitivesQueries) { const { currency } = ( await primitivesQueries.getCurrency(db, { id: existing.baseCurrencyId }, ctx) ).value; if (currency?.status !== "ACTIVE") { return err(new InvalidBaseCurrencyError(companyId)); } } // 5. Set status ACTIVE const company = await db .updateTable("Company") .set({ status: nextStatus, }) .where("id", "=", companyId) .returningAll() .executeTakeFirstOrThrow(); return ok({ company }); }