01 Topología física + WAN
Internet → ISP CNT/Movistar (público
181.39.243.227) → modem 192.168.100.1 → OPNsense (10.10.20.2) → Proxmox host (i5-13400, 96GB, RTX 5070 Ti). Nota: la IP pública está bloqueada por WhatsApp para Baileys (anti-bot datacenter).%% Topología física + WAN — PELTIC
%% Generado: 2026-05-19 | Fuente: CLAUDE.md raíz + Memory/01-INFRA.md
%% Render: mmdc -i 01_physical.mmd -o 01_physical.png -b transparent -w 2400
flowchart TB
subgraph WAN["🌐 Internet"]
CF[Cloudflare CDN<br/>peltic.com / erp / hd / cloud /<br/>rd / chat / mcp / rag / agents]
WA[WhatsApp servers<br/>g.whatsapp.net]
UPSTREAM[ISP CNT / Movistar<br/>público 181.39.243.227]
end
MODEM[Modem ISP<br/>192.168.100.1<br/>NAT primario]
OPN[OPNsense<br/>10.10.20.2 / WAN 192.168.100.3<br/>Double NAT · Zenarmor · DoT]
SW[UniFi Switch<br/>VLAN 20 = 10.10.20.0/24]
subgraph PVE["Proxmox Host (PVE 9.1.9) — 10.10.20.1:8006"]
direction TB
CPU[i5-13400 · 10c/16t · 96GB DDR5]
GPU[RTX 5070 Ti 16GB<br/>passthrough → VM 101<br/>mapping label legacy rtx3060]
ZFS[rpool ZFS · 928G NVMe mirror · 65% usado · ARC 8GB]
HDD[Toshiba 9.1TB ext4<br/>vps-storage → /mnt/vps-storage]
SWAP[16GB swap zd0]
end
AP[UniFi WiFi APs]
ESP[ESP32 callejón<br/>10.10.20.190<br/>IP quemada · static reservation]
CF -- 80/443 --> MODEM
WA -. handshake bloqueado<br/>desde 181.39.243.227 .-> UPSTREAM
UPSTREAM --> MODEM
MODEM -- 192.168.100.0/24 --> OPN
OPN -- 80/443 → 10.10.20.157<br/>RustDesk → .163/.164 --> SW
SW -- 10.10.20.0/24 --> PVE
SW --> AP
AP --> ESP
style WAN fill:#1d2733,stroke:#5b9,color:#fff
style PVE fill:#222a,stroke:#5b9,color:#fff
style GPU fill:#3a1a1a,stroke:#f55,color:#fff
style ESP fill:#3a3a1a,stroke:#fb5,color:#fff
02 VMs Proxmox
5 VMs activas. SRVDOCKER (100) host principal · IASRV (101) con GPU para Ollama + OSINT · PBS (103) backups · ZABBIXSRV (104) monitoring · DEBIANSRV (102) videojuego. VM 105 GVOT destruida 2026-05-03.
%% VMs Proxmox — PELTIC
%% Generado: 2026-05-19 | Fuente: CLAUDE.md raíz
flowchart LR
subgraph PVE["Proxmox 10.10.20.1"]
direction TB
subgraph VM100["VM 100 · SRVDOCKER (10.10.20.3) · Ubuntu 24.04 · 32GB"]
v100d1[scsi0 = local-zfs 250GB NVMe<br/>87GB usado]
v100d2[scsi2 = vps-storage 4TB qcow2 thin<br/>Seafile data en HDD]
v100r[Docker host principal<br/>~40 containers]
end
subgraph VM101["VM 101 · IASRV (10.10.20.45) · Ubuntu 24.04 · 24GB (balloon 20)"]
v101g[GPU passthrough RTX 5070 Ti]
v101o[Ollama :11434<br/>9 modelos productivos<br/>peltic/primary,heavy,coder,weak<br/>+bge-m3, qwen3-coder, nomic]
v101oc[OpenClaw AI npm<br/>WS :18789 · 3 agents]
v101osint[OSINT stack 11 containers<br/>elastic·neo4j·redis·minio·worker·UI]
end
VM102["VM 102 · DEBIANSRV (10.10.20.35) · Debian 12 · 4GB<br/>OpenClaw videojuego (red recuperada 2026-05-03)"]
VM103["VM 103 · PRMXBKP (10.10.20.36) · Debian 13 · 8GB<br/>Proxmox Backup Server 4.1.0<br/>datastore /bkp/ · 251GB/582GB"]
VM104["VM 104 · ZABBIXSRV (10.10.20.6) · Debian 13 · 4GB<br/>Zabbix 7.0.25"]
VM105["~~VM 105 · GVOT~~<br/>DESTROYED 2026-05-03"]:::dead
end
classDef dead fill:#311,stroke:#866,color:#a99,stroke-dasharray:5
style PVE fill:#1d2733,stroke:#5b9,color:#fff
style VM100 fill:#1a3a1a,stroke:#7c7,color:#fff
style VM101 fill:#1a2a3a,stroke:#79c,color:#fff
03 Containers Docker SRVDOCKER
80+ containers en macvlan infra-lan (10.10.20.144–.191) + redes bridge dedicadas. NPM (.157) es el único SSL público. RustDesk (.163/.164) sellado.
%% Containers Docker SRVDOCKER (10.10.20.3) — PELTIC
%% Generado: 2026-05-19 | Fuente: CLAUDE.md raíz + memoria
%% Render: mmdc -i 03_containers.mmd -o 03_containers.png -b transparent -w 3200
flowchart TB
subgraph EXT["🌐 Externos"]
USER[Cliente web]
CF[Cloudflare]
end
OPN[OPNsense<br/>10.10.20.2]
subgraph NPM_NET["NPM = único SSL público"]
NPM[npm 10.10.20.157<br/>Nginx Proxy Manager]
end
subgraph IDENTITY["🔐 Identity"]
CAS[casdoor 10.10.20.180<br/>auth.peltic.com<br/>SSO + 13 apps OIDC]
CASDB[casdoor-postgres]
end
subgraph WEB["🛒 Website + commerce"]
PWEB[peltic-web .158<br/>php8.4 apache]
PWEBDB[peltic-web-db postgres16<br/>bridge peltic-web-net<br/>cotizaciones, orders, subs]
end
subgraph ERP["📊 ERP PelticSaas"]
SAAS[peltic-saas 10.10.20.3:3000<br/>FastAPI+React]
ERPDB[peltic-db postgres<br/>multi-tenant]
end
subgraph CLOUD["☁️ Cloud / Office"]
SF[seafile :8181<br/>cloud.peltic.com]
COLLAB[collabora .173<br/>docs.peltic.com]
CAL[calcom .159 + db]
JIT[jitsi-web .160 + jicofo + jvb + prosody]
end
subgraph HD["🎫 Helpdesk Zammad"]
ZN[zammad-nginx .152]
ZPG[zammad-postgresql .145]
ZR[zammad-redis .147]
ZES[zammad-elasticsearch .148]
ZAPP[zammad-railsserver .149]
end
subgraph SMART["🏠 Smart-home / IoT"]
HA[homeassistant .154]
UNI[unifi .156 + mongo .155]
end
subgraph RD["🖥️ RustDesk LOCKED"]
HBBS[rustdesk-hbbs .163]
HBBR[rustdesk-hbbr .164]
end
subgraph AI["🤖 AI stack PelticAiPlatform"]
RAG[pai-rag-api :8090<br/>rag.peltic.com]
MCP[pai-mcp-server :8091<br/>mcp.peltic.com · 33 tools]
AGE[pai-agents-api :8092<br/>agents.peltic.com · 6 agents]
AIPG[pai-postgres]
QDR[pai-qdrant]
OWUI[open-webui .175<br/>chat.peltic.com]
MCPO[mcpo-peltic :8200<br/>MCP→OpenAPI bridge]
N8N[n8n .176<br/>n8n.peltic.com]
end
subgraph WA["💬 WhatsApp (BLOCKED upstream)"]
EVO[rmserver-whatsapp .186<br/>Evolution API · stopped]:::warn
end
subgraph CLAUDEWS["🛠 Dev infra"]
OH[claudews-openhands :3300<br/>openhands.peltic.com]
SG[claudews-sourcegraph :7080]
DB[claudews-dashboard :8099]
end
subgraph BIL["💵 Billing"]
FB[fossbilling .170 + db .171]
end
subgraph OBS["📈 Observability"]
PROM[prometheus]
GRAF[grafana monitoring.peltic.com]
LOKI[loki]
ALERT[alertmanager]
end
UM[umami .3001 + db<br/>analytics privacy-first]
USER --> CF --> OPN --> NPM
NPM --> PWEB & SAAS & SF & ZN & CAS & RAG & MCP & AGE & OWUI & N8N & HA & FB & GRAF & OH
PWEB -.> PWEBDB & SAAS
SAAS -.> ERPDB
SF -.> COLLAB
PWEB -- "/api/bot.php → Ollama" --> AI_OLLAMA[Ollama VM101 :11434]
RAG -.> AIPG & QDR & AI_OLLAMA
MCP -.> AIPG & ERPDB & PWEBDB & SF
AGE -.> MCP & RAG
OWUI -- MCP tools via mcpo --> MCPO --> MCP
N8N -. webhooks .-> EVO
CAS -- OIDC --> PWEB & SAAS & SF & ZN & RAG & OWUI & GRAF
HBBS -.- HBBR
classDef warn fill:#3a2a1a,stroke:#fb5,color:#fff,stroke-dasharray:5
style AI fill:#1a2a3a,stroke:#79c,color:#fff
style IDENTITY fill:#3a1a3a,stroke:#c7c,color:#fff
style RD fill:#3a1a1a,stroke:#f77,color:#fff
04 SSO unificado Casdoor
Casdoor (.180) reemplaza Authentik/Keycloak/Zitadel desde 2026-04-29. 75 usuarios, 13 apps OIDC: 7 activas ✅, 3 pendientes ⏸, 3 sin soporte nativo ❌.
%% SSO Unificado Casdoor — PELTIC
%% Generado: 2026-05-19 | Fuente: CLAUDE.md raíz "SSO Unificado"
%% Casdoor activo desde 2026-04-29 · org=peltic · 75 users · 13 apps
flowchart LR
USER([Usuario])
subgraph CAS["🔐 Casdoor 10.10.20.180:8000 · auth.peltic.com"]
IDP[Casdoor IdP<br/>cert-peltic RSA 4096<br/>75 users importados]
CASDB[casdoor-postgres]
end
subgraph OK["✅ OIDC ACTIVO"]
A1[peltic-web<br/>peltic.com/api/oidc_login.php]
A2[peltic-erp<br/>erp.peltic.com]
A3[osint-white<br/>osint.peltic.com]
A4[zammad<br/>hd.peltic.com/auth/casdoor]
A5[seafile<br/>cloud.peltic.com/oauth/login]
A6[open-webui<br/>chat.peltic.com]
A7[grafana<br/>monitoring.peltic.com]
end
subgraph PEND["⏸ Pendiente integración"]
B1[fossbilling<br/>extensión OIDC]
B2[calcom<br/>SAML jackson]
B3[homeassistant<br/>custom_component]
end
subgraph NO["❌ Sin soporte OIDC nativo"]
C1[n8n Community<br/>req Enterprise pago]
C2[anythingllm<br/>ELIMINADO 2026-05-16]:::dead
C3[portainer CE<br/>no soporta OAuth]
end
DEPR["~~Authentik · Keycloak · Zitadel~~<br/>DEPRECATED 2026-04-29<br/>Archive/SSO-deprecated-2026-04-29/"]:::dead
USER --> IDP
IDP -.->|/login/oauth/authorize<br/>/api/login/oauth/access_token<br/>/.well-known/openid-configuration| A1 & A2 & A3 & A4 & A5 & A6 & A7
IDP -. m2m API .-> ADMIN[/clientId=522515df5e3844b7ec6f<br/>solo desde 10.10.20.180\]
IDP -.- CASDB
classDef dead fill:#311,stroke:#866,color:#a99,stroke-dasharray:5
style CAS fill:#2a1a3a,stroke:#c7c,color:#fff
style OK fill:#1a3a1a,stroke:#7c7,color:#fff
style PEND fill:#3a2a1a,stroke:#cb5,color:#fff
style NO fill:#3a1a1a,stroke:#f77,color:#fff
05 AI stack completo
3 stacks separados: pai-* (RAG+MCP+Agents producción), claudews-* (dev OpenHands+Sourcegraph), rmserver-* (pgvector+Neo4j+Evolution). Ollama VM101 con 9 modelos productivos. Agente personal `asistente_gvaldez` recién deployado.
%% AI stack PELTIC (auditado 2026-05-16/19) — Generado 2026-05-19
%% Fuente: CLAUDE.md raíz "Stack AI real" + Memory/13-IA-PIPELINE.md + 16-IA-CANALES.md
flowchart TB
subgraph CHANNELS["📱 Canales de entrada"]
WEB[peltic.com chat Andrea<br/>bot.php · bot_stream.php]
UI_RAG[rag.peltic.com/ui]
UI_OWUI[chat.peltic.com Open WebUI]
UI_AGENTS[agents.peltic.com<br/>/agents/asistente_gvaldez/run]
WA[WhatsApp · asistente_gvaldez<br/>BLOCKED handshake]:::warn
AIDER[aider · Claude Code<br/>Mac local · MCP client]
end
subgraph OLLAMA["🦙 Ollama VM 101 (10.10.20.45:11434) · RTX 5070 Ti 16GB"]
OPRIM["peltic/primary:tuned 13.3GB<br/>Qwen3-Coder 30B-A3B Q3_K_S<br/>(chat principal, web Andrea + asistente)"]
OHEAVY["peltic/heavy:tuned 23.9GB<br/>Qwen3.6 35B abliterated<br/>(agentes pesados)"]
OCODER["peltic/coder:tuned 9GB · qwen2.5-coder 14b"]
OWEAK["peltic/weak:tuned 9GB · qwen2.5 14b<br/>(LLM classify/identify scraper)"]
OEMB["bge-m3 1.2GB · embeddings 1024d<br/>nomic-embed-text 0.3GB"]
OAB["huihui_ai/qwen2.5-abliterate:14b 9GB"]
OQC["qwen3-coder:30b 18.6GB"]
end
subgraph PAI["🤖 pai-* (PelticAiPlatform — /docker/peltic-ai-platform/)"]
PRAG[pai-rag-api :8090<br/>collections: empresa 945 docs / 162k chunks<br/>demo 2 docs]
PMCP[pai-mcp-server :8091<br/>34 tools auditadas en mcp_tool_calls<br/>core7 + web10 + erp12 + seafile4 + write1]
PAGE[pai-agents-api :8092<br/>6 agents: sales/support/website/infra/<br/>marketing + asistente_gvaldez]
PPG[pai-postgres]
PQDR[pai-qdrant]
end
subgraph DATA["💾 Data sources MCP"]
PWDB[(peltic-web-db<br/>cotizaciones · orders · subs)]
EDB[(peltic-db ERP<br/>invoices · products · clientes)]
SFAPI[Seafile API<br/>libraries · search · browse]
DOCKER[Docker socket RO<br/>docker_status_readonly]
end
subgraph CLAUDEWS["🛠 ClaudeWS dev (/srv/ClaudeWS/)"]
OH[openhands :3300]
SG[sourcegraph :7080]
DASH[dashboard :8099]
RAGCW[rag-api dev :7100]
end
subgraph RM["🗄 RMServer (/docker/rmserver/)"]
PGV[rmserver-db pgvector]
N4[rmserver-graph Neo4j 5.26]
RED[rmserver-redis]
EVO[rmserver-whatsapp Evolution<br/>stopped]:::warn
end
N8N[n8n .176<br/>webhooks · 8 workflows activos]
MCPO[mcpo-peltic :8200<br/>MCP→OpenAPI bridge]
WEB --> OPRIM
UI_RAG --> PRAG
UI_OWUI --> MCPO --> PMCP
UI_AGENTS --> PAGE
WA -.-> N8N -.-> PAGE
AIDER -.-> OLLAMA & PMCP
PRAG --> PPG & PQDR & OEMB & OPRIM
PMCP --> PPG & PWDB & EDB & SFAPI & DOCKER
PAGE --> PMCP & PRAG
OPRIM & OHEAVY -. razonamiento .- OLLAMA
N8N -.- EVO
classDef warn fill:#3a2a1a,stroke:#fb5,color:#fff,stroke-dasharray:5
style OLLAMA fill:#1a2a3a,stroke:#79c,color:#fff
style PAI fill:#1a3a2a,stroke:#7c9,color:#fff
style CHANNELS fill:#2a2a3a,stroke:#aaf,color:#fff
06 Dataflows críticos
A) Scraper diario (3 proveedores → Ollama classify → SQLite → architect → deploy). B) Andrea web (visitante → bot.php → Ollama direct → respuesta vendedora). C) Cotización (chat detecta intención → INSERT + DOMPDF + SMTP + creación via MCP tool nueva).
%% Dataflows críticos PELTIC — Generado 2026-05-19
%% Tres flujos: (A) Scraper diario, (B) Andrea web, (C) Cotización ERP + email
flowchart TB
subgraph A["A · Scraper diario peltic.com"]
CRON[Cron daily_scrape.sh<br/>SRVDOCKER /srv/peltic-architect/]
SCRAPI[scraper_api.py Flask :5050]
CART[peltic_scraper.py · Cartimex]
INT[Intcomex]
TEC[Tecnomega]
CACHE[storage/llm_identify_cache.json<br/>cache by SKU]
LLM[Ollama VM101<br/>peltic/weak:tuned · classify+identify]
SQLITE[(peltic.db SQLite<br/>/srv/peltic-architect/peltic.db<br/>2032 productos)]
ARCH[peltic_architect.py<br/>PAGES_REGISTRY + Jinja2]
SITIO[sitio/ HTML estático regenerable]
DEPLOY[deploy.sh<br/>rsync atómico<br/>→ /docker/peltic-web/html/public/]
WEBCT[peltic-web .158 · php8.4 apache]
CRON --> SCRAPI --> CART & INT & TEC
CART & INT & TEC --> LLM
LLM --> CACHE --> ARCH
CART & INT & TEC --> SQLITE
SQLITE --> ARCH --> SITIO --> DEPLOY --> WEBCT
end
subgraph B["B · Andrea web (ventas pública)"]
VISITOR([Visitante peltic.com])
BUBBLE[andrea-chat.js · burbuja]
BOT[bot.php<br/>/api/bot.php]
CATJSON[bot_catalog.json<br/>SQLite local · solo público]
OLDIR[Ollama VM101<br/>peltic/primary:tuned<br/>POST /api/chat]
VEND[Vendedora persona<br/>system prompt navy/yellow]
VISITOR --> BUBBLE --> BOT
BOT -.- CATJSON
BOT --> OLDIR --> VEND --> BOT --> BUBBLE
end
subgraph C["C · Cotización + email automático"]
CHAT[Andrea detecta intención]
CONFIRM["Cliente: si / dale / ok / confirmo"]
COT[bot_cotizacion.php]
QCREATE[INSERT cotizaciones<br/>+ cotizacion_items<br/>peltic-web-db]
PDF[DOMPDF · genera PDF]
SMTP[smtp_helper.php<br/>email a cliente]
ADMIN[admin.html · vendedor ve la cot]
MCPCREATE[MCP peltic_quote_create<br/>NUEVA 2026-05-19<br/>vía asistente_gvaldez agent]
CHAT --> CONFIRM --> COT --> QCREATE & PDF
PDF --> SMTP
QCREATE --> ADMIN
MCPCREATE -. mismo destino .-> QCREATE
end
style A fill:#1a2a3a,stroke:#79c,color:#fff
style B fill:#1a3a1a,stroke:#7c7,color:#fff
style C fill:#3a2a1a,stroke:#cb5,color:#fff
07 Mapa de credenciales (estructura, sin valores)
Qué credencial abre qué servicio. Los valores reales NUNCA están aquí — viven en
CREDENTIALS.md (gitignored) y se referencian por nombre. Sigue las reglas CLAUDE.md raíz § Secretos.%% Mapa de credenciales (sin valores) — Generado 2026-05-19
%% Fuente: CREDENTIALS.md (gitignored) + memoria
%% IMPORTANTE: este diagrama mapea QUIÉN abre QUÉ, nunca el valor real
flowchart LR
subgraph CRED["🔐 CREDENTIALS.md (gitignored)"]
direction TB
C1[gvaldez password]
C2[root@10.10.20.1]
C3[opnsense root]
C4[Casdoor admin]
C5[Casdoor m2m clientId+secret]
C6[Cloudflare API token]
C7[Seafile API token]
C8[RAG_API_TOKEN]
C9[MCP_API_TOKEN]
C10[AGENTS_API_TOKEN]
C11[QDRANT_API_KEY]
C12[OLLAMA_API_KEY vacío]
C13[EVOLUTION_API_KEY]
C14[N8N_ENCRYPTION_KEY]
C15[RustDesk Key qRf82MX6...]
C16[fail2ban unban]
C17[PayPhone secrets]
C18[PayPal client]
C19[SMTP titan]
C20[PAI db passwords]
end
C1 --> srvdocker[ssh srvdocker · gvaldez@10.10.20.3<br/>+ zabbix .6]
C2 --> pve[Proxmox host 10.10.20.1]
C3 --> opn[OPNsense 10.10.20.2]
C4 --> casui[Casdoor UI auth.peltic.com]
C5 --> casapi[Casdoor API m2m provisioning scripts]
C6 --> cf[Cloudflare DNS · DoH · cache bust]
C7 --> seafapi[Seafile API · sync RAG empresarial]
C8 --> ragapi[pai-rag-api /ask /search /ingest]
C9 --> mcpapi[pai-mcp-server JSONRPC · 34 tools]
C10 --> agapi[pai-agents-api /agents/.../run]
C11 --> qdr[Qdrant collections]
C13 --> evo[Evolution API · stopped<br/>blocked upstream WA]
C14 --> n8ndec[n8n decrypt credentials]
C15 --> rd[RustDesk clientes config<br/>🔒 LOCKED no tocar]
C16 --> jail[fail2ban-client unban]
C17 & C18 --> ord[peltic-web orders + paypal_orders]
C19 --> smtp[smtp_helper.php · cotizaciones email]
C20 --> paipg[pai-postgres + peltic-web-db + peltic-db ERP]
NOTOK[❌ NUNCA en git<br/>NUNCA en URL/log<br/>NUNCA en prompts a LLM externos]:::warn
style CRED fill:#2a1a3a,stroke:#c7c,color:#fff
classDef warn fill:#3a1a1a,stroke:#f77,color:#fff,font-weight:bold