CreaRack-SL

Validación de esquemas de entrada en la API de biblioteca de stencils (R7-P1a)

Resumen ejecutivo

v1.45.1 introduce esquemas de validación (Ninja) en 16 endpoints de la biblioteca de stencils y gestión de racks. Cada endpoint declara formalmente qué campos acepta, con lo que:

  1. OpenAPI genera documentación automática del shape esperado.
  2. Type hints en editor para quien integra la API.
  3. Mismo contrato funcional: campos opcionales con defaults, checks 400 originales conservados, claves extra ignoradas.
  4. Sin breaking changes para callers actuales.

Es la primera mitad del lote R7-P1 de la auditoría s187 (esquemas de entrada en mutadores). La segunda mitad (blueprints, signage, vendor, fleet, Help) sigue en próximo PR.


Cambios de firma

8 esquemas nuevos en racks/schemas.py

SchemaCamposEndpoint(s)Propósito
StencilUpdateInname, category, default_u_height, manufacturer (todos opcionales)PUT /stencils/{id}Actualizar stencil con exclude_unset para parciales
StencilMoveInnew_category: strPUT /stencils/{id}/moveMover stencil a otra categoría
StencilFromDeviceIndevice_id (required), name (required), category (default: "Custom Devices")POST /stencils/create_from_deviceCrear stencil desde dispositivo
CategoryDeleteIncategory: str (required)DELETE /library/category/deleteEliminar categoría completa
CategoryRenameInold_name, new_name (ambos required)PUT /library/category/renameRenombrar categoría
RackRenameInname (optional)POST /{rack_id}/rename (legacy)Renombrar rack
VisioConfirmInsession_id (required), masters/selected (legacy compat), category_namePOST /visio/confirmConfirmar importación Visio
RestoreConfirmInsession_id (required), categories: list[str]POST /library/restore/confirmConfirmar restauración de backup

16 endpoints migrados

Rutas principales (/api/racks/):

  • PUT /stencils/{id} → StencilUpdateIn
  • PUT /stencils/{id}/move → StencilMoveIn
  • POST /stencils/create_from_device → StencilFromDeviceIn
  • DELETE /library/category/delete → CategoryDeleteIn
  • PUT /library/category/rename → CategoryRenameIn
  • POST /visio/confirm → VisioConfirmIn
  • POST /library/restore/confirm → RestoreConfirmIn

Wrappers legacy (/api/stencils/, /api/library/, /api/visio/):

  • /api/stencils/{id} (PUT)
  • /api/stencils/{id}/move (PUT)
  • /api/stencils/create_from_device (POST)
  • /api/library/category/delete (DELETE)
  • /api/library/category/rename (PUT)
  • /api/library/restore/confirm (POST)
  • /api/visio/confirm (POST)

En racks/api/racks.py:

  • POST /{rack_id}/rename → RackRenameIn

Detalles de implementación

Semántica preservada en migración

Cada handler que migraba de payload: dict = Body(...) a schema tipado mantiene:

  1. Opcionalidad e defaults:

    • Campos con default en schema → handler recibe valor, no None.
    • Handlers llaman payload.dict(exclude_unset=True) para parciales (ej. StencilUpdateIn, RackRenameIn).
  2. Checks 400 originales:

    • Mismos checks de validación lógica (ej. “new_category required”, “session_id valid”) → sin 422 nuevas.
    • Claves extra ignoradas automáticamente por Ninja (compatible con clientes legacy).
  3. Compatibilidad legacy:

    • Endpoints nuevos con ruta legacy usan mismos schemas (ej. PUT /api/library/category/rename → CategoryRenameIn).
    • Visio: acepta "masters" (frontend) y "selected" (legacy backend), vía campos separados en schema con defaults vacíos.

Exclusión deliberada

save_device_network_config (en racks/api/export_network_config.py y network/api/devices.py) queda fuera deliberadamente:

  • Campo config: dict es free-form (JSON del usuario).
  • Migración con cifrado es la task #165 (diseño separado).
  • No va en R7-P1a para no mezclar concerns.

Verificación

Procedencia de cambios:

  • racks/schemas.py: +49 líneas (8 schemas nuevos con docstrings).
  • racks/api/library.py: 16 handlers refactorizados (imports, firma de parámetro, acceso a attrs).
  • racks/api/library_files.py: imports y 3 handlers.
  • racks/api/racks.py: 1 handler.
  • CHANGELOG.md, RELEASE_NOTES.md, config/settings/base.py: version bump + notas.

Testing implícito:

  • Endpoints existentes siguen aceptando mismos request bodies.
  • OpenAPI ahora documenta el shape.
  • CI pasa sobre callers legacy.

Véase también

  • [[entity—racks—model—stencil]]
  • [[entity—racks—endpoint—update-stencil]]
  • [[entity—racks—endpoint—move-stencil]]
  • [[concept—api—validacion-entrada]]
  • [[concept—refactor—tipo-seguridad]]