{"message":"Pegassus-NG Backend API","version":"1.0.0","docs":"/docs","health":"/health","auth":{"login":"/api/v1/auth/login","refresh":"/api/v1/auth/refresh","logout":"/api/v1/auth/logout","me":"/api/v1/auth/me"},"companies":{"me":"/api/v1/companies/me"},"proveedores":{"by_company":"/api/v1/proveedores/{company_id}","details":"/api/v1/proveedores/{company_id}/{proveedor_id}"},"categorias":{"departamentos":"/api/v1/categorias/{company_id}/departamentos","rubros":"/api/v1/categorias/{company_id}/departamentos/{codigo_departamento}/rubros","familias":"/api/v1/categorias/{company_id}/departamentos/{codigo_departamento}/rubros/{codigo_rubro}/familias","subfamilias":"/api/v1/categorias/{company_id}/departamentos/{codigo_departamento}/rubros/{codigo_rubro}/familias/{codigo_familia}/subfamilias"},"medidas":{"by_company":"/api/v1/medidas/{company_id}","by_codigo":"/api/v1/medidas/{company_id}/{codigo_medida}"},"grupos_articulos":{"by_company":"/api/v1/grupos-articulos/{company_id}","by_codigo":"/api/v1/grupos-articulos/{company_id}/{codigo_grupo}"},"sedes":{"by_company":"/api/v1/sedes/{company_id}"},"etiquetas":{"lotes_by_sede":"/api/v1/etiquetas/{company_id}/sedes/{codigo_sede}/lotes","lote_detail":"/api/v1/etiquetas/{company_id}/sedes/{codigo_sede}/lotes/{lote_id}"},"tipos_etiquetas":{"by_company":"/api/v1/tipos-etiquetas/{company_id}"},"ofertas":{"list_by_sede":"/api/v1/articulos/{company_id}/sedes/{sede_id}/ofertas","toggle":"/api/v1/articulos/{company_id}/sedes/{sede_id}/ofertas/{id_vigencia}/toggle"},"recetas":{"by_company":"/api/v1/recetas/{company_id}","by_codigo":"/api/v1/recetas/{company_id}/{codigo_receta}"},"depositos":{"by_company_and_sede":"/api/v1/depositos/{company_id}/sede/{sede_id}","by_id":"/api/v1/depositos/{company_id}/deposito/{deposito_id}"},"ordenes_carga":{"create":"/api/v1/ordenes-carga/","get_by_id":"/api/v1/ordenes-carga/{orden_id}","get_completa":"/api/v1/ordenes-carga/{orden_id}/completa","update":"/api/v1/ordenes-carga/{orden_id}","anular":"/api/v1/ordenes-carga/{orden_id}/anular","list":"/api/v1/ordenes-carga/","detalles":{"get":"/api/v1/ordenes-carga/{orden_id}/detalles","create":"/api/v1/ordenes-carga/{orden_id}/detalles","update":"/api/v1/ordenes-carga/{orden_id}/detalles/{detalle_id}","delete":"/api/v1/ordenes-carga/{orden_id}/detalles/{detalle_id}"}},"asignacion_operadores":{"operadores_disponibles":"/api/v1/deposito/asignacion-operadores/operadores-disponibles","asignar":"/api/v1/deposito/asignacion-operadores/asignar","reasignar":"/api/v1/deposito/asignacion-operadores/reasignar","historial":"/api/v1/deposito/asignacion-operadores/historial/{id_orden_carga}","estadisticas":"/api/v1/deposito/asignacion-operadores/estadisticas/{id_operador}","carga_trabajo":"/api/v1/deposito/asignacion-operadores/carga-trabajo/{id_operador}"},"inventarios":{"tipos_by_company":"/api/v1/inventarios/tipos/{company_id}","tipo_by_id":"/api/v1/inventarios/tipos/{company_id}/tipo/{tipo_id}","by_deposito":"/api/v1/inventarios/{company_id}/sede/{codigo_sede}/deposito/{deposito_id}/inventarios","inventarios_reales":"/api/v1/inventarios/{company_id}/sede/{sede_id}/deposito/{codigo_deposito}/inventario/{inventario_pk}/inventarios-reales","inventarios_teoricos":"/api/v1/inventarios/{company_id}/sede/{sede_id}/deposito/{codigo_deposito}/inventario/{inventario_pk}/inventarios-teoricos","tramos_conteo":"/api/v1/inventarios/{company_id}/sede/{sede_id}/deposito/{codigo_deposito}/tramos-conteo"},"websocket":{"endpoints":{"orden_carga":"/ws/orden-carga","wave_picking":"/ws/wave-picking","inventario":"/ws/inventario","cierre_pos":"/ws/cierre-pos","stats":"/ws/stats"},"descripcion":"Sistema WebSocket consolidado (4 endpoints) con PostgreSQL LISTEN/NOTIFY, hardening de seguridad y filtrado inteligente","arquitectura":{"notificaciones":"PostgreSQL LISTEN/NOTIFY automático","filtrado":"Inteligente por estado, role y tipo de conexión","auth":"JWT en Sec-WebSocket-Protocol + re-validación cada 5 minutos","heartbeat":"Cliente envía ping cada 25s; server timeout 90s","reconexion":"Automática en códigos transitorios (1006/4408/4500)"},"discriminadores":{"/ws/orden-carga":{"campo":"role","valores":["cargador","deposito","supervisor_asignaciones","operador"]},"/ws/wave-picking":{"campo":"action","valores":["get_dashboard","get_zonas","get_olas_armar"]}},"codigos_cierre":{"1000":"Cierre normal (voluntario)","4400":"Bad Request — payload inválido","4401":"Unauthorized — JWT inválido o expirado","4403":"Forbidden — sin acceso o Origin no permitido","4408":"Timeout — primer mensaje o heartbeat","4429":"Rate limited","4500":"Internal error"},"ejemplo_orden_carga":{"conexion":"new WebSocket('ws://host/ws/orden-carga', ['access_token.' + jwt])","primer_mensaje":"{role: 'deposito', id_empresa: 58, id_sede: 29, codigo_deposito: 158}"},"docs":{"feature":"docs/features/2026-05-09-consolidacion-websocket-hardening.md","migration_frontend":"docs/migration-guides/2026-05-09-frontend-websocket-migration.md","tester_html":"tools/ws-tester.html"}}}