Add HST reconstruction document 2026-01-07
Complete documentation for rebuilding the HST system including: - Database schema (tables, views, functions) - PostgREST API configuration - Nginx configuration - Web interface (index.html) with D3.js graph - Docker compose setup - Step-by-step reconstruction guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
889
docs/HST_RECONSTRUCTION_2026-01-07.md
Normal file
889
docs/HST_RECONSTRUCTION_2026-01-07.md
Normal file
@@ -0,0 +1,889 @@
|
|||||||
|
# HST - Sistema de Tags Semanticos
|
||||||
|
## Documento de Reconstruccion Completa
|
||||||
|
|
||||||
|
**Fecha:** 2026-01-07
|
||||||
|
**Version:** 2.0
|
||||||
|
**Servidor:** 72.62.2.84 (HST)
|
||||||
|
**Dominio:** tzrtech.org / hst.etereo.io
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. ARQUITECTURA GENERAL
|
||||||
|
|
||||||
|
### 1.1 Componentes
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ NGINX (Host) │
|
||||||
|
│ - SSL Termination (Let's Encrypt) │
|
||||||
|
│ - Reverse Proxy │
|
||||||
|
│ - Static Files │
|
||||||
|
└───────────────┬─────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────┼───────────┬───────────┬─────────────┐
|
||||||
|
│ │ │ │ │
|
||||||
|
▼ ▼ ▼ ▼ ▼
|
||||||
|
┌───────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐
|
||||||
|
│postgrest│ │postgres│ │directus│ │hst-api │ │filebrowser│
|
||||||
|
│ :3000 │ │ :5432 │ │ :8055 │ │ :5000 │ │ :8080 │
|
||||||
|
└────┬────┘ └────┬───┘ └────────┘ └────────┘ └──────────┘
|
||||||
|
│ │
|
||||||
|
└───────────┘
|
||||||
|
hst-net
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Contenedores Docker
|
||||||
|
| Contenedor | Puerto | Proposito | Red |
|
||||||
|
|------------|--------|-----------|-----|
|
||||||
|
| postgres_hst | 5432 | PostgreSQL 15 | hst-net |
|
||||||
|
| postgrest | 3000 | REST API automatico | hst-net |
|
||||||
|
| directus_hst | 8055 | CMS/Admin | hst-net |
|
||||||
|
| hst-api | 5000 | API legacy Flask | hst-net |
|
||||||
|
| hst-images | - | Servicio imagenes | hst-net |
|
||||||
|
| filebrowser | 8080 | Gestor archivos | hst-net |
|
||||||
|
|
||||||
|
### 1.3 Estructura de Directorios
|
||||||
|
```
|
||||||
|
/opt/hst/
|
||||||
|
├── web/
|
||||||
|
│ └── index.html # Interfaz web principal
|
||||||
|
├── assets/
|
||||||
|
│ ├── hst/ # Imagenes tags HST
|
||||||
|
│ │ └── thumb/ # Thumbnails HST
|
||||||
|
│ ├── flg/ # Imagenes flags
|
||||||
|
│ │ └── thumb/
|
||||||
|
│ ├── itm/ # Imagenes items
|
||||||
|
│ ├── loc/ # Imagenes locations
|
||||||
|
│ ├── ply/ # Imagenes players
|
||||||
|
│ └── index.html
|
||||||
|
├── nginx/
|
||||||
|
│ └── default.conf # Configuracion nginx
|
||||||
|
├── api/ # API Flask legacy
|
||||||
|
├── directus/ # Datos Directus
|
||||||
|
└── docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. BASE DE DATOS
|
||||||
|
|
||||||
|
### 2.1 Tablas Principales (5)
|
||||||
|
|
||||||
|
#### hst - Hashtags
|
||||||
|
```sql
|
||||||
|
CREATE TABLE hst (
|
||||||
|
num SERIAL PRIMARY KEY,
|
||||||
|
alias VARCHAR(255),
|
||||||
|
ref VARCHAR(50),
|
||||||
|
rootref VARCHAR(100),
|
||||||
|
img_url TEXT,
|
||||||
|
txt TEXT,
|
||||||
|
standard_md TEXT,
|
||||||
|
jsonb_standard JSONB,
|
||||||
|
version VARCHAR(50),
|
||||||
|
mrf VARCHAR(64) UNIQUE NOT NULL, -- SHA-256 hash
|
||||||
|
owner VARCHAR(100),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
roothash VARCHAR(64),
|
||||||
|
private_mrf VARCHAR(64),
|
||||||
|
url TEXT,
|
||||||
|
url_json TEXT,
|
||||||
|
date DATE,
|
||||||
|
name_es VARCHAR(255),
|
||||||
|
name_en VARCHAR(255),
|
||||||
|
name_ch VARCHAR(255),
|
||||||
|
img_thumb_url TEXT,
|
||||||
|
set_hst VARCHAR(64), -- FK a grupo/tipo
|
||||||
|
url_atc TEXT
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### flg - Flags
|
||||||
|
```sql
|
||||||
|
CREATE TABLE flg (
|
||||||
|
-- Misma estructura que hst
|
||||||
|
num SERIAL PRIMARY KEY,
|
||||||
|
mrf VARCHAR(64) UNIQUE NOT NULL,
|
||||||
|
ref VARCHAR(50),
|
||||||
|
name_es VARCHAR(255),
|
||||||
|
name_en VARCHAR(255),
|
||||||
|
img_url TEXT,
|
||||||
|
img_thumb_url TEXT,
|
||||||
|
txt TEXT,
|
||||||
|
set_hst VARCHAR(64),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### itm, loc, ply - Items, Locations, Players
|
||||||
|
```sql
|
||||||
|
-- Misma estructura base que flg
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Tablas de Relaciones (6)
|
||||||
|
|
||||||
|
#### tree_hst - Jerarquia
|
||||||
|
```sql
|
||||||
|
CREATE TABLE tree_hst (
|
||||||
|
num SERIAL PRIMARY KEY,
|
||||||
|
mrf_parent VARCHAR(64) NOT NULL,
|
||||||
|
mrf_child VARCHAR(64) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
UNIQUE(mrf_parent, mrf_child)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_tree_hst_parent ON tree_hst(mrf_parent);
|
||||||
|
CREATE INDEX idx_tree_hst_child ON tree_hst(mrf_child);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### graph_hst - Grafo de Relaciones
|
||||||
|
```sql
|
||||||
|
CREATE TABLE graph_hst (
|
||||||
|
num SERIAL PRIMARY KEY,
|
||||||
|
mrf_a VARCHAR(64) NOT NULL,
|
||||||
|
mrf_b VARCHAR(64) NOT NULL,
|
||||||
|
weight DECIMAL(3,2) DEFAULT 0.5,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
edge_type VARCHAR(50) DEFAULT 'relation',
|
||||||
|
UNIQUE(mrf_a, mrf_b)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_graph_hst_a ON graph_hst(mrf_a);
|
||||||
|
CREATE INDEX idx_graph_hst_b ON graph_hst(mrf_b);
|
||||||
|
CREATE INDEX idx_graph_hst_type ON graph_hst(edge_type);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### library_hst - Bibliotecas
|
||||||
|
```sql
|
||||||
|
CREATE TABLE library_hst (
|
||||||
|
num SERIAL PRIMARY KEY,
|
||||||
|
mrf_library VARCHAR(64) NOT NULL,
|
||||||
|
mrf_tag VARCHAR(64) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
UNIQUE(mrf_library, mrf_tag)
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_library_hst_lib ON library_hst(mrf_library);
|
||||||
|
CREATE INDEX idx_library_hst_tag ON library_hst(mrf_tag);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Vistas SQL (5)
|
||||||
|
|
||||||
|
#### api_tags - Tags unificados
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE VIEW api_tags AS
|
||||||
|
SELECT mrf, ref, name_es, name_en, name_ch, img_url, img_thumb_url,
|
||||||
|
txt, set_hst, 'hst' as type, created_at
|
||||||
|
FROM hst
|
||||||
|
UNION ALL
|
||||||
|
SELECT mrf, ref, name_es, name_en, name_ch, img_url, img_thumb_url,
|
||||||
|
txt, set_hst, 'flg' as type, created_at
|
||||||
|
FROM flg
|
||||||
|
UNION ALL
|
||||||
|
SELECT mrf, ref, name_es, name_en, name_ch, img_url, img_thumb_url,
|
||||||
|
txt, set_hst, 'itm' as type, created_at
|
||||||
|
FROM itm
|
||||||
|
UNION ALL
|
||||||
|
SELECT mrf, ref, name_es, name_en, name_ch, img_url, img_thumb_url,
|
||||||
|
txt, set_hst, 'loc' as type, created_at
|
||||||
|
FROM loc
|
||||||
|
UNION ALL
|
||||||
|
SELECT mrf, ref, name_es, name_en, name_ch, img_url, img_thumb_url,
|
||||||
|
txt, set_hst, 'ply' as type, created_at
|
||||||
|
FROM ply;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_groups - Grupos/Tipos
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE VIEW api_groups AS
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url,
|
||||||
|
(SELECT count(*) FROM hst WHERE set_hst = h.mrf) as count
|
||||||
|
FROM hst h
|
||||||
|
WHERE h.mrf IN (SELECT DISTINCT set_hst FROM hst WHERE set_hst IS NOT NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_library_list - Lista de bibliotecas
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE VIEW api_library_list AS
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url,
|
||||||
|
(SELECT count(*) FROM library_hst WHERE mrf_library = h.mrf) as member_count
|
||||||
|
FROM hst h
|
||||||
|
WHERE h.mrf IN (SELECT DISTINCT mrf_library FROM library_hst);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_graph_stats - Estadisticas grafo
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE VIEW api_graph_stats AS
|
||||||
|
SELECT
|
||||||
|
(SELECT count(*) FROM hst) as total_tags,
|
||||||
|
(SELECT count(*) FROM graph_hst) as total_edges,
|
||||||
|
(SELECT count(DISTINCT edge_type) FROM graph_hst) as edge_types;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_tree_roots - Raices del arbol
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE VIEW api_tree_roots AS
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.img_thumb_url
|
||||||
|
FROM hst h
|
||||||
|
WHERE h.mrf IN (SELECT DISTINCT mrf_parent FROM tree_hst)
|
||||||
|
AND h.mrf NOT IN (SELECT mrf_child FROM tree_hst);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 Funciones RPC (5)
|
||||||
|
|
||||||
|
#### api_children - Hijos directos
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION api_children(parent_mrf VARCHAR(64))
|
||||||
|
RETURNS TABLE(mrf VARCHAR, ref VARCHAR, name_es VARCHAR, name_en VARCHAR, img_thumb_url TEXT)
|
||||||
|
LANGUAGE SQL STABLE
|
||||||
|
AS $$
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url
|
||||||
|
FROM hst h
|
||||||
|
JOIN tree_hst t ON h.mrf = t.mrf_child
|
||||||
|
WHERE t.mrf_parent = parent_mrf;
|
||||||
|
$$;
|
||||||
|
GRANT EXECUTE ON FUNCTION api_children(VARCHAR) TO anon;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_descendants - Descendientes recursivos
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION api_descendants(parent_mrf VARCHAR(64))
|
||||||
|
RETURNS TABLE(mrf VARCHAR, ref VARCHAR, name_es VARCHAR, name_en VARCHAR, img_thumb_url TEXT, depth INTEGER)
|
||||||
|
LANGUAGE SQL STABLE
|
||||||
|
AS $$
|
||||||
|
WITH RECURSIVE tree AS (
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url, 1 as depth
|
||||||
|
FROM hst h
|
||||||
|
JOIN tree_hst t ON h.mrf = t.mrf_child
|
||||||
|
WHERE t.mrf_parent = parent_mrf
|
||||||
|
UNION ALL
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url, tr.depth + 1
|
||||||
|
FROM hst h
|
||||||
|
JOIN tree_hst t ON h.mrf = t.mrf_child
|
||||||
|
JOIN tree tr ON t.mrf_parent = tr.mrf
|
||||||
|
WHERE tr.depth < 10
|
||||||
|
)
|
||||||
|
SELECT * FROM tree;
|
||||||
|
$$;
|
||||||
|
GRANT EXECUTE ON FUNCTION api_descendants(VARCHAR) TO anon;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_path - Ruta al root
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION api_path(tag_mrf VARCHAR(64))
|
||||||
|
RETURNS TABLE(mrf VARCHAR, ref VARCHAR, name_es VARCHAR, img_thumb_url TEXT, depth INTEGER)
|
||||||
|
LANGUAGE SQL STABLE
|
||||||
|
AS $$
|
||||||
|
WITH RECURSIVE path AS (
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.img_thumb_url, 0 as depth
|
||||||
|
FROM hst h WHERE h.mrf = tag_mrf
|
||||||
|
UNION ALL
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.img_thumb_url, p.depth + 1
|
||||||
|
FROM hst h
|
||||||
|
JOIN tree_hst t ON h.mrf = t.mrf_parent
|
||||||
|
JOIN path p ON t.mrf_child = p.mrf
|
||||||
|
WHERE p.depth < 20
|
||||||
|
)
|
||||||
|
SELECT * FROM path ORDER BY depth DESC;
|
||||||
|
$$;
|
||||||
|
GRANT EXECUTE ON FUNCTION api_path(VARCHAR) TO anon;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_related - Tags relacionados
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION api_related(tag_mrf VARCHAR(64))
|
||||||
|
RETURNS TABLE(mrf VARCHAR, ref VARCHAR, name_es VARCHAR, name_en VARCHAR, img_thumb_url TEXT, edge_type VARCHAR, weight DECIMAL)
|
||||||
|
LANGUAGE SQL STABLE
|
||||||
|
AS $$
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url, g.edge_type, g.weight
|
||||||
|
FROM hst h
|
||||||
|
JOIN graph_hst g ON (h.mrf = g.mrf_b AND g.mrf_a = tag_mrf)
|
||||||
|
OR (h.mrf = g.mrf_a AND g.mrf_b = tag_mrf)
|
||||||
|
WHERE h.mrf != tag_mrf;
|
||||||
|
$$;
|
||||||
|
GRANT EXECUTE ON FUNCTION api_related(VARCHAR) TO anon;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### api_library_tags - Tags de biblioteca
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION api_library_tags(library_mrf VARCHAR(64))
|
||||||
|
RETURNS TABLE(mrf VARCHAR, ref VARCHAR, name_es VARCHAR, name_en VARCHAR, img_thumb_url TEXT)
|
||||||
|
LANGUAGE SQL STABLE
|
||||||
|
AS $$
|
||||||
|
SELECT h.mrf, h.ref, h.name_es, h.name_en, h.img_thumb_url
|
||||||
|
FROM hst h
|
||||||
|
JOIN library_hst l ON h.mrf = l.mrf_tag
|
||||||
|
WHERE l.mrf_library = library_mrf;
|
||||||
|
$$;
|
||||||
|
GRANT EXECUTE ON FUNCTION api_library_tags(VARCHAR) TO anon;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 Permisos
|
||||||
|
```sql
|
||||||
|
-- Usuario anon para PostgREST
|
||||||
|
CREATE ROLE anon NOLOGIN;
|
||||||
|
GRANT USAGE ON SCHEMA public TO anon;
|
||||||
|
GRANT SELECT ON ALL TABLES IN SCHEMA public TO anon;
|
||||||
|
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO anon;
|
||||||
|
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO anon;
|
||||||
|
|
||||||
|
-- Usuario autenticado
|
||||||
|
CREATE ROLE authenticated NOLOGIN;
|
||||||
|
GRANT anon TO authenticated;
|
||||||
|
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO authenticated;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. API REST (PostgREST)
|
||||||
|
|
||||||
|
### 3.1 Endpoints Principales
|
||||||
|
|
||||||
|
| Metodo | Endpoint | Descripcion |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| GET | /api/hst | Lista todos los hashtags |
|
||||||
|
| GET | /api/flg | Lista todos los flags |
|
||||||
|
| GET | /api/itm | Lista todos los items |
|
||||||
|
| GET | /api/loc | Lista todas las locations |
|
||||||
|
| GET | /api/ply | Lista todos los players |
|
||||||
|
| GET | /api/api_tags | Vista unificada |
|
||||||
|
| GET | /api/api_groups | Lista grupos |
|
||||||
|
| GET | /api/api_library_list | Lista bibliotecas |
|
||||||
|
| GET | /api/tree_hst | Relaciones jerarquicas |
|
||||||
|
| GET | /api/graph_hst | Relaciones grafo |
|
||||||
|
|
||||||
|
### 3.2 Endpoints RPC
|
||||||
|
|
||||||
|
| Metodo | Endpoint | Body | Descripcion |
|
||||||
|
|--------|----------|------|-------------|
|
||||||
|
| POST | /api/rpc/api_children | {"parent_mrf":"xxx"} | Hijos directos |
|
||||||
|
| POST | /api/rpc/api_descendants | {"parent_mrf":"xxx"} | Descendientes |
|
||||||
|
| POST | /api/rpc/api_path | {"tag_mrf":"xxx"} | Ruta a root |
|
||||||
|
| POST | /api/rpc/api_related | {"tag_mrf":"xxx"} | Relacionados |
|
||||||
|
| POST | /api/rpc/api_library_tags | {"library_mrf":"xxx"} | Tags de lib |
|
||||||
|
|
||||||
|
### 3.3 Filtros PostgREST
|
||||||
|
```
|
||||||
|
# Paginacion
|
||||||
|
?limit=50&offset=0
|
||||||
|
|
||||||
|
# Ordenacion
|
||||||
|
?order=ref.asc
|
||||||
|
?order=created_at.desc
|
||||||
|
|
||||||
|
# Filtros
|
||||||
|
?ref=eq.xxx
|
||||||
|
?mrf=eq.xxx
|
||||||
|
?set_hst=eq.xxx
|
||||||
|
?edge_type=eq.relation
|
||||||
|
|
||||||
|
# Busqueda
|
||||||
|
?name_es=ilike.*busqueda*
|
||||||
|
|
||||||
|
# Seleccion de campos
|
||||||
|
?select=mrf,ref,name_es
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. CONFIGURACION NGINX
|
||||||
|
|
||||||
|
### 4.1 /opt/hst/nginx/default.conf
|
||||||
|
```nginx
|
||||||
|
# Redirect HTTP to HTTPS
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name tzrtech.org www.tzrtech.org *.tzrtech.org;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main site - tzrtech.org
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name tzrtech.org www.tzrtech.org;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/tzrtech.org-0001/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/tzrtech.org-0001/privkey.pem;
|
||||||
|
|
||||||
|
root /opt/hst/web;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# Serve images from /hst/, /flg/, /itm/, /loc/, /ply/
|
||||||
|
location ~ ^/(hst|flg|itm|loc|ply)/(thumb/)?(.+\.png)$ {
|
||||||
|
alias /opt/hst/assets/$1/$2$3;
|
||||||
|
add_header Access-Control-Allow-Origin * always;
|
||||||
|
add_header Cache-Control "public, max-age=86400";
|
||||||
|
try_files "" =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assets folder (fallback)
|
||||||
|
location /assets/ {
|
||||||
|
alias /opt/hst/assets/;
|
||||||
|
add_header Access-Control-Allow-Origin * always;
|
||||||
|
}
|
||||||
|
|
||||||
|
# PostgREST API
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://postgrest:3000/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Access-Control-Allow-Origin * always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, PATCH, DELETE, OPTIONS" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Authorization, Content-Type, Prefer" always;
|
||||||
|
add_header Access-Control-Expose-Headers "Content-Range, Range" always;
|
||||||
|
if ($request_method = OPTIONS) { return 204; }
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Directus HST Admin
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name hst.tzrtech.org directus.tzrtech.org;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/tzrtech.org-0001/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/tzrtech.org-0001/privkey.pem;
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://directus_hst:8055;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Graph subdomain (Flask legacy)
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name graph.tzrtech.org;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/tzrtech.org-0001/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/tzrtech.org-0001/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://hst-api:5000/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. INTERFAZ WEB
|
||||||
|
|
||||||
|
### 5.1 Constantes JavaScript
|
||||||
|
|
||||||
|
#### CATS - Categorias/Colores
|
||||||
|
```javascript
|
||||||
|
const CATS = {
|
||||||
|
hst: {name: "Hashtags", color: "#7c8aff"},
|
||||||
|
spe: {name: "Specs", color: "#FF9800"},
|
||||||
|
vue: {name: "Values", color: "#00BCD4"},
|
||||||
|
vsn: {name: "Visions", color: "#E91E63"},
|
||||||
|
msn: {name: "Missions", color: "#9C27B0"},
|
||||||
|
flg: {name: "Flags", color: "#4CAF50"}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### EDGE_COLORS - Tipos de relacion
|
||||||
|
```javascript
|
||||||
|
const EDGE_COLORS = {
|
||||||
|
relation: "#8BC34A",
|
||||||
|
specialization: "#9C27B0",
|
||||||
|
mirror: "#607D8B",
|
||||||
|
dependency: "#2196F3",
|
||||||
|
sequence: "#4CAF50",
|
||||||
|
composition: "#FF9800",
|
||||||
|
hierarchy: "#E91E63",
|
||||||
|
library: "#00BCD4",
|
||||||
|
contextual: "#FFC107",
|
||||||
|
association: "#795548"
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Caracteristicas de la Interfaz
|
||||||
|
|
||||||
|
1. **Vista Biblioteca (Grid)**
|
||||||
|
- Grid responsive con tarjetas
|
||||||
|
- Imagenes con fallback a placeholder
|
||||||
|
- Seleccion multiple con checkboxes
|
||||||
|
- Click para ver detalle
|
||||||
|
|
||||||
|
2. **Vista Arbol (Tree)**
|
||||||
|
- Agrupacion por set_hst
|
||||||
|
- Expandir/colapsar grupos
|
||||||
|
- Seleccion multiple
|
||||||
|
- Navegacion a hijos
|
||||||
|
|
||||||
|
3. **Vista Grafo (Graph)**
|
||||||
|
- D3.js force simulation
|
||||||
|
- Nodos coloreados por categoria
|
||||||
|
- Edges coloreados por tipo
|
||||||
|
- Sidebar con:
|
||||||
|
- Estadisticas (nodos, edges)
|
||||||
|
- Filtros por categoria
|
||||||
|
- Filtros por tipo de edge
|
||||||
|
- Slider peso minimo
|
||||||
|
- Controles (zoom, fit)
|
||||||
|
- Leyenda de colores
|
||||||
|
|
||||||
|
4. **Panel Lateral (Detail)**
|
||||||
|
- Imagen grande
|
||||||
|
- Ref y MRF (copiable)
|
||||||
|
- Nombre localizado
|
||||||
|
- Descripcion
|
||||||
|
- Hijos (api_children)
|
||||||
|
- Relacionados (api_related)
|
||||||
|
|
||||||
|
5. **Controles Globales**
|
||||||
|
- Selector de idioma (ES/EN/CH)
|
||||||
|
- Selector de base (HST/FLG/ITM/LOC/PLY)
|
||||||
|
- Buscador
|
||||||
|
- Filtros por grupo (set_hst)
|
||||||
|
- Filtros por biblioteca
|
||||||
|
- SEL/GET para seleccion multiple
|
||||||
|
|
||||||
|
### 5.3 Estado de la Aplicacion
|
||||||
|
```javascript
|
||||||
|
const state = {
|
||||||
|
base: "hst", // Base activa
|
||||||
|
lang: "es", // Idioma
|
||||||
|
view: "grid", // Vista actual
|
||||||
|
search: "", // Busqueda
|
||||||
|
group: "all", // Filtro grupo
|
||||||
|
library: "all", // Filtro biblioteca
|
||||||
|
libraryMembers: Set(), // MRFs de biblioteca
|
||||||
|
selectionMode: false, // Modo seleccion
|
||||||
|
selected: Set(), // Tags seleccionados
|
||||||
|
selectedTag: null, // Tag en panel detalle
|
||||||
|
tags: [], // Tags cargados
|
||||||
|
groups: [], // Grupos cargados
|
||||||
|
libraries: [], // Bibliotecas cargadas
|
||||||
|
graphEdges: [], // Edges del grafo
|
||||||
|
treeEdges: [], // Edges del arbol
|
||||||
|
graphFilters: { // Filtros grafo
|
||||||
|
cats: Set(["hst"]),
|
||||||
|
edges: Set(Object.keys(EDGE_COLORS))
|
||||||
|
},
|
||||||
|
graphSettings: { // Config grafo
|
||||||
|
nodeSize: 18,
|
||||||
|
textSize: 9,
|
||||||
|
linkDist: 70,
|
||||||
|
showImg: true,
|
||||||
|
showLbl: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. DOCKER COMPOSE
|
||||||
|
|
||||||
|
### 6.1 docker-compose.yml
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: postgres_hst
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: hst
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB: hst
|
||||||
|
volumes:
|
||||||
|
- ./postgres_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- hst-net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U hst -d hst"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
postgrest:
|
||||||
|
image: postgrest/postgrest:latest
|
||||||
|
container_name: postgrest
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
PGRST_DB_URI: postgres://hst:${POSTGRES_PASSWORD}@postgres:5432/hst
|
||||||
|
PGRST_DB_SCHEMA: public
|
||||||
|
PGRST_DB_ANON_ROLE: anon
|
||||||
|
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- hst-net
|
||||||
|
|
||||||
|
directus:
|
||||||
|
image: directus/directus:latest
|
||||||
|
container_name: directus_hst
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
KEY: ${DIRECTUS_KEY}
|
||||||
|
SECRET: ${DIRECTUS_SECRET}
|
||||||
|
DB_CLIENT: pg
|
||||||
|
DB_HOST: postgres
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_DATABASE: hst
|
||||||
|
DB_USER: hst
|
||||||
|
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
ADMIN_EMAIL: ${ADMIN_EMAIL}
|
||||||
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- ./directus/uploads:/directus/uploads
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- hst-net
|
||||||
|
|
||||||
|
hst-api:
|
||||||
|
build: ./api
|
||||||
|
container_name: hst-api
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgres://hst:${POSTGRES_PASSWORD}@postgres:5432/hst
|
||||||
|
volumes:
|
||||||
|
- ./assets:/app/assets:ro
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- hst-net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
filebrowser:
|
||||||
|
image: filebrowser/filebrowser:latest
|
||||||
|
container_name: filebrowser
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./assets:/srv
|
||||||
|
- ./filebrowser.db:/database.db
|
||||||
|
networks:
|
||||||
|
- hst-net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
networks:
|
||||||
|
hst-net:
|
||||||
|
driver: bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. RECONSTRUCCION PASO A PASO
|
||||||
|
|
||||||
|
### 7.1 Preparar Servidor
|
||||||
|
```bash
|
||||||
|
# Conectar
|
||||||
|
ssh root@72.62.2.84
|
||||||
|
|
||||||
|
# Crear estructura
|
||||||
|
mkdir -p /opt/hst/{web,assets,nginx,api,directus}
|
||||||
|
mkdir -p /opt/hst/assets/{hst,flg,itm,loc,ply}
|
||||||
|
mkdir -p /opt/hst/assets/hst/thumb
|
||||||
|
mkdir -p /opt/hst/assets/flg/thumb
|
||||||
|
|
||||||
|
# Instalar Docker (si no esta)
|
||||||
|
curl -fsSL https://get.docker.com | sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 Configurar PostgreSQL
|
||||||
|
```bash
|
||||||
|
# Iniciar contenedor
|
||||||
|
docker run -d \
|
||||||
|
--name postgres_hst \
|
||||||
|
--network hst-net \
|
||||||
|
-e POSTGRES_USER=hst \
|
||||||
|
-e POSTGRES_PASSWORD=xxx \
|
||||||
|
-e POSTGRES_DB=hst \
|
||||||
|
-v /opt/hst/postgres_data:/var/lib/postgresql/data \
|
||||||
|
--restart always \
|
||||||
|
postgres:15-alpine
|
||||||
|
|
||||||
|
# Crear esquema
|
||||||
|
docker exec -i postgres_hst psql -U hst -d hst << 'EOF'
|
||||||
|
-- Insertar SQL de seccion 2
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 Configurar PostgREST
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name postgrest \
|
||||||
|
--network hst-net \
|
||||||
|
-e PGRST_DB_URI="postgres://hst:xxx@postgres_hst:5432/hst" \
|
||||||
|
-e PGRST_DB_SCHEMA=public \
|
||||||
|
-e PGRST_DB_ANON_ROLE=anon \
|
||||||
|
--restart always \
|
||||||
|
postgrest/postgrest:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.4 Configurar Nginx
|
||||||
|
```bash
|
||||||
|
# Copiar configuracion
|
||||||
|
cp default.conf /opt/hst/nginx/
|
||||||
|
|
||||||
|
# Obtener certificados SSL
|
||||||
|
certbot certonly --standalone -d tzrtech.org -d www.tzrtech.org -d hst.tzrtech.org
|
||||||
|
|
||||||
|
# Reiniciar nginx
|
||||||
|
nginx -t && systemctl reload nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.5 Desplegar Interfaz Web
|
||||||
|
```bash
|
||||||
|
# Copiar index.html a /opt/hst/web/
|
||||||
|
# El archivo completo esta en la seccion 5
|
||||||
|
|
||||||
|
# Verificar
|
||||||
|
curl -s http://localhost/api/hst?limit=1 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.6 Importar Datos
|
||||||
|
```bash
|
||||||
|
# Desde backup PostgreSQL
|
||||||
|
docker exec -i postgres_hst psql -U hst -d hst < backup.sql
|
||||||
|
|
||||||
|
# O desde CSV
|
||||||
|
docker exec -i postgres_hst psql -U hst -d hst -c "\copy hst FROM '/tmp/hst.csv' CSV HEADER"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.7 Verificacion Final
|
||||||
|
```bash
|
||||||
|
# Servicios
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# API
|
||||||
|
curl -s http://localhost/api/hst?limit=1
|
||||||
|
curl -s http://localhost/api/api_groups
|
||||||
|
curl -s -X POST http://localhost/api/rpc/api_children \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"parent_mrf":"xxx"}'
|
||||||
|
|
||||||
|
# Web
|
||||||
|
curl -s http://localhost/ | head -20
|
||||||
|
|
||||||
|
# SSL
|
||||||
|
curl -sI https://tzrtech.org/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. DATOS ACTUALES
|
||||||
|
|
||||||
|
### 8.1 Conteos
|
||||||
|
| Tabla | Registros |
|
||||||
|
|-------|-----------|
|
||||||
|
| hst | 963 |
|
||||||
|
| flg | 65 |
|
||||||
|
| itm | 0 |
|
||||||
|
| loc | 0 |
|
||||||
|
| ply | 0 |
|
||||||
|
| tree_hst | ~900 |
|
||||||
|
| graph_hst | ~800 |
|
||||||
|
| library_hst | variable |
|
||||||
|
|
||||||
|
### 8.2 Grupos Principales (set_hst)
|
||||||
|
- abeb605c... (hst - etiqueta): ~721 tags
|
||||||
|
- d3d633ff... (spe - especificacion): ~178 tags
|
||||||
|
- 33fa2912... (msn - mision): ~3 tags
|
||||||
|
- 320ad174... (vue - valor): ~21 tags
|
||||||
|
|
||||||
|
### 8.3 Tipos de Edge (graph_hst.edge_type)
|
||||||
|
- relation
|
||||||
|
- specialization
|
||||||
|
- mirror
|
||||||
|
- dependency
|
||||||
|
- sequence
|
||||||
|
- composition
|
||||||
|
- hierarchy
|
||||||
|
- library
|
||||||
|
- contextual
|
||||||
|
- association
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. URLs DE ACCESO
|
||||||
|
|
||||||
|
| Servicio | URL |
|
||||||
|
|----------|-----|
|
||||||
|
| Interfaz Web | https://tzrtech.org/ |
|
||||||
|
| API REST | https://tzrtech.org/api/ |
|
||||||
|
| Directus Admin | https://hst.tzrtech.org/ |
|
||||||
|
| Graph Legacy | https://graph.tzrtech.org/ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. TROUBLESHOOTING
|
||||||
|
|
||||||
|
### PostgREST no responde
|
||||||
|
```bash
|
||||||
|
docker logs postgrest --tail 50
|
||||||
|
docker restart postgrest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Imagenes no cargan
|
||||||
|
```bash
|
||||||
|
# Verificar ruta
|
||||||
|
ls -la /opt/hst/assets/hst/
|
||||||
|
# Verificar nginx
|
||||||
|
nginx -t
|
||||||
|
systemctl reload nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error 502 Bad Gateway
|
||||||
|
```bash
|
||||||
|
# Verificar red docker
|
||||||
|
docker network inspect hst-net
|
||||||
|
# Verificar contenedor destino
|
||||||
|
docker ps | grep postgrest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Recargar schema PostgREST
|
||||||
|
```bash
|
||||||
|
docker exec postgrest pkill -SIGUSR1 postgrest
|
||||||
|
# o
|
||||||
|
docker restart postgrest
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ANEXO: ARCHIVOS COMPLETOS
|
||||||
|
|
||||||
|
### A. index.html (Web Interface)
|
||||||
|
El archivo completo `/opt/hst/web/index.html` contiene ~47KB de HTML/CSS/JavaScript.
|
||||||
|
Caracteristicas principales implementadas:
|
||||||
|
- SPA con 3 vistas (Grid, Tree, Graph)
|
||||||
|
- D3.js v7 para visualizacion de grafo
|
||||||
|
- Sistema de seleccion SEL/GET
|
||||||
|
- Panel de detalle con hijos y relacionados
|
||||||
|
- Filtros por grupo, biblioteca, categoria
|
||||||
|
- Multiidioma (ES/EN/CH)
|
||||||
|
- Theme oscuro profesional
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Documento generado: 2026-01-07*
|
||||||
|
*Sistema: HST v2.0*
|
||||||
|
*Servidor: 72.62.2.84*
|
||||||
Reference in New Issue
Block a user