tecsas3-cli
CLI del Ecosistema Salud TecsaS3 (salud_rural_segura). Multi-tenant, agent-friendly, orientado a salud rural colombiana. Diseñado para uso humano (tablas rich) y automatizable por agentes LLM (JSON determinista, modo --no-input, agent-info).
Status: Beta (Fase 4 — v0.4.0). Cubre lectura, escrituras, batch, dashboards, reportes, exports, IA v1/v2, pipelines declarativos, HCE, FHIR, golden tests y skill universal para agentes.
Instalación (desarrollo)
cd cli
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pre-commit install
tecsas3 --version
Quickstart — perfil demo
1. Config global (una vez)
mkdir $HOME\.tecsas3
@'
[profile.demo]
base_url = "https://dev.tecsas3.com"
tenant = "tecsas3-demo"
tenant_org = 1
plan_id = 4
auth_scheme = "token"
timeout = 30.0
verify_tls = true
'@ | Set-Content $HOME\.tecsas3\config.toml
O por comando:
tecsas3 util config set tenant tecsas3-demo
tecsas3 util config set tenant_org 1
tecsas3 util config set plan_id 4
2. Login
tecsas3 --profile demo auth login -u TU_USUARIO -p
# (token se guarda en keyring; fallback ~/.tecsas3/credentials 0600)
Alternativa no interactiva (CI / agentes):
$env:TECSAS3_PASSWORD = "..."
tecsas3 auth login -u user --no-input
3. Verificar
tecsas3 ping
tecsas3 auth whoami
tecsas3 riesgo niveles
tecsas3 paciente list --page-size 5
4. Modo JSON (agentes / pipes)
tecsas3 paciente list --page-size 5 --json | jq '.results[0].id'
tecsas3 util agent-info --json
tecsas3 paciente search --q Godoy --json
Uso por agentes de código
El CLI expone autodescubrimiento estructurado para LLMs y un skill universal compatible con Claude Code, OpenCode, OpenClaw, Hermes y otros.
Autodescubrimiento
tecsas3 util agent-info # descripción de recursos y golden paths
tecsas3 util schema # OpenAPI 3 del backend (alias raíz: tecsas3 schema)
tecsas3 --help # ayuda completa
Skill universal
Copia el skill a la carpeta de skills de tu agente:
# OpenCode / Hermes / OpenClaw
copy ..\docs\skills\tecsas3-cli\SKILL.md .opencode\skills\tecsas3-cli\SKILL.md
# Claude Code
copy ..\docs\skills\tecsas3-cli\SKILL.md .claude\skills\tecsas3-cli\SKILL.md
Golden paths para agentes
# 1. Descubrir
tecsas3 util agent-info --json
# 2. Conectar
tecsas3 util ping --json
tecsas3 auth whoami --json
# 3. Operar
tecsas3 --json --no-input paciente list --page-size 5
tecsas3 --json --no-input hce historia-list --paciente 123
tecsas3 --json --no-input fhir paciente-list --limit 10
# 4. Orquestar
tecsas3 --json --no-input pipe run triage.yml
Ver documentación completa en docs/GUIA_CLI_TECSA_S3.md.
Mapa real de endpoints (verificado contra dev.tecsas3.com)
| Recurso | Acción | Método + Path | Notas |
|---|---|---|---|
auth |
login (token) | POST /api/autenticar/ |
DRF Token legacy. Body {username, password} → {token} |
auth |
login (jwt) | POST /api/token/ |
SimpleJWT → {access, refresh} |
auth |
whoami | GET /persona/me/ |
Requiere tenant headers |
util |
ping | GET /health/ |
No auth, no tenant |
util |
schema | GET /api/schema/?format=json |
OpenAPI 3.0.3 (962 paths) |
paciente |
list | GET /paciente/paciente/?page=&page_size=&nivel_riesgo= |
Paginado DRF. Columnas aplanadas desde persona. |
paciente |
get | GET /paciente/paciente/{id_entero}/ |
lookup_field='id' (entero), NO UUID. Soporta --uuid. |
paciente |
search | GET /paciente/busqueda/?q= |
Búsqueda unificada. Sin ?q= → 400. |
paciente |
create | POST /paciente/paciente/ |
Requiere persona (int FK), familia (int FK), codigo_eapb (objeto). |
paciente |
update | PATCH /paciente/paciente/{id}/ |
Soporta --uuid y --data. |
persona |
me | GET /persona/me/ |
|
persona |
list/search | GET /persona/?search= |
Sin paginación |
familia |
list | GET /familia/familia/?page=&page_size= |
Paginado |
familia |
get | GET /familia/familia/{id}/ |
|
agente |
list | GET /agente/api/agente/?page=&page_size= |
Paginado, incluye planes del usuario |
agente |
get | GET /agente/api/agente/{uuid}/ |
UUID |
agente |
create | POST /agente/api/agente/ |
|
agente |
ubicacion | GET /agente/api/locations/ |
Última posición GPS |
riesgo |
niveles | GET /nivel-riesgo/ |
En raíz, NO /riesgo/ |
riesgo |
patologias | GET /patologia/ |
En raíz |
riesgo |
registros | GET /registro-riesgo/?paciente=&color_semaforo= |
En raíz |
examen |
list | GET /lab/api/examen/?paciente= |
¡Sin paginación DRF! Trunca client-side con --limit |
examen |
create | POST /lab/api/examen/ |
|
batch |
run | — | Ejecuta operaciones JSON/JSONL secuencialmente. |
dashboard |
resumen | GET /api/dashboard/ |
Plan activo, conteos, series temporales |
dashboard |
metricas | GET /platform/api/v1/dashboard/{tipo}/ |
summary | activity | tenant | access |
dashboard |
paciente-stats | GET /paciente/estadisticas/resumen/ |
Estadísticas agregadas de pacientes |
agente |
heatmap | GET /agente/api/locations/ |
Agregación client-side por celdas lat/lon |
agente |
kpi / kpi-detalle | GET /agente/api/kpi_agentes/ |
KPIs globales o por agente |
agente |
valoracion-dashboard | GET /agente/api/agentes/kpi/ |
Dashboard de valoraciones |
agente |
toggle-activo | POST /agente/api/agente/{id}/toggle-activo/ |
Activa/desactiva agente |
agente |
eventos-list / logs-list | GET /agente/api/eventos/ / logs-agente/ |
Actividad de agentes |
agente |
autocomplete | GET /agente/api/autocomplete/{model}/ |
Autocomplete de modelos |
riesgo |
patologia-list/get | GET /patologia/ |
Catálogo de patologías (raíz, no /riesgo/) |
riesgo |
nivel-riesgo-list/get | GET /nivel-riesgo/ |
Niveles de riesgo HL7 |
riesgo |
registro-list/get/create | GET/POST /registro-riesgo/ |
Registros de riesgo de pacientes |
riesgo |
registro-por-agente | GET /registro-riesgo-por-agente/ |
Registros del agente autenticado |
ia |
chat-list | GET /api/ia/chat/ |
Chats de consulta IA |
ia |
v2-chat-list/mensaje/analyze | GET/POST /api/ia/v2/chats/... |
Chat IA versión 2 |
ia |
v2-patient-search / v2-family-search | GET /api/ia/v2/patients/search/ |
Búsqueda para contexto IA |
ia |
v2-consulta-libre | POST /api/ia/v2/consultations/free/ |
Consulta libre sin chat |
ia |
ai-query | POST /api/ia/ia/ai-query/ |
Consulta simple a IA |
ia |
examen-search / examen-prompt | GET/POST /api/ia/examenes/ |
Exámenes para chat IA |
ia |
chat-get | GET /api/ia/chat/{id}/detalle/ |
Detalle con mensajes (--detalle) |
ia |
chat-create | POST /api/ia/chat/ |
|
ia |
chat-export | POST /api/ia/chat/{id}/exportar_{fmt}/ |
markdown | pdf | word | email | fhir. Requiere --mensaje-id |
ia |
chat-exports | GET /api/ia/chat/{id}/historial_exportaciones/ |
|
ia |
auditorias | GET /api/ia/auditorias/ |
--stats para métricas globales |
reportes |
list | GET /dashboard/api/reports/scheduled/ |
Reportes programados |
reportes |
create | POST /dashboard/api/reports/scheduled/ |
|
reportes |
execute | POST /dashboard/api/reports/scheduled/{id}/execute_now/ |
Ejecutar ahora |
reportes |
executions | GET /dashboard/api/reports/executions/ |
|
reportes |
notifications | GET /dashboard/api/reports/notifications/ |
--retry <id> para reintentar |
export |
paciente/examen/agente | — | Volcados paginados a CSV/JSON/Parquet |
hce |
historias | GET /hce/api/historias/ |
Lista plana por paciente |
hce |
notas | GET /hce/api/notas/ |
Notas clínicas de una historia |
hce |
diagnosticos | GET /hce/api/diagnosticos/ |
Diagnósticos CIE-10 |
hce |
ordenes | GET /hce/api/ordenes/ |
Órdenes médicas |
hce |
formulas | GET /hce/api/formulas/ |
Fórmulas / prescripciones |
hce |
documentos | GET /hce/api/documentos/ |
Documentos adjuntos |
hce |
consentimientos | GET /hce/api/consentimientos/ |
Consentimientos informados |
hce |
escalas | GET /hce/api/escalas/ |
Escalas clínicas |
hce |
icd buscar | GET /hce/api/icd/buscar/?q= |
Búsqueda CIE-10 |
fhir |
pacientes | GET /eps_fhir/eps/fhir/pacientes/ |
Recurso Patient FHIR R4 |
fhir |
diagnostic-reports | GET /eps_fhir/eps/fhir/diagnostic-reports/ |
DiagnosticReport |
fhir |
observations | GET /eps_fhir/eps/fhir/observations/ |
Observation |
fhir |
agents | GET /eps_fhir/eps/fhir/agents/ |
Agentes como Practitioner/Organization |
fhir |
organizations | GET /eps_fhir/eps/fhir/organizations/ |
Organization (EAPB) |
fhir |
bundle | POST /eps_fhir/eps/fhir/bundle/ |
Bundle collection/transaction |
fhir |
export | — | Exportación de recurso FHIR a archivo |
fhir |
logs | GET /eps_fhir/eps/fhir/logs/ |
Logs de integración FHIR |
Quirks documentados
- Multi-tenant headers obligatorios en paths protegidos (
/api/,/paciente/,/familia/,/agente/api/,/ia/,/lab/api/, etc.). El CLI envíaX-Tenant-Slug,X-Tenant-Org-ID,X-Plan-IDautomáticamente desde el perfil. paciente/paciente/{id}/usa ID interno entero, no el UUID. Para resolver UUID → ID interno, usapaciente search --uuid <uuid>opaciente get --uuid <uuid>.- POST/PATCH de paciente esperan FKs enteras, no objetos persona anidados. Ejemplo:
--persona-id 5267 --familia-id 1959 --eapb-codigo FAMISANAR --eapb-nombre FAMISANAR. riesgovive en raíz (/nivel-riesgo/,/patologia/,/registro-riesgo/). Las URLs/riesgo/*devuelven 404./lab/api/examen/no pagina (ViewSet sinpagination_class). El CLI limita client-side./paciente/busqueda/rechaza búsquedas vacías con 400. Siempre pasa--qo--uuid.- Auth dual: soporta Token legacy (
Authorization: Token <...>) y JWT (Authorization: Bearer <...>). Auto-detección: si el token empieza coneyJ, se asume JWT. - HCE vive bajo
/hce/api/; la respuesta de historias es una lista plana (no paginada). - FHIR vive bajo
/eps_fhir/eps/fhir/. El endpoint/eps_fhir/eps/patients/devuelve 500 (bug backend); usarfhir paciente-list.
Escrituras y batch (Fase 1)
# Actualizar riesgo de paciente por UUID
tecsas3 paciente update --uuid 673b20ba-7784-468c-8b74-40db428ed267 --data '{"nivel_riesgo":"amarillo"}'
# Crear examen
tecsas3 examen create --paciente 2760 --descripcion "Hemoglobina"
# Crear agente
tecsas3 agente create --numero-ebs EBS999 --esta-activo
# Batch desde JSON array
tecsas3 batch run operaciones.json
Formatos soportados por batch run:
- JSON array:
[{"op":"paciente.create","payload":{...}}, ...] - JSON Lines: una operación por línea.
- JSON object:
{"operations": [...]}
Operaciones soportadas en batch: paciente.create/update/get, examen.create/list, agente.create/get.
Reportes, dashboard, IA y exports ETL (Fase 2)
# Dashboard del tenant
tecsas3 dashboard resumen --json
# Métricas de plataforma
tecsas3 dashboard metricas --tipo summary
# Estadísticas de pacientes
tecsas3 dashboard paciente-stats
# Heatmap de ubicaciones de agentes (agregado client-side)
tecsas3 agente heatmap --precision 2 --exclude-invalid --json
# KPIs y actividad de agentes
tecsas3 agente kpi --json
tecsas3 agente kpi-detalle <uuid-agente> --json
tecsas3 agente valoracion-dashboard --json
tecsas3 agente eventos-list --agente <uuid-agente> --page-size 5 --json
tecsas3 agente logs-list --page-size 5 --json
tecsas3 agente autocomplete perfil_personal --q juan
# Riesgo
tecsas3 riesgo patologia-list
tecsas3 riesgo nivel-riesgo-list
tecsas3 riesgo registro-list --color rojo --agente <uuid-agente>
tecsas3 riesgo registro-por-agente --color verde --json
# Chats IA
tecsas3 ia chat-list
tecsas3 ia chat-get <uuid> --detalle
tecsas3 ia chat-create --tipo general
tecsas3 ia chat-export <uuid> markdown --mensaje-id <msg-id>
# Reportes programados
tecsas3 reportes list
tecsas3 reportes execute 7
tecsas3 reportes executions
# Exports ETL (CSV / JSON / Parquet)
tecsas3 export paciente --riesgo rojo --file pacientes_rojo.csv
tecsas3 export examen --paciente 2760 --file examenes.json
tecsas3 export agente --file agentes.parquet # requiere pip install 'tecsas3-cli[etl]'
# Pipelines declarativos (encadenar recursos)
tecsas3 pipe init triage.yml # genera plantilla
tecsas3 pipe validate triage.yml # valida sintaxis
tecsas3 pipe run triage.yml --json # ejecuta; usa ${step.path} para encadenar
HCE y FHIR (Fase 4)
# HCE - Historia clínica electrónica
tecsas3 hce historia-list --paciente 123 --json
tecsas3 hce nota-list --historia 456 --json
tecsas3 hce diagnostico-list --historia 456 --json
tecsas3 hce orden-list --historia 456 --json
tecsas3 hce formula-list --historia 456 --json
tecsas3 hce icd-search diabetes --json
# FHIR R4
tecsas3 fhir paciente-list --limit 10 --json
tecsas3 fhir paciente-get 123 --json
tecsas3 fhir diagnostic-report-list --patient-id 123 --json
tecsas3 fhir resultado-examen-list --patient-id 123 --json
tecsas3 fhir export-fhir-bundle --type collection --entries bundle.json --json
tecsas3 fhir export --formato fhir --output paciente_123.fhir.json
Semáforo HL7 de riesgo
| Color | Nivel | Código HL7 |
|---|---|---|
| blanco | Negligible | 0 |
| verde | Bajo | 1 |
| amarillo | Moderado | 2 |
| naranja | Alto | 3 |
| rojo | Certero | 4 |
| negro | Desconocido | 5 |
| azul | No aplica | 6 |
Códigos de salida
| Código | Significado |
|---|---|
| 0 | Éxito |
| 1 | Error de negocio (404, 400, validación) |
| 2 | Error del backend (5xx) |
| 3 | Error de autenticación (401/403) |
| 4 | Error de configuración (falta tenant/base_url) |
| 5 | Error de red (timeout, DNS, TLS) |
| 99 | Error inesperado (ver --debug) |
Seguridad y PHI
- HTTPS obligatorio (
verify_tls=truepor defecto;--insecuresólo con--debug). - Tokens en
keyringdel sistema; fallback~/.tecsas3/credentialscon permisos0600. - Redacción PHI en logs por defecto (
nombres,cedula,diagnóstico, etc.). Desactivar sólo con--debug --redact-phi=false(uso estrictamente de depuración). - Multi-tenant: nunca se omite
X-Tenant-*en paths protegidos. - Rotación:
tecsas3 auth logoutborra tokens locales. Para revocación server-side, usar admin Django o blacklist JWT.
Estructura
cli/
├── pyproject.toml
├── README.md
├── .gitignore
├── data/
│ └── openapi.json # gitignored (PHI posible)
└── src/tecsas3_cli/
├── __init__.py
├── __main__.py
├── cli.py # entry Typer
├── runtime.py # agregación Settings+Client+Output
├── config.py # perfiles, env, TOML
├── http_client.py # httpx + auth + tenant + errores
├── auth.py # keyring + fallback 0600
├── output.py # table/json/yaml/csv
├── errors.py # jerarquía TecsaError + factory HTTP
├── redaction.py # PHI redactor
├── agent_info.py # autodescripción para LLMs
└── resources/
├── auth.py # login/whoami/logout
├── util.py # ping/schema/agent-info/config
├── paciente.py
├── persona.py
├── familia.py
├── agente.py
├── riesgo.py
├── examen.py
├── dashboard.py # dashboards y estadísticas
├── ia.py # chats/auditorías IA
├── reportes.py # reportes programados
├── export.py # volcados ETL
├── pipeline.py # orquestador declarativo YAML
├── hce.py # Historia Clínica Electrónica
└── fhir.py # Recursos FHIR R4
Desarrollo
ruff check . && ruff format .
mypy src/tecsas3_cli
pytest
Roadmap
| Fase | Estado | Cobertura |
|---|---|---|
| 0 — Fundaciones | ✅ Hecho | scaffold, config, http, auth, resources básicos, smoke dev |
| 1 — MVP | ✅ Hecho | escrituras (create/update paciente, examen), paciente get --uuid, batch JSON |
| 2 — Ampliación | ✅ Hecho | dashboard, métricas, reportes, heatmap, IA chat/auditorías, exports ETL |
| 3 — Agentes | ✅ Hecho | IA v2, pipe, golden tests, modo --json --no-input |
| 4 — HCE + FHIR | ✅ Hecho | recursos hce y fhir, 69 tests verdes |
| 5 — Distribución | ⏳ | PyPI privado, autocompletado, hardening adicional, snapshots JSON |
Metadata
Release files for tecsas3-cli 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| tecsas3_cli-0.5.0.tar.gz | 54.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tecsas3_cli-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 124.7 kB
Release files / tecsas3_cli-0.5.0.tar.gz
| Download URL | tecsas3_cli-0.5.0.tar.gz |
|---|---|
| Size | 54.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1be232259613995b5a16d7f167efaeb306cab496eee0f8aad874298188d33807
|
|
BLAKE2b-256 checksum How to use checksums |
3df86e5892a5e78319eace788cb95b19bbe3258412e4947fcb518adb4b91e6b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / tecsas3_cli-0.5.0-py3-none-any.whl
| Download URL | tecsas3_cli-0.5.0-py3-none-any.whl |
|---|---|
| Size | 69.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
241c0ca56f37a084c8fb533f9418d8d649d1536d8f48fec3f7f1bf88ade467dc
|
|
BLAKE2b-256 checksum How to use checksums |
8c825412533cef55598a78304be2c6e8271ecc5e8138be1921f7918963c4c170
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Security for tecsas3-cli 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.