Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ency07/B2B-import/llms.txt

Use this file to discover all available pages before exploring further.

A Requirement is the primary intake record for any client technical need in B2B Import ERP. In an industrial B2B context — such as HVAC engineering, extraction systems, or duct fabrication — clients express a need that must be understood, diagnosed, scoped, and ultimately converted into a quotation and then a work order. The Requirements module orchestrates this entire journey, assigning the right engineers and commercial staff at each phase, enforcing SLAs by priority, and blocking invalid transitions at the database level.

Requirement States

Requirements follow a strict sequential workflow enforced by the validate_requirement_state_transitions and enforce_requirement_permissions triggers. No state can be skipped and no transition outside the matrix is permitted.
BORRADOR


NUEVO


EN_REVISION


DIAGNOSTICO ──── requires: engineering_user_id assigned


COTIZACION ────── requires: sales_user_id assigned + DIAGNOSTIC PDF document


APROBACION ────── requires: description ≥ 15 chars + QUOTE PDF document


OT_GENERADA ───── requires: APPROVAL document + approved quote linked


EJECUCION


CERRADO
At any stage, a requirement can transition to CANCELADO provided the cancelling user supplies a cancel_code from the catalogue and a cancel_reason of at least 10 characters.

Transition Conditions

TransitionGuard Condition
EN_REVISION → DIAGNOSTICOengineering_user_id must be set
DIAGNOSTICO → COTIZACIONsales_user_id must be set; a DIAGNOSTIC PDF document must exist
COTIZACION → APROBACIONdescription ≥ 15 characters; a QUOTE PDF document must exist
APROBACION → OT_GENERADAAn APPROVAL document must exist; an APROBADA quote must be linked
ANY → CANCELADOcancel_code + cancel_reason (≥ 10 chars) required
Physical deletion of requirements is blocked by trg_block_physical_requirement_delete. All removals must use soft-delete (deleted_at). The AUDITOR role can still read soft-deleted records via RLS.

RequirementRow Interface

The following TypeScript interface is exported from src/app/actions/requirements.ts and reflects the full shape of a requirement row as returned by the server actions:
interface RequirementRow {
  id: string;
  requirement_code: string;          // Auto-generated: "REQ-000001"
  title: string;
  category: string;                  // See Categories section below
  priority: "LOW" | "MEDIUM" | "HIGH";
  status:
    | "BORRADOR"
    | "NUEVO"
    | "EN_REVISION"
    | "DIAGNOSTICO"
    | "COTIZACION"
    | "COMPLETADO"
    | "CANCELADO";
  client_id: string;
  engineering_user_id: string | null;
  sales_user_id: string | null;
  created_at: string;
  // Joined relations
  client: { legal_name: string; city: string | null } | null;
  engineering_user?: { first_name: string; last_name: string } | null;
}
requirement_code is generated transactionally using tenant_sequences as REQ-XXXXXX, ensuring no code collisions under concurrent inserts. The code is immutable after creation.

Server Actions

All server actions are declared with "use server" and run exclusively on the Next.js server. They resolve the tenant from tenantCode using getTenantId() and call supabaseAdmin — bypassing RLS — but rely on database-level triggers for permission enforcement.

getRequirements

getRequirements(tenantCode?)Returns all non-deleted requirements for the resolved tenant, ordered newest first. The response includes joined client (legal name, city) and engineering_user (first and last name) relations.
const requirements = await getRequirements("acme");
// Returns RequirementRow[]

createRequirement

createRequirement(tenantCode, reqData)Creates a new requirement in BORRADOR status. The requirement_code is auto-generated by the database trigger.
const req = await createRequirement("acme", {
  title: "Sistema de extracción bodega norte",
  clientId: "uuid-client",
  category: "FABRICACION",
  priority: "HIGH",
});

updateRequirementStatus

updateRequirementStatus(reqId, newStatus, extra?)Updates the status of a requirement along with any extra fields (e.g. engineering_user_id, cancel_code, cancel_reason). The database trigger validates the transition and RBAC before persisting.
await updateRequirementStatus(reqId, "DIAGNOSTICO", {
  engineering_user_id: "uuid-engineer",
});

Categories

Requirements are classified into industrial service categories defined in the requirements.category CHECK constraint:
Category CodeDescription
FABRICACIONCustom fabrication of HVAC components, ducts, or equipment
VENTADirect product sale (equipment or materials)
MANTENIMIENTOScheduled or preventive maintenance services
REPARACIONCorrective repair of existing installations
OTROOther technical services not covered by the above
The data dictionary lists additional operational categories (HVAC, extraction, filtration, duct installation) that map to these five canonical codes in the database. Use OTRO when the client’s need does not fit the four primary categories.

Priority Levels & SLAs

Priority is set at creation and drives automatic SLA deadline calculation by the handle_requirement_traceability trigger:
PrioritySLA — ResponseSLA — CloseTypical Use Case
LOW24 business hours240 business hoursRoutine maintenance scheduling
MEDIUM24 business hours120 business hoursStandard service requests
HIGH24 business hours72 business hoursUrgent equipment repairs
CRITICAL24 business hours48 business hoursProduction-stopping failures
SLA timestamps (sla_response_due_at, sla_diagnostic_due_at, sla_quote_due_at, sla_close_due_at) are stored in UTC and computed using the add_business_hours() function, which skips weekends.

RBAC — Role-Based Access

Permission enforcement is handled by enforce_requirement_permissions trigger and RLS policies:
ActionRoles Permitted
Create requirementEJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL, TECNICO_CAMPO
BORRADOR → NUEVOEJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL, TECNICO_CAMPO
NUEVO → EN_REVISIONEJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL, TECNICO_CAMPO
EN_REVISION → DIAGNOSTICOTECNICO_CAMPO, GERENTE_GENERAL
DIAGNOSTICO → COTIZACIONTECNICO_CAMPO, EJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL
COTIZACION → APROBACIONEJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL
APROBACION → OT_GENERADAGERENTE_GENERAL
OT_GENERADA → EJECUCIONDIRECTOR_OPERACIONES, TECNICO_CAMPO
EJECUCION → CERRADODIRECTOR_OPERACIONES, GERENTE_GENERAL
Cancel (any state)EJECUTIVO_COMERCIAL, DIRECTOR_COMERCIAL, GERENTE_GENERAL

Dashboard

Navigate to the Requirements dashboard for your tenant:
/dashboard/requirements?tenant=<code>

Build docs developers (and LLMs) love