Edifiko
Edifiko DocsDocumentación del proyecto
  • Overview
Proyecto
  • README
  • CONTRIBUTING
  • WORKFLOW
  • Workflows CI/CD
  • UI Components
  • Showcase: Works UI Components
  • Schemas
  • Servicios
  • Hooks
  • Utils
  • Types
  • Constants
  • Errors
  • API Materiales
Herramientas de IA
  • Agentes
  • Skills
  1. Documentación
  2. Api
  3. Materials

API REST — Materiales

docs/api/materials.md

API REST — Materiales

Documentación del endpoint REST para consulta del catálogo de materiales. Opera en el contexto de servidor (Next.js Route Handler) y aplica control de acceso por rol.

Descripción General

El endpoint GET /api/materials expone el catálogo de materiales con soporte para paginación, búsqueda por texto y filtros de categorización. La respuesta varía según el rol del usuario que realiza la petición:

  • Rol admin: consulta en vivo a Firestore con filtros compuestos aplicados directamente en la base de datos.
  • Otros roles / sin token: devuelve el catálogo desde caché ISR de Next.js con filtrado en memoria.

Archivo

text
app/api/materials/route.ts

🔌 Endpoints

GET /api/materials

Retorna una lista paginada de materiales activos.

Query Parameters

ParámetroTipoDefaultDescripción
pagenumber1Número de página (mínimo: 1)
limitnumber50Items por página (mínimo: 1, máximo: 200)
searchstring""Filtro de búsqueda por nombre (normalizado, sin diacríticos)
groupIdstring—Filtra por ID de rubro
categoryIdstring—Filtra por ID de categoría
subcategoryIdstring—Filtra por ID de subcategoría

Headers

HeaderDescripción
AuthorizationBearer <idToken> — opcional. Si se provee un token válido con rol admin, se salta la caché.

Respuesta exitosa (200 OK)

json
{
  "data": [
    {
      "id": "mat-abc123",
      "name": "Cemento Portland",
      "groupId": "grp-001",
      "groupName": "Materiales estructurales",
      "categoryId": "cat-002",
      "categoryName": "Cementos",
      "subcategoryId": "sub-003",
      "subcategoryName": "Portland tipo I",
      "isActive": true,
      "createdAt": "...",
      "updatedAt": "..."
    }
  ],
  "meta": {
    "totalItems": 120,
    "totalPages": 3,
    "currentPage": 1,
    "limit": 50
  }
}

Respuesta de error (500)

json
{ "error": "Error al obtener los materiales" }

🔐 Lógica de Autorización

Request → resolveIsAdmin(request) ├─ Sin header Authorization → isAdmin = false ├─ Token inválido / expirado → isAdmin = false (nunca lanza error) └─ Token válido + role === 'admin' → isAdmin = true

La función resolveIsAdmin nunca lanza una excepción: ante cualquier error de verificación retorna false y el handler continúa con el path de caché.

🔄 Flujo de Datos por Rol

┌─────────────────────────────────────┐ │ GET /api/materials │ └──────────────────┬──────────────────┘ │ resolveIsAdmin(request) │ ┌──────────────────────┴──────────────────────┐ │ isAdmin = true isAdmin = false │ ▼ ▼ getMaterials(filters) getCachedMaterials() (Firestore live query) ('use cache' ISR) (Admin SDK, sin rules) (cacheTag: 'materials') │ │ │ applyFilters(materials, filters) │ (en memoria) └──────────────────────┬──────────────────────┘ │ search ? filter by name (normalizeText) │ paginate │ NextResponse.json(...)

📊 Índices de Firestore Requeridos

Los filtros compuestos en el path de admin requieren índices en Firestore (configurados en firestore.indexes.json):

Campos del índiceUso
isActive + groupIdFiltro solo por rubro
isActive + categoryIdFiltro solo por categoría
isActive + subcategoryIdFiltro solo por subcategoría
isActive + groupId + categoryIdFiltro por rubro y categoría
isActive + groupId + categoryId + subcategoryIdFiltro por los tres niveles de categorización

Nota: Los índices deben estar desplegados en el proyecto de Firebase antes de que las consultas admin con múltiples filtros funcionen en producción. Se despliegan con firebase deploy --only firestore:indexes.

Notas de Diseño

  • Sin caché para admin: El rol admin siempre recibe datos en tiempo real. Esto permite ver materiales recién creados sin esperar la invalidación de caché.
  • Búsqueda normalizada: El parámetro search compara textos normalizados (sin acentos, en minúsculas) tanto sobre el término de búsqueda como sobre el nombre del material. Esto permite buscar "cemento" y encontrar "Cémento".
  • Límite de 200 items: El parámetro limit tiene un tope de 200 para evitar respuestas excesivamente grandes. Para cargas masivas se recomienda la importación Excel directa vía createMaterialsBatch.