Documents how the image system works internally: - img vs mrf fields explained - File naming convention (SHA256 hash) - Step-by-step image upload procedure - Common errors and solutions - Diagnostic commands 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.4 KiB
9.4 KiB
HST - Manual del Sistema de Imágenes
Versión: 1.0
Fecha: 2 Enero 2026
Servidor: HST (72.62.2.84)
1. Arquitectura del Sistema
1.1 Componentes
┌─────────────────────────────────────────────────────────────┐
│ NGINX (tzrtech.org) │
│ │
│ /thumb/{hash}.png ──────► hst-images container │
│ /{hash}.png ──────► /usr/share/nginx/html/ │
│ (mount: /root/hst_images/) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BASE DE DATOS (PostgreSQL) │
│ │
│ Tabla: hst │
│ ┌─────────┬────────────────────────────────────────────┐ │
│ │ Campo │ Descripción │ │
│ ├─────────┼────────────────────────────────────────────┤ │
│ │ ref │ Código corto (3 letras): ply, bom, led │ │
│ │ mrf │ Hash SHA256 único del tag (64 chars) │ │
│ │ img │ Hash del archivo de imagen (64 chars) │ │
│ └─────────┴────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
1.2 Directorios de Imágenes
| Ruta | Contenido | Tamaño típico |
|---|---|---|
/root/hst_images/ |
Imágenes completas | Variable |
/root/hst_images/thumb/ |
Miniaturas 64x64px | 2-5 KB |
1.3 Formato de Nombres
IMPORTANTE: Los archivos de imagen deben nombrarse con el hash SHA256 (64 caracteres):
Correcto: d674e6592894c5d7b88693a0c53ec92b84ac6cb252674c7af88dc15d51c2eb77.png
Incorrecto: ply.png
2. Campos Relevantes en Tabla HST
2.1 mrf (Mandatory Reference Field)
- Tipo: VARCHAR(64)
- Propósito: Identificador único del tag
- Formato: Hash SHA256 (64 caracteres hexadecimales)
- Uso: Clave primaria funcional, usado en relaciones (graph, tree, library)
2.2 img (Image Reference)
- Tipo: VARCHAR(64)
- Propósito: Referencia al archivo de imagen
- Formato: Hash SHA256 (64 caracteres hexadecimales)
- Uso: Genera las URLs de imagen en la API
IMPORTANTE: El campo img determina qué archivo de imagen se muestra, NO el campo mrf.
2.3 Relación img ↔ mrf
| Escenario | img | Resultado |
|---|---|---|
| img = mrf | Hash del tag | Imagen usa el mismo hash que el tag |
| img ≠ mrf | Hash diferente | Imagen tiene hash propio |
| img vacío | NULL/empty | No se muestra imagen |
3. Generación de URLs en la API
La API (Flask en hst-api container) genera las URLs así:
BASE_URL = "https://tzrtech.org"
# Si img tiene valor:
imagen_url = f"{BASE_URL}/{img}.png" # Imagen completa
thumb_url = f"{BASE_URL}/thumb/{img}.png" # Miniatura
# Si img está vacío:
imagen_url = None
thumb_url = None
Ejemplo:
Tag: ply (jugadores)
img: d674e6592894c5d7b88693a0c53ec92b84ac6cb252674c7af88dc15d51c2eb77
URLs generadas:
- https://tzrtech.org/d674e6592894c5d7b88693a0c53ec92b84ac6cb252674c7af88dc15d51c2eb77.png
- https://tzrtech.org/thumb/d674e6592894c5d7b88693a0c53ec92b84ac6cb252674c7af88dc15d51c2eb77.png
4. Procedimiento: Añadir/Reemplazar Imagen
4.1 Pasos Completos
# 1. Obtener el mrf del tag
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -t -c \
\"SELECT ref, mrf FROM hst WHERE ref = 'XXX';\""
# 2. Subir imagen con nombre = mrf (o hash deseado)
scp imagen.png root@72.62.2.84:/root/hst_images/{HASH}.png
# 3. Generar miniatura
ssh root@72.62.2.84 "convert /root/hst_images/{HASH}.png -resize 64x64 \
/root/hst_images/thumb/{HASH}.png"
# 4. Actualizar campo img en base de datos
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -c \
\"UPDATE hst SET img = '{HASH}' WHERE ref = 'XXX';\""
# 5. Verificar
curl -sI "https://tzrtech.org/thumb/{HASH}.png" | head -3
4.2 Ejemplo Práctico
Reemplazar imagen de bom (lista de materiales):
# 1. Obtener mrf
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -t -c \
\"SELECT mrf FROM hst WHERE ref = 'bom';\""
# Resultado: 23f3770b6441c8d5c9c5fd6b364972b0bf29ae5cd1782749edaae17847dac020
# 2. Subir imagen
scp bom.png root@72.62.2.84:/root/hst_images/23f3770b6441c8d5c9c5fd6b364972b0bf29ae5cd1782749edaae17847dac020.png
# 3. Generar thumb
ssh root@72.62.2.84 "convert /root/hst_images/23f3770b6441c8d5c9c5fd6b364972b0bf29ae5cd1782749edaae17847dac020.png \
-resize 64x64 /root/hst_images/thumb/23f3770b6441c8d5c9c5fd6b364972b0bf29ae5cd1782749edaae17847dac020.png"
# 4. Actualizar DB
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -c \
\"UPDATE hst SET img = '23f3770b6441c8d5c9c5fd6b364972b0bf29ae5cd1782749edaae17847dac020' WHERE ref = 'bom';\""
5. Errores Comunes
5.1 Imagen no aparece en endpoint
Síntoma: La imagen está en el servidor pero no se ve en la web.
Causas posibles:
| Causa | Diagnóstico | Solución |
|---|---|---|
| Nombre incorrecto | ls /root/hst_images/ |
Renombrar a hash correcto |
| Campo img vacío | SELECT img FROM hst WHERE ref='X' |
UPDATE hst SET img = mrf |
| img ≠ nombre archivo | Comparar img con filename | Alinear ambos valores |
| Falta thumbnail | ls /root/hst_images/thumb/ |
Generar con convert |
5.2 Error 404 en imagen
# Verificar que el archivo existe
ssh root@72.62.2.84 "ls -la /root/hst_images/{HASH}.png"
# Verificar permisos
ssh root@72.62.2.84 "chmod 644 /root/hst_images/{HASH}.png"
5.3 Imagen corrupta
# Verificar integridad
ssh root@72.62.2.84 "file /root/hst_images/{HASH}.png"
# Debe mostrar: PNG image data, ...
6. Flujo de Trabajo Recomendado
6.1 Desde R2 (documentos adjuntos)
# 1. Usuario sube imagen a R2: s3://architect/documentos adjuntos/XXX.png
# 2. Obtener hash del tag
MRF=$(ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -t -c \
\"SELECT mrf FROM hst WHERE ref = 'XXX';\"" | tr -d ' ')
# 3. Descargar de R2 y subir a HST con nombre correcto
aws s3 cp "s3://architect/documentos adjuntos/XXX.png" /tmp/img.png \
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
scp /tmp/img.png root@72.62.2.84:/root/hst_images/${MRF}.png
# 4. Generar thumbnail
ssh root@72.62.2.84 "convert /root/hst_images/${MRF}.png -resize 64x64 \
/root/hst_images/thumb/${MRF}.png"
# 5. Actualizar DB
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -c \
\"UPDATE hst SET img = '${MRF}' WHERE ref = 'XXX';\""
# 6. Limpiar R2
aws s3 rm "s3://architect/documentos adjuntos/XXX.png" \
--endpoint-url https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com
# 7. Limpiar temporal
rm /tmp/img.png
# 8. Verificar
curl -sI "https://tzrtech.org/thumb/${MRF}.png" | grep -E "HTTP|content-type"
7. Comandos de Diagnóstico
# Contar imágenes totales
ssh root@72.62.2.84 "ls /root/hst_images/*.png | wc -l"
# Contar thumbnails
ssh root@72.62.2.84 "ls /root/hst_images/thumb/*.png | wc -l"
# Tags sin imagen (img vacío)
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -c \
\"SELECT ref, nombre_es FROM hst WHERE img IS NULL OR img = '' LIMIT 20;\""
# Tags con imagen pero archivo no existe
ssh root@72.62.2.84 "docker exec postgres_hst psql -U directus -d hst_images -t -c \
\"SELECT img FROM hst WHERE img IS NOT NULL AND img != '';\"" | while read hash; do
[ -n "$hash" ] && [ ! -f "/root/hst_images/${hash}.png" ] && echo "Falta: $hash"
done
# Verificar contenedor de imágenes
ssh root@72.62.2.84 "docker ps | grep hst-images"
8. Estructura de Contenedores
hst-api → Flask API (puerto 5000)
hst-images → Nginx sirviendo imágenes (puerto 80 interno)
postgres_hst → PostgreSQL con datos
directus_hst → CMS Directus
9. URLs de Referencia
| Servicio | URL |
|---|---|
| API HST | https://tzrtech.org/api/ |
| Lista de tags | https://tzrtech.org |
| Graph Explorer | https://graph.tzrtech.org |
| Imagen directa | https://tzrtech.org/{hash}.png |
| Thumbnail | https://tzrtech.org/thumb/{hash}.png |
| Directus | https://hst.tzrtech.org |
Manual generado por Captain Claude - 2026-01-02