Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Danielings/Pasantia-Proyecto/llms.txt

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

Peripherals in the inventory system can live in two states: standalone (registered in the perifericos Firestore collection but not linked to any PC or Laptop) or assigned (linked to a specific equipment record via equipoId). This design allows you to track peripherals from the moment they arrive in the warehouse, before they are ever attached to a machine. The same serial-uniqueness guarantee that protects equipment serials also applies to every peripheral serial.

Peripheral Types

The system recognizes the following peripheral types, defined in inventory.constants.js:
export const PERIFERICOS_MAP = {
  monitor:   "Monitor",
  teclado:   "Teclado",
  teclados:  "Teclado",   // plural alias
  mouse:     "Mouse",
  switch:    "Switch",
  impresora: "Impresora",
  corneta:   "Corneta",
  cornetas:  "Corneta",   // plural alias
};
The URL path parameter (:tipo) is normalized before lookup, so /api/perifericos/Monitor, /api/perifericos/monitor, and /api/perifericos/MONITOR all resolve correctly.

Registering a Standalone Peripheral

POST /api/perifericos/:tipo
1

Choose the peripheral type

Use one of the keys from PERIFERICOS_MAP as the URL segment — for example /api/perifericos/monitor.
2

Build the request body

Provide serial, modelo, estado, and optionally marca, notas, procedencia, and asignacion. The peripheral starts as asignado: false with equipoId: null.
3

Submit and receive the document ID

The handler opens a transaction that checks both the indices collection and the perifericos collection for the serial before writing. On success it returns 201 Created with the new document ID.
curl -X POST http://localhost:3001/api/perifericos/monitor \
  -H "Content-Type: application/json" \
  -d '{
    "marca": "LG",
    "modelo": "27MK400H",
    "serial": "MON-LG-0312",
    "estado": "Funcional",
    "notas": "Pantalla sin rayaduras",
    "procedencia": {
      "region": "Capital",
      "estado": "Distrito Capital",
      "ciudad": "Caracas",
      "sede": "Almacén Central",
      "piso": "1"
    },
    "asignacion": null
  }'
Success response:
HTTP/1.1 201 Created

{
  "message": "Monitor registrado correctamente.",
  "id": "8hWnX2pQrMzL5cTvA9bK"
}
If the serial MON-LG-0312 already exists anywhere in the system — whether in the indices collection or the perifericos collection — the API returns 400 Bad Request with a message identifying the duplicate serial. The transaction is aborted and nothing is written.

Frontend Validation Schema

The frontend validates peripheral forms using Zod (perifericoSchema.ts) before sending data:
import { z } from "zod";

export const perifericoSchema = z.object({
  type:   z.string().min(1, "El tipo de periférico es requerido"),
  name:   z.string().min(1, "La marca es requerida"),
  model:  z.string().min(1, "El modelo es requerido"),
  serial: z.string().min(1, "El serial es requerido"),
  status: z.string().min(1, "El estado es requerido"),
  region: z.preprocess((val) => val == null ? "" : String(val),
    z.string().min(1, "La región es requerida")),
  estado: z.preprocess((val) => val == null ? "" : String(val),
    z.string().min(1, "El estado es requerido")),
  city:   z.preprocess((val) => val == null ? "" : String(val),
    z.string().min(1, "La ciudad es requerida")),
  sede:   z.preprocess((val) => val == null ? "" : String(val),
    z.string().min(1, "La sede es requerida")),
  piso:   z.preprocess((val) => val == null ? "" : String(val),
    z.string().min(1, "El piso es requerido")),
  ala:        z.preprocess((val) => val == null ? "" : String(val), z.string().optional()),
  notas:      z.string().optional(),
  asignadoA:  z.string().optional(),
});

Retrieving a Peripheral

GET /api/perifericos/:id Returns the full peripheral document. If the peripheral is currently embedded in an equipment’s perifericos array (matched by serial), the response also includes an equipoRelacionado object:
{
  "id": "8hWnX2pQrMzL5cTvA9bK",
  "tipo": "Monitor",
  "marca": "LG",
  "modelo": "27MK400H",
  "serial": "MON-LG-0312",
  "estado": "Funcional",
  "asignado": true,
  "equipoId": "3fKqL9mXzRpT2vAoW8nY",
  "equipoSerial": "DL-OPT-00142",
  "procedencia": { "region": "Capital", "estado": "Distrito Capital", "ciudad": "Caracas", "sede": "Almacén Central", "piso": "1" },
  "asignacion":  { "region": "Capital", "estado": "Distrito Capital", "ciudad": "Caracas", "sede": "Torre Norte", "piso": "4", "ala": "Este" },
  "equipoRelacionado": {
    "id": "3fKqL9mXzRpT2vAoW8nY",
    "tipo": "PC",
    "serial": "DL-OPT-00142",
    "marca": "Dell",
    "modelo": "OptiPlex 7090"
  }
}
When asignado is false, equipoRelacionado is null.

Updating a Peripheral

PUT /api/perifericos/:tipo/:id This endpoint handles three scenarios in a single transaction:
Omit asignadoA entirely. The handler updates marca, modelo, serial, estado, notas, and asignacion (if ubicacion is provided) while preserving procedencia as-is.
PUT /api/perifericos/monitor/8hWnX2pQrMzL5cTvA9bK

{
  "estado": "En Reparación",
  "notas": "Pantalla con rayaduras leves"
}
Pass the target equipment’s Firestore document ID in asignadoA. The handler:
  1. Removes the peripheral from the old equipment’s perifericos array.
  2. Adds it to the new equipment’s perifericos array.
  3. Updates the perifericos document with the new equipoId, equipoSerial, and equipoRelacionado.
PUT /api/perifericos/monitor/8hWnX2pQrMzL5cTvA9bK

{
  "asignadoA": "7gRmK4nPqLzT1uBoX3cW"
}
The target equipment must not already have a peripheral of the same type. If it does, the transaction is aborted with 400 Bad Request: "El equipo ya tiene un 'Monitor' asignado.".
Pass "desvincular" (or an empty string "") in asignadoA. The peripheral is removed from the equipment’s array and its asignado flag is set back to false.
PUT /api/perifericos/monitor/8hWnX2pQrMzL5cTvA9bK

{
  "asignadoA": "desvincular"
}

One-Per-Type Constraint

The backend enforces that each equipment record may have at most one peripheral of each type. Before adding a peripheral to an equipment during a PUT, the handler inspects the existing perifericos array:
const yaTieneEsteTipo = (eqData.perifericos || []).some(
  (p) => p.tipo === tipoCorrecto && p.id !== id
);
if (yaTieneEsteTipo)
  throw badRequest(`El equipo ya tiene un "${tipoCorrecto}" asignado.`);
This means a PC can have one Monitor, one Teclado, one Mouse, and so on — but never two Monitors simultaneously.

Listing All Components and Peripherals

GET /api/componentes — requires authentication. Returns a flat array of all equipment and standalone peripherals with their location fields resolved. The response shape is:
[
  {
    "id": "3fKqL9mXzRpT2vAoW8nY",
    "tipo": "PC",
    "marca": "Dell",
    "modelo": "OptiPlex 7090",
    "serial": "DL-OPT-00142",
    "estado": "Funcional",
    "region": "Capital",
    "estado_region": "Distrito Capital",
    "ciudad": "Caracas",
    "sede": "Torre Norte",
    "piso": "4",
    "ala": "Este"
  },
  {
    "id": "8hWnX2pQrMzL5cTvA9bK",
    "tipo": "Monitor",
    "marca": "LG",
    "modelo": "27MK400H",
    "serial": "MON-LG-0312",
    "estado": "Funcional",
    "region": "Capital",
    "estado_region": "Distrito Capital",
    "ciudad": "Caracas",
    "sede": "Torre Norte",
    "piso": "4",
    "ala": "Este"
  }
]
Role-based scoping: Superadministrador users see all items across every office. All other roles only see items where asignacion.sede (or the legacy sede field) matches their own assigned office. Users with no sede on their account receive an empty array.

Verifying a Serial Before Registration

GET /api/verificar-periferico/:dispositivo/:serial Use this endpoint to check whether a serial is already in use before displaying the registration form. The :dispositivo parameter accepts any key from PERIFERICOS_MAP or COMPONENTES_MAP.
curl "http://localhost:3001/api/verificar-periferico/monitor/MON-LG-0312"
Possible responses:
// Serial exists and is assigned
{
  "existe": true,
  "asignado": true,
  "equipo": "PC",
  "serialEquipo": "DL-OPT-00142",
  "message": "Este periferico ya está asignado a un equipo (PC) con serial: DL-OPT-00142"
}

// Serial exists but is not assigned
{
  "existe": true,
  "asignado": false,
  "message": "El periferico existe en la base de datos pero no está asignado a ningún equipo."
}

// Serial is completely new
{
  "existe": false,
  "asignado": false,
  "message": "El periferico está disponible y será registrado como nuevo."
}

Build docs developers (and LLMs) love