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:
- OpenAPI genera documentación automática del shape esperado.
- Type hints en editor para quien integra la API.
- Mismo contrato funcional: campos opcionales con defaults, checks 400 originales conservados, claves extra ignoradas.
- 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
| Schema | Campos | Endpoint(s) | Propósito |
|---|---|---|---|
StencilUpdateIn | name, category, default_u_height, manufacturer (todos opcionales) | PUT /stencils/{id} | Actualizar stencil con exclude_unset para parciales |
StencilMoveIn | new_category: str | PUT /stencils/{id}/move | Mover stencil a otra categoría |
StencilFromDeviceIn | device_id (required), name (required), category (default: "Custom Devices") | POST /stencils/create_from_device | Crear stencil desde dispositivo |
CategoryDeleteIn | category: str (required) | DELETE /library/category/delete | Eliminar categoría completa |
CategoryRenameIn | old_name, new_name (ambos required) | PUT /library/category/rename | Renombrar categoría |
RackRenameIn | name (optional) | POST /{rack_id}/rename (legacy) | Renombrar rack |
VisioConfirmIn | session_id (required), masters/selected (legacy compat), category_name | POST /visio/confirm | Confirmar importación Visio |
RestoreConfirmIn | session_id (required), categories: list[str] | POST /library/restore/confirm | Confirmar restauración de backup |
16 endpoints migrados
Rutas principales (/api/racks/):
PUT /stencils/{id}→StencilUpdateInPUT /stencils/{id}/move→StencilMoveInPOST /stencils/create_from_device→StencilFromDeviceInDELETE /library/category/delete→CategoryDeleteInPUT /library/category/rename→CategoryRenameInPOST /visio/confirm→VisioConfirmInPOST /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:
-
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).
- Campos con default en schema → handler recibe valor, no
-
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).
-
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.
- Endpoints nuevos con ruta legacy usan mismos schemas (ej.
Exclusión deliberada
save_device_network_config (en racks/api/export_network_config.py y network/api/devices.py) queda fuera deliberadamente:
- Campo
config: dictes 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]]