\begin{figure}[ht] \centering \begin{tikzpicture}[ font=\small, box/.style={draw=ipsblue, rounded corners=2pt, align=center, inner sep=4pt, minimum height=0.85cm, minimum width=2.3cm}, ext/.style={draw=ipsgrey, dashed, rounded corners=2pt, align=center, inner sep=4pt, minimum height=0.85cm}, arr/.style={-{Latex}, thick, ipsblue}, dbarr/.style={-{Latex}, thick, ipsgrey} ] \node[box, fill=codebg] (desk) {Desktop\\Electron}; \node[box, fill=codebg, right=1.7cm of desk] (gw) {api\_gateway\\:8189}; \node[box, below=1.05cm of gw] (ext) {extraction\\(+ workers)}; \node[box, left=0.7cm of ext] (clean) {cleaning\\:8002}; \node[box, right=0.7cm of ext] (count) {count-api\\:8080}; \node[box, below=1.05cm of ext] (bot) {bot-descarga\\orquestador}; \node[box, below left=1.15cm and 1.4cm of bot] (pg) {PostgreSQL}; \node[box, below right=1.15cm and 1.4cm of bot] (redis) {Redis}; \node[ext, left=1.5cm of desk] (agent) {Agent Selenium\\(PC externo)}; \node[ext, below=2.5cm of agent] (minio) {MinIO/S3}; \node[ext, below=0.85cm of minio] (img) {Imaging}; % HTTP via gateway \draw[arr] (desk) -- (gw); \draw[arr] (gw) -- (ext); \draw[arr] (gw) -- (clean); \draw[arr] (gw) -- (count); \draw[arr] (gw) -- (bot); \draw[arr] (agent) |- (gw); % PostgreSQL: solo servicios de dominio (NO gateway, NO count-api) \draw[dbarr] (ext) -- (pg); \draw[dbarr] (clean) |- (pg); \draw[dbarr] (bot) -- (pg); % Redis: cola ARQ (extraction/workers) \draw[dbarr] (ext) -- (redis); % MinIO / Imaging \draw[arr] (agent) -- (minio); \draw[arr] (bot) -| (minio); \draw[arr] (agent) -- (img); \end{tikzpicture} \caption{Arquitectura bajo prueba. El \textbf{gateway no habla con Postgres}: solo hace proxy HTTP. Usan la BD compartida: \texttt{extraction} (+ workers), \texttt{cleaning} y \texttt{bot-descarga}. \texttt{count-api} hace OCR y \textbf{devuelve JSON} (no escribe en PG); el Desktop/extraction persiste esos resultados con \texttt{POST /count-jobs} en Postgres.} \label{fig:arquitectura} \end{figure}