Falla en abierto
Si el servicio de cola no está accesible o la cola no existe, el script no hace nada y la tienda sigue siendo plenamente utilizable. Una caída de la sala de espera nunca bloquea la tienda.
ADITUS-Queue es una sala de espera virtual autónoma que protege cualquier sitio web, API o servicio en línea frente a los picos de tráfico. Se integra a la perfección con la plataforma de venta de entradas ADITUS y se despliega con la misma independencia delante de cualquier aplicación web. Los visitantes se retienen en una sala de espera alojada y se redirigen estrictamente por orden de llegada, a un ritmo configurado por minuto. La integración va desde un simple enlace gateway o una etiqueta de script, sin ninguna infraestructura del lado del operador, hasta la API REST pura, pasando por la aplicación en el reverse proxy o el CDN.
Novedad: el ritmo de redirección autorregulado. La cola lee un health check de tu tienda y ajusta el ritmo por sí sola: más visitantes cuando la tienda tiene margen, alivio inmediato cuando se ve bajo presión.
A pesar de toda esta potencia: la configuración lleva minutos, no días. Un enlace publicado o una etiqueta de script: ninguna infraestructura, ningún despliegue, ningún cambio de código por tu parte.
Protege tu aplicación en menos de 2 minutos: copia la etiqueta de script en tu head o usa el enlace gateway. Sin cambios en tu infraestructura de servidor. Solo cuando quieras el máximo control activas las funciones avanzadas opcionales; todo lo demás en esta página es exactamente eso: profundidad opcional para más adelante.
En la administración de ADITUS: nombre, dirección de la tienda, ritmo de redirección por minuto. Todo lo demás viene preconfigurado con valores predeterminados razonables.
O bien publicar el enlace gateway ya preparado en lugar del enlace de la tienda, o bien insertar la etiqueta de script preparada en la página de la tienda, exactamente como un snippet de analítica.
Por debajo del ritmo de redirección, los visitantes nunca ven la sala de espera. Solo cuando llega un pico interviene la cola: alojada, escalada y operada por nosotros.
La potencia de la cola es una ruta de ampliación, no un requisito. El nivel 1 cubre por sí solo la gran mayoría de los casos de uso.
Qué variante encaja depende de una sola pregunta: ¿se puede cambiar el enlace publicado de la tienda? Si es así, el enlace gateway es la mejor opción: el tráfico nunca llega a la tienda antes de la redirección. Si la URL publicada de la tienda es fija, la etiqueta de script protege la tienda sin cambiar nada en su publicación. Más allá de estas dos, la comprobación puede aplicarse en el reverse proxy o el CDN (abajo), controlarse directamente mediante la API REST o verificarse en cualquier lenguaje de backend con una biblioteca JWT: Node.js, PHP, Java, .NET, Python, Go.
Cada sala de espera proporciona su propia URL de entrada. Se publica en todos los lugares donde de otro modo aparecería el enlace de la tienda: boletín, sitio web, redes sociales. La cola recibe la solicitud y decide del lado del servidor en un solo paso: por debajo del ritmo de redirección, el visitante se redirige directamente a la dirección configurada de la tienda y no percibe la cola en absoluto; una vez superado el ritmo, el visitante llega a la sala de espera y se redirige automáticamente cuando le toca. La tienda en sí no recibe ningún tráfico antes de la redirección: las solicitudes se absorben antes de llegar a la infraestructura de la tienda.
<!-- Der veröffentlichte Shop-Link zeigt auf die Queue statt auf den Shop: -->
<a href="https://developers.aditus.com/queue/<slug>/enter">Tickets kaufen</a>Para esta variante, la dirección de destino de la tienda (Ziel-URL) debe estar configurada en la cola: es la dirección a la que se redirigen los visitantes admitidos. Los visitantes admitidos llegan a la tienda con un token de acceso firmado en la URL, un JWT HS256 estándar que la tienda puede verificar opcionalmente offline en su propio backend con el secreto compartido. La estructura, los claims y un ejemplo de backend están documentados más abajo. Nota: el gateway protege el punto de entrada publicado; los visitantes que conocen directamente la URL de la tienda pueden eludirlo. Si eso importa, combina el enlace gateway con la etiqueta de script o verifica el token en el backend de la tienda.
Cuando no se puede cambiar el enlace publicado de la tienda, la integración consiste en una sola etiqueta de script. Se entrega junto con las páginas de la tienda, de la misma forma que un snippet de analítica, y debe estar presente en cada página que la sala de espera deba proteger. Se recomienda colocarla en el <head> con el atributo defer; la posición exacta no es crítica.
<!-- Auf jeder zu schützenden Shop-Seite im <head>: -->
<script src="https://developers.aditus.com/queue/<slug>/embed.js" defer></script>La etiqueta exacta para una sala de espera concreta, con el slug correcto ya insertado, está disponible en la administración de ADITUS por cada cola. El script realiza tres comprobaciones en cada carga de página:
No ocurre nada. El pase se guarda por sesión del navegador; el visitante usa la tienda sin interrupción.
El token de acceso de la URL se verifica del lado del servidor (firma, asignación a la cola, caducidad). Si es válido, se guarda un pase de sesión y se elimina el token de la barra de direcciones. Los tokens inválidos o caducados devuelven al visitante a la sala de espera.
Si en ese momento no espera nadie, el visitante se admite en silencio en segundo plano y permanece en la página: la sala de espera no aparece nunca. Solo cuando se supera el ritmo de redirección configurado y se ha formado una cola se redirige al visitante a la sala de espera; la página actual se transmite como URL de retorno validada, de modo que tras la redirección el visitante llega exactamente a la página que había solicitado originalmente.
Si el servicio de cola no está accesible o la cola no existe, el script no hace nada y la tienda sigue siendo plenamente utilizable. Una caída de la sala de espera nunca bloquea la tienda.
Las URL de retorno se validan del lado del servidor frente a los dominios configurados para la cola. La sala de espera solo redirige a páginas de la tienda registrada.
Las dos variantes anteriores protegen el punto de entrada publicado. Si la tienda debe ser inaccesible sin autorización incluso para los visitantes que conocen directamente su URL, la comprobación se coloca delante de la tienda, en el reverse proxy o el CDN que termina su tráfico. La lógica es siempre la misma en tres pasos: tomar el token del parámetro de URL aditus_queue_token cuando el visitante vuelve de la sala de espera y guardarlo como cookie; en cada solicitud, verificar el token de la cookie como un JWT HS256 estándar con el secreto compartido (issuer aditus-queue, audience el slug de la cola, caducidad); sin un token válido, redirigir a la sala de espera en https://developers.aditus.com/queue/<slug>. La verificación es offline: el proxy nunca llama a la cola y no añade latencia. Los siguientes esquemas muestran el patrón para cuatro entornos habituales; adáptalos a tu propio entorno.
# Skizze: Nginx mit njs (js_import) — prüft den Zugriffs-Token als HS256-JWT
# direkt am Proxy, ohne Rückruf an die Queue. An die eigene Umgebung anpassen.
# nginx.conf:
# env ADITUS_QUEUE_SECRET;
# js_import queue from /etc/nginx/queue.js;
# server {
# location / { js_content queue.gate; }
# location @shop { proxy_pass http://shop_backend; }
# }
// /etc/nginx/queue.js:
const crypto = require('crypto');
const SLUG = '<slug>';
const SECRET = process.env.ADITUS_QUEUE_SECRET; // Shared Secret der Queue
function claims(token) {
const p = token.split('.');
if (p.length !== 3) return null;
const sig = crypto.createHmac('sha256', SECRET)
.update(p[0] + '.' + p[1]).digest('base64url');
if (sig !== p[2]) return null;
const c = JSON.parse(Buffer.from(p[1], 'base64url'));
const ok = c.iss === 'aditus-queue' && c.aud === SLUG && c.exp > Date.now() / 1000;
return ok ? c : null;
}
function gate(r) {
const fromUrl = r.args.aditus_queue_token;
const m = (r.headersIn.Cookie || '').match(/(?:^|;\s*)aditus_queue=([^;]+)/);
const token = fromUrl || (m && m[1]);
if (!token || !claims(token)) {
// Kein gültiger Token -> zurück in den Warteraum
r.return(302, 'https://developers.aditus.com/queue/' + SLUG);
return;
}
if (fromUrl) {
// Token aus der Rücksprung-URL in ein Sitzungs-Cookie übernehmen
r.headersOut['Set-Cookie'] =
'aditus_queue=' + fromUrl + '; Path=/; Secure; HttpOnly; Max-Age=600';
}
r.internalRedirect('@shop');
}
export default { gate };# Skizze: Caddy mit dem jwtauth-Plugin (github.com/ggicci/caddy-jwt).
# Token kommt beim Rücksprung als ?aditus_queue_token=… oder danach als Cookie;
# jwtauth prüft beide Quellen. An die eigene Umgebung anpassen.
shop.example.com {
route {
jwtauth {
sign_key {env.ADITUS_QUEUE_SECRET}
sign_alg HS256
from_query aditus_queue_token
from_cookies aditus_queue
issuer_whitelist aditus-queue
audience_whitelist <slug>
user_claims qnr
}
# Token aus der URL einmalig in ein Cookie übernehmen
@rueckkehr query aditus_queue_token=*
header @rueckkehr Set-Cookie "aditus_queue={http.request.uri.query.aditus_queue_token}; Path=/; Secure; HttpOnly; Max-Age=600"
reverse_proxy shop_backend:8080
}
# Ohne gültigen Token: zurück in den Warteraum
handle_errors {
@unauth expression {http.error.status_code} == 401
redir @unauth https://developers.aditus.com/queue/<slug> 302
}
}// Skizze: Cloudflare Worker vor dem Shop — prüft den HS256-JWT offline per
// WebCrypto. Secret als Worker-Secret ADITUS_QUEUE_SECRET hinterlegen.
const SLUG = "<slug>";
const ROOM = "https://developers.aditus.com/queue/" + SLUG;
export default {
async fetch(req, env) {
const url = new URL(req.url);
const fromUrl = url.searchParams.get("aditus_queue_token");
const m = (req.headers.get("Cookie") || "").match(/(?:^|;\s*)aditus_queue=([^;]+)/);
const token = fromUrl || (m && m[1]);
if (!token || !(await valid(token, env.ADITUS_QUEUE_SECRET))) {
return Response.redirect(ROOM, 302); // zurück in den Warteraum
}
if (fromUrl) {
// Token in ein Cookie übernehmen und die URL bereinigen
url.searchParams.delete("aditus_queue_token");
return new Response(null, {
status: 302,
headers: {
Location: url.toString(),
"Set-Cookie": "aditus_queue=" + token +
"; Path=/; Secure; HttpOnly; Max-Age=600",
},
});
}
return fetch(req); // gültiger Pass -> durch zum Shop
},
};
async function valid(token, secret) {
const p = token.split(".");
if (p.length !== 3) return false;
const key = await crypto.subtle.importKey(
"raw", new TextEncoder().encode(secret),
{ name: "HMAC", hash: "SHA-256" }, false, ["verify"],
);
const ok = await crypto.subtle.verify(
"HMAC", key, b64url(p[2]),
new TextEncoder().encode(p[0] + "." + p[1]),
);
if (!ok) return false;
const c = JSON.parse(new TextDecoder().decode(b64url(p[1])));
return c.iss === "aditus-queue" && c.aud === SLUG && c.exp > Date.now() / 1000;
}
function b64url(v) {
return Uint8Array.from(
atob(v.replace(/-/g, "+").replace(/_/g, "/")),
(ch) => ch.charCodeAt(0),
);
}// Skizze: AWS CloudFront mit Lambda@Edge (Viewer-Request, Node.js).
// Gleiches Muster: Token aus ?aditus_queue_token oder Cookie, HS256 offline
// prüfen, ohne gültigen Token in den Warteraum umleiten.
// Hinweis: Lambda@Edge hat keine Umgebungsvariablen — das Secret z. B. beim
// Deployment einbetten oder aus SSM/Secrets Manager cachen.
'use strict';
const crypto = require('crypto');
const SLUG = '<slug>';
const ROOM = 'https://developers.aditus.com/queue/' + SLUG;
const SECRET = '<ADITUS_QUEUE_SECRET>';
exports.handler = async (event) => {
const req = event.Records[0].cf.request;
const qs = new URLSearchParams(req.querystring || '');
const fromUrl = qs.get('aditus_queue_token');
const cookie = (req.headers.cookie || []).map((h) => h.value).join('; ');
const m = cookie.match(/(?:^|;\s*)aditus_queue=([^;]+)/);
const token = fromUrl || (m && m[1]);
if (!token || !valid(token)) {
return redirect(ROOM); // zurück in den Warteraum
}
if (fromUrl) {
// Token in ein Cookie übernehmen und die URL bereinigen
qs.delete('aditus_queue_token');
const clean = req.uri + (qs.toString() ? '?' + qs.toString() : '');
return redirect(clean, {
'set-cookie': [{ key: 'Set-Cookie', value:
'aditus_queue=' + token + '; Path=/; Secure; HttpOnly; Max-Age=600' }],
});
}
return req; // gültiger Pass -> durch zum Shop (Origin)
};
function valid(token) {
const p = token.split('.');
if (p.length !== 3) return false;
const sig = crypto.createHmac('sha256', SECRET)
.update(p[0] + '.' + p[1]).digest();
const got = Buffer.from(p[2], 'base64url');
if (got.length !== sig.length || !crypto.timingSafeEqual(sig, got)) {
return false;
}
const c = JSON.parse(Buffer.from(p[1], 'base64url'));
return c.iss === 'aditus-queue' && c.aud === SLUG && c.exp > Date.now() / 1000;
}
function redirect(location, extraHeaders) {
return {
status: '302',
headers: Object.assign(
{ location: [{ key: 'Location', value: location }] },
extraHeaders || {},
),
};
}Nota: con la comprobación activa en el edge, cada visitante necesita un token, incluidos los que, por debajo del ritmo de redirección, pasarían de otro modo en silencio. Publica para ello el enlace gateway (variante A), o deja que el proxy redirija a los visitantes sin token a la sala de espera; esta emite un token de inmediato cuando la cola está vacía.
La sala de espera la configura ADITUS. Para la puesta en marcha, proporciona lo siguiente:
Una imagen de cabecera para la página de la sala de espera, p. ej. el key visual del evento. Formato horizontal, al menos 920 × 380 píxeles (mostrada hasta 460 px de ancho, recortada a una altura máxima de 190 px), JPG o PNG, entregada como URL HTTPS de acceso público o como archivo a ADITUS.
Un mensaje breve que se muestra bajo el título de la sala de espera, p. ej. una nota sobre el inicio de la venta o la espera prevista. Texto sin formato, se conservan los saltos de línea; longitud recomendada de hasta unos 300 caracteres. El texto se muestra tal cual: si te diriges a un público internacional, facilítalo en el idioma adecuado o de forma bilingüe.
Un color de marca como valor hexadecimal (p. ej. #0a63c9). Colorea la barra de progreso y el indicador en vivo de la página de la sala de espera; sin valor, se usa el color predeterminado de ADITUS. Junto con el gráfico y el texto, la sala de espera adopta así la identidad del organizador.
Los dominios de las páginas en las que se ejecutará el script (p. ej. shop.example.com). Definen qué URL de retorno acepta la sala de espera.
El título de la sala de espera (p. ej. el nombre del evento), la URL de destino para los visitantes redirigidos (necesaria para el enlace gateway: es la dirección de la tienda a la que redirige el gateway) y el ritmo de redirección en visitantes por minuto. El ritmo es el umbral de rendimiento: mientras lleguen menos visitantes de los que permite el ritmo, todos pasan sin sala de espera. Se puede ajustar en cualquier momento durante el funcionamiento.
Número de espera — asignado una vez al abrir la página y conservado durante toda la espera, incluso tras recargar.
Posición y número redirigido — cuántos números hay por delante y hasta qué número está abierta actualmente la redirección. El número redirigido crece de forma continua con el ritmo de redirección.
Barra de progreso — visualiza cuánto ha avanzado ya la redirección hacia tu propio número.
Espera estimada — calculada a partir de la posición actual y el ritmo de redirección; se acorta a medida que avanza la redirección. En cuanto tu número queda admitido, la página redirige automáticamente a la tienda, sin ninguna intervención.
Imagen de cabecera — opcional, p. ej. el key visual del evento.
Nombre visible — el título de la sala de espera, p. ej. el nombre del evento.
Mensaje — texto opcional bajo el título, mostrado tal cual.
La página de la sala de espera es en sí bilingüe (alemán/inglés). El idioma se selecciona automáticamente según la configuración del navegador del visitante; no hace falta ninguna configuración.
Durante la venta, ADITUS supervisa cada sala de espera en un panel en vivo: los indicadores muestran el número actual de personas en espera, la afluencia de nuevos visitantes frente al ritmo de redirección, el propio ritmo de redirección (con su tope configurado cuando el ritmo autorregulado está activo) y la espera estimada para los recién llegados. Un gráfico de dos series compara la espera y la afluencia a lo largo del tiempo, y las instancias de cola que atienden el tráfico informan de su propia carga: CPU, memoria y tasa de solicitudes. El ritmo de redirección puede ajustarse en cualquier momento durante el funcionamiento, por ejemplo cuando la tienda muestra margen.
La solidez de la cola no solo se afirma: se prueba con regularidad. Desde la administración de ADITUS, las pruebas de carga lanzan solicitudes reales a una sala de espera de prueba dedicada en el sistema de producción (las salas de espera productivas nunca se tocan). Una prueba simula la ruta del visitante —unirse y consultar el estado— a un ritmo y una duración configurables. Los indicadores en vivo muestran la tasa de solicitudes alcanzada, la latencia mediana y p95 y la tasa de error; un gráfico por segundo compara el rendimiento con la latencia, y cada ejecución se conserva en un historial para que los resultados sigan siendo comparables con el tiempo. Las pruebas también se ejecutan según una planificación recurrente, y una ejecución planificada que rinde claramente peor que las anteriores comparables se marca automáticamente.
Para la supervisión externa, el servicio de cola expone un health check público en /queue/healthz. Responde sin autenticación y sin acceso a la base de datos: una simple señal de disponibilidad para la supervisión de disponibilidad. Durante una prueba de carga, la administración muestra además las instancias de cola autoinformadas con CPU, memoria, retardo del event loop y tasa de solicitudes; bajo carga, la plataforma arranca instancias adicionales automáticamente, y la prueba lo hace visible.
El ritmo de redirección es el único control que decide todo durante una venta, y hasta ahora alguien tenía que vigilarlo. Se acabó: la cola puede regular el ritmo por sí misma, guiada por el estado real de la tienda protegida. El resultado es una sala de espera que vende, en cada momento, tan rápido como la tienda puede soportar con seguridad, sin que nadie toque ningún control.
Mientras la tienda está sana, el ritmo sube en pequeños pasos y el margen no utilizado se convierte en ventas. En cuanto la tienda muestra tensión, el ritmo cae con fuerza, deliberadamente asimétrico: el alivio es inmediato, la carga vuelve con cautela.
Un health check inaccesible nunca abre más las puertas: el ritmo primero se congela y luego cae al mínimo configurado. La tienda está protegida justo cuando nadie está mirando.
Tú defines qué significa «sano»: tiempo de respuesta, carga de CPU, cualquier métrica que informe tu tienda. Cada ajuste automático se registra y es visible en el panel en vivo, junto con la regla que lo activó.
En lugar de ajustar el ritmo de redirección a mano, una sala de espera puede regularlo automáticamente a partir de un health check de la tienda protegida. ADITUS consulta una URL de salud de la tienda a un intervalo configurable y evalúa el tiempo de respuesta y, opcionalmente, campos numéricos de la respuesta JSON frente a reglas definidas por el operador (por ejemplo: tiempo de respuesta por debajo de 500 ms, carga de CPU por debajo de 0,8). Mientras la tienda está sana, el ritmo se sube lentamente en pequeños pasos; en cuanto se incumple una regla, se baja rápidamente un porcentaje, deliberadamente asimétrico, para que la tienda se alivie de inmediato pero la carga vuelva con cautela. El ritmo se mantiene siempre dentro de un mínimo y un máximo configurados.
Si el endpoint de salud no responde, el sistema pasa a modo fail-safe: el ritmo primero se congela y, tras varios fallos consecutivos, cae al mínimo configurado; un health check inaccesible nunca abre más las puertas. Cada ajuste automático se registra y es visible en el panel en vivo, y antes de poder activar la automatización, el endpoint debe superar una prueba única lanzada desde la administración.
El endpoint de salud del lado de la tienda sigue siendo trivial: una URL HTTPS, accesible sin autenticación, que responde 2xx. Un cuerpo JSON es opcional: todos los campos numéricos (los objetos anidados se aplanan a rutas con puntos) se convierten en métricas a las que las reglas pueden hacer referencia:
{
"status": "ok",
"responseBudgetMs": 500,
"metrics": {
"cpuLoad": 0.42,
"dbPoolWaiting": 0,
"openCheckouts": 118
}
}
// Nutzbare Messwerte (Punktpfade):
// responseBudgetMs, metrics.cpuLoad, metrics.dbPoolWaiting, metrics.openCheckouts
// Dazu immer verfügbar: die gemessene Antwortzeit (ms).Para las ventas de gran demanda, una sala de espera puede exigir además una prueba de trabajo antes de emitir un número de espera. El navegador resuelve entonces en segundo plano un pequeño acertijo criptográfico, invisible para el visitante y, con la dificultad predeterminada, muy por debajo de un segundo en dispositivos normales. Para una granja de bots la cosa cambia: cada unión cuesta el mismo trabajo de cálculo, de modo que sacar miles de números se vuelve proporcionalmente caro en lugar de gratis. La protección está desactivada por defecto y se activa por sala de espera en la administración de ADITUS; la dificultad es ajustable (de 8 a 24 bits, 15 por defecto: cada bit adicional duplica el trabajo). La página de sala de espera alojada resuelve el acertijo automáticamente; nada cambia para la integración de la tienda.
Una consecuencia deliberada: mientras la protección está activa, el paso silencioso por debajo del ritmo de redirección queda desactivado; cada visitante atraviesa la sala de espera, porque solo allí se realiza la prueba de trabajo. Y una aclaración de alcance: la prueba de trabajo protege la emisión de números de espera frente a las uniones masivas. Es una pieza más contra los compradores automatizados, no una defensa anti-bots completa: combínala cuando haga falta con medidas en la propia tienda (como límites de compra).
Solo las integraciones propias que llaman directamente a la API de la cola deben resolver el acertijo por sí mismas. El flujo: obtener un challenge, encontrar un nonce cuyo hash SHA-256 del challenge más el nonce empiece por el número requerido de bits en cero, y enviar ambos con la solicitud de unión. Los challenges están firmados y son válidos durante cinco minutos; además, su reutilización se bloquea por instancia:
// 1. Challenge holen (nur relevant, wenn PoW für die Queue aktiv ist)
GET https://developers.aditus.com/queue/<slug>/pow
// -> { queue, enabled: true, challenge, bits, expiresInSeconds: 300,
// algorithm: "sha256" }
// 2. Nonce suchen: SHA-256(challenge + "." + nonce) muss mit <bits>
// Null-Bits beginnen. Im Browser per WebCrypto — bei der
// Standard-Schwierigkeit deutlich unter einer Sekunde.
// 3. Beitritt mit Lösung
POST https://developers.aditus.com/queue/<slug>/join
{ "pow": { "challenge": "…", "nonce": "…" } }
// Ohne oder mit ungültiger Lösung antwortet /join mit
// 428 Precondition Required — und liefert im Fehlerkörper direkt eine
// frische Challenge mit, sodass kein zweiter Abruf nötig ist.Para las ventas anunciadas, una sala de espera puede tener una hora de apertura fija. Los visitantes que llegan pronto acaban en una precola: la página de la sala de espera muestra una cuenta atrás hasta la apertura y todavía no se redirige a nadie. A la hora de apertura ocurre el paso decisivo: el orden de redirección entre todas las personas que esperan en ese momento se sortea de forma justa. Llegar tres horas antes no aporta, por tanto, ninguna ventaja frente a llegar tres minutos antes; los maratones de recarga y las pestañas aparcadas pierden todo su sentido. Quien se une después de la apertura se coloca detrás del grupo sorteado, en el orden de llegada normal.
El sorteo es una permutación matemática sobre los números de espera emitidos antes de la apertura: cada número recibe exactamente una posición, ninguno se pierde, ninguno aparece dos veces, y la asignación no es predecible a partir del orden de unión. Cambiar la hora de apertura en la administración rearma el sorteo; nada cambia para la integración de la tienda ni para la API.
No todos los que sacan un número de espera se quedan. Las pestañas cerradas y los navegadores abandonados dejan de otro modo huecos: la ventana de redirección pasa sobre números que ya no pertenecen a nadie, y el rendimiento real cae por debajo del ritmo configurado. Con la detección de abandono activada, la página de sala de espera alojada señala su presencia mediante un heartbeat regular. Si un número permanece en silencio más tiempo que el periodo de gracia configurado (de 60 a 3600 segundos, 180 por defecto), cuenta como abandonado, y la ventana de redirección avanza justo esa cantidad más rápido, de modo que las plazas liberadas van a parar a los visitantes que realmente siguen esperando.
La detección es deliberadamente indulgente: un visitante que vuelve y cuyo número se había contado como abandonado, pero que ya está dentro de la ventana de redirección, se redirige con normalidad; el heartbeat solo acelera, nunca revoca una redirección. Las integraciones propias que construyen su propia página de espera envían la misma señal mediante POST /queue/<slug>/heartbeat (cuerpo JSON con el número de espera, recomendado cada 60 segundos).
Prensa, socios, contingentes de fan-clubs: algunos visitantes no deberían ver nunca una sala de espera. Para ellos se pueden crear códigos de bypass por sala de espera en la administración de ADITUS, cada uno con una etiqueta, un límite de uso opcional y una fecha de caducidad opcional, y cada uno se puede desactivar o eliminar en cualquier momento. Un código se comparte como un simple enlace: /queue/<slug>/enter?code=… redirige directamente a la tienda con un token de acceso válido, saltándose toda la cola. Las integraciones propias pueden canjear los códigos mediante POST /queue/<slug>/bypass y recibir el token como JSON.
Dos propiedades de seguridad deliberadas: un código inválido en el enlace gateway cae en silencio en la ruta normal; desde fuera es imposible saber si un código existió alguna vez. Y la ruta JSON responde de forma idéntica para los códigos inválidos, caducados, agotados y desactivados, de modo que no hay ningún oráculo para adivinar códigos. Las redirecciones por bypass se marcan como tales en el token y no consumen plazas de redirección regulares.
Las siguientes secciones no son necesarias para la integración: la etiqueta de script anterior está completa. Documentan el funcionamiento interno para la evaluación técnica y para las tiendas que quieren verificar además la redirección en su propio backend.
Cada visitante recibe un número de espera secuencial mediante un único incremento atómico en la base de datos. La redirección avanza de forma continua: el número redirigido actual se calcula como base + ritmo × minutos transcurridos. La consulta de estado es de solo lectura y no toca la base de datos en cada solicitud. No hay ningún estado por visitante en el servidor, ninguna tarea cron ni ningún temporizador: el servicio de cola no puede convertirse él mismo en un cuello de botella bajo carga. Pausar una cola detiene tanto la redirección como la emisión de nuevos números; los cambios de ritmo surten efecto de forma continua y el número redirigido nunca retrocede.
La redirección se hace estrictamente por orden de llegada (First come, first served): el incremento atómico fija la posición de cada visitante en el momento de unirse, y las posiciones no cambian nunca después. No hay deliberadamente ninguna lotería, ninguna selección aleatoria ni ningún carril prioritario: en situación de escasez, el orden de llegada es el único orden que los visitantes aceptan como justo, y el único que no se puede manipular. Colarse queda técnicamente excluido en dos niveles: los números de espera solo crecen, y la comprobación de redirección compara el número del visitante con el número redirigido actual en el servidor; el token de acceso solo se emite una vez superada esa comprobación, firmado con el secreto de la cola. Un visitante no puede reclamar una posición mejor, y un token falsificado falla la verificación de firma. Los operadores que necesitan flujos separados —por ejemplo, una sala de espera por evento o por venta— ejecutan varias salas de espera independientes, cada una con su propio slug, secreto, ritmo y configuración.
El objetivo de diseño se deriva directamente de la lógica de redirección anterior: como el número redirigido se deduce del tiempo transcurrido y la comprobación de estado no lee ningún estado por visitante, casi todo el tráfico de visitantes es cálculo sin estado. Cualquier instancia puede responder a cualquier solicitud, las instancias no comparten nada salvo la base de datos, y la plataforma añade instancias automáticamente bajo carga. La única escritura en la base de datos por visitante —el incremento atómico al unirse— es el único punto de serialización, y ocurre exactamente una vez por visitante, no en cada consulta. Las cifras siguientes provienen del runner de pruebas de carga integrado descrito antes, medidas a través del endpoint HTTPS público contra una sola instancia del servicio de cola; el perfil mix combina la unión y la consulta de estado en la proporción de la ruta real del visitante:
mix · 10 req/s · 30 sLatencia p50 7,6 ms · p95 12,0 ms · tasa de error 0 %mix · 25 req/s · 60 sLatencia p50 7,3 ms · p95 11,4 ms · tasa de error 0 %mix · 50 req/s · 45 sLatencia p50 6,7 ms · p95 11,0 ms · tasa de error 0 %status · 50 req/s · 45 sLatencia p50 6,4 ms · p95 8,9 ms · tasa de error 0 %Medido en julio de 2026 con la ruta de código de producción; cada ejecución terminó sin errores y con una latencia mediana de un solo dígito. Una sola instancia asume cincuenta solicitudes por segundo —varios miles de visitantes en espera consultando en el intervalo recomendado— sin inmutarse; más allá de eso, entran instancias adicionales. Este escalado no es una caja negra: cada instancia en ejecución se informa a sí misma de forma continua con métricas en vivo —CPU, memoria, rendimiento de solicitudes— consultables en cualquier momento en la administración de ADITUS. Así queda transparente cuántas instancias sostienen una venta y cuánto margen queda. Las pruebas de carga programadas revalidan estas cifras de forma continua contra el sistema de producción, y una ejecución que queda claramente por detrás de sus predecesoras se marca automáticamente.
Diez endpoints, sin autenticación para los visitantes, CORS restringido a los dominios configurados por cola. La página de sala de espera alojada usa exactamente esta API, que también puede controlarse directamente para una experiencia de espera totalmente a medida.
GET /queue/<slug>Página de sala de espera alojada: solicita un número, consulta el estado y redirige automáticamente al visitante una vez admitido.POST /queue/<slug>/joinEmitir un número de espera (el único acceso de escritura en la ruta del visitante). 423 mientras la cola está en pausa.GET /queue/<slug>/status?number=NConsultar el estado de redirección de un número: solo lectura, incluye una cabecera Retry-After. 404 para números nunca emitidos.POST /queue/<slug>/tokenCanjear un número admitido por un JWT HS256 firmado. 425 mientras el número aún no está admitido; 404 para números nunca emitidos.GET /queue/<slug>/enterPunto de entrada gateway: se publica en lugar de la URL de la tienda. Redirige directamente a la URL de destino configurada (con token de acceso) mientras haya capacidad; de lo contrario, a la sala de espera. Requiere una URL de destino configurada. Acepta ?code=… para códigos VIP: un código válido omite por completo la cola, uno inválido cae en la ruta normal sin ninguna indicación.GET /queue/<slug>/embed.jsScript de integración del lado de la tienda: deja pasar a los visitantes en silencio mientras nadie espera; en cuanto se ha formado una cola, dirige a los visitantes sin pase válido a la sala de espera y los devuelve exactamente a la página de origen.GET /queue/<slug>/verify?token=…Comprobación de token del lado del servidor utilizada por el script de integración: valida la firma, la audience y la caducidad de un token de acceso.GET /queue/<slug>/infoInformación pública de la cola: estado activo, número admitido actualmente y cantidad de personas en espera.POST /queue/<slug>/heartbeatSeñal de presencia para la detección de abandono opcional: la página de sala de espera informa de que un número sigue presente. Se acepta en silencio mientras la detección está desactivada.POST /queue/<slug>/bypassCanjear un código VIP mediante JSON: devuelve un token de acceso junto con la URL de destino. Los códigos inválidos, caducados, agotados y desactivados devuelven todos el mismo 404: ningún oráculo para adivinar códigos.GET /queue/<slug>/powDesafío de prueba de trabajo para la protección anti-bots opcional: devuelve enabled: false mientras la protección está desactivada; de lo contrario, un desafío firmado cuya solución espera /join.GET /queue/healthzHealth check público para la supervisión de disponibilidad: responde sin autenticación y sin acceso a la base de datos. Excluido deliberadamente de las métricas de instancia, para que los pings de supervisión nunca distorsionen la imagen del tráfico.// Wartenummer anfordern (einziger Schreibzugriff im Besucherpfad).
const res = await fetch("https://developers.aditus.com/queue/<slug>/join", {
method: "POST",
});
const ticket: {
queue: string; // Queue-Slug
name: string; // Anzeigename des Warteraums
number: number; // vergebene Wartenummer
serving: number; // bis zu dieser Nummer wird weitergeleitet
ahead: number; // Anzahl Nummern vor dieser
admitted: boolean; // true -> sofort weiter zu /token
estimatedWaitSeconds: number;
retryAfterSeconds: number; // empfohlenes Polling-Intervall
} = await res.json();
// 423 Locked -> der Warteraum ist pausiert (keine Weiterleitung, keine neuen Nummern).// Statusabfrage — rein lesend, beliebig oft wiederholbar.
// Der Server sendet zusätzlich einen Retry-After-Header.
const res = await fetch(
"https://developers.aditus.com/queue/<slug>/status?number=" + ticket.number,
);
const status: {
queue: string;
name: string;
active: boolean; // false -> Weiterleitung pausiert
number: number;
serving: number;
ahead: number;
admitted: boolean;
estimatedWaitSeconds: number;
retryAfterSeconds: number;
} = await res.json();
if (status.admitted) {
// -> Token abholen und zum Shop weiterleiten
}// Sobald admitted=true: Zugriffs-Token abholen.
const res = await fetch("https://developers.aditus.com/queue/<slug>/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ number: ticket.number }),
});
// 425 Too Early -> die Nummer ist noch nicht zur Weiterleitung freigegeben.
const grant: {
queue: string;
number: number;
token: string; // signierter HS256-JWT
tokenType: "JWT";
expiresInSeconds: number; // Standard: 600 s
targetUrl: string | null; // konfiguriertes Weiterleitungsziel
} = await res.json();
// Weiterleitung übernimmt die gehostete Warteraum-Seite automatisch:
// targetUrl + "?aditus_queue_token=" + grant.tokenLa integración por etiqueta de script es completa por sí sola. Las tiendas que controlan su backend pueden verificar allí además el token de acceso: es un JWT HS256 estándar, verificable offline con el secreto compartido, sin devolución de llamada a la cola ni latencia adicional. El secreto se genera al crear la cola, se muestra una sola vez y se puede rotar en cualquier momento. Claims: iss siempre vale aditus-queue, aud es el slug de la cola, qnr es el número de espera redirigido, exp limita la validez (10 minutos por defecto). Nota: el paso silencioso por debajo del ritmo de redirección no produce token; un backend que exija obligatoriamente un token debería enviar a los visitantes que no lo tengan a la sala de espera, que entonces emite un token de inmediato cuando no espera nadie.
// ZIELSYSTEM (dein Shop / deine Seite): Token prüfen — Standard-JWT (HS256).
// Das Secret erhältst du einmalig von ADITUS beim Einrichten des Warteraums.
import jwt from "jsonwebtoken";
const payload = jwt.verify(token, process.env.ADITUS_QUEUE_SECRET!, {
algorithms: ["HS256"],
issuer: "aditus-queue", // iss ist immer aditus-queue
audience: "<slug>", // aud ist der Queue-Slug deines Warteraums
}) as { qnr: number; iat: number; exp: number };
// payload.qnr = die weitergeleitete Wartenummer.
// Gültiger Token -> Besucher passieren lassen (z. B. Cookie setzen).
// Fehlender/ungültiger Token -> zurück in den Warteraum:
// https://developers.aditus.com/queue/<slug>Los mecanismos de seguridad se describen arriba donde encajan en el flujo; esta sección los reúne. Tokens firmados: los tokens de acceso son JWT HS256, firmados con un secreto propio de cada cola, que se muestra una sola vez y se puede rotar en cualquier momento; la vinculación de audience (slug de la cola) y una validez corta (10 minutos por defecto) limitan lo que vale un token interceptado. Protección anti-bots: la comprobación opcional por prueba de trabajo hace que la unión masiva desde granjas de bots resulte proporcionalmente cara; los challenges están firmados con HMAC y caducan a los cinco minutos; una protección best-effort por instancia bloquea además la reutilización de un challenge ya consumido: el verdadero factor de coste es el propio trabajo de hash. Redirecciones: las URL de retorno se validan del lado del servidor frente a los dominios configurados por cola; la sala de espera nunca se convierte en una redirección abierta. Superficie de la API: los endpoints de visitante no llevan ninguna credencial, el CORS está restringido por cola, el acceso de administración usa claves de API vinculadas cada una a una sola sala de espera, almacenadas solo como hash, que no pueden gestionar otras claves y dejan un rastro de auditoría. Picos de tráfico: la arquitectura sin estado absorbe la carga por diseño; cualquier instancia responde a cualquier solicitud, y la plataforma escala las instancias automáticamente; el filtrado DDoS a nivel de red lo proporciona la plataforma de alojamiento delante del servicio.
Una sala de espera se sitúa delante de los ingresos: su comportamiento en caso de fallo importa tanto como su funcionamiento normal.
ADITUS-Queue aborda los mismos problemas técnicos que los productos empresariales especializados de sala de espera virtual. La tabla relaciona las capacidades por las que se mide a estos productos con la forma en que ADITUS-Queue las cubre, incluida una omisión deliberada.
Todo lo que la administración de ADITUS puede hacer con una sola sala de espera —ajustar el ritmo de redirección, pausar, cambiar la configuración— está también al alcance de las máquinas. El acceso se realiza mediante una clave de API con el prefijo qak_, enviada como Bearer token; cada clave se crea para exactamente una sala de espera y solo puede leer y modificar esa sala. Las claves se crean y revocan en la administración, se muestran una sola vez y se almacenan solo como hash. El caso de uso típico es un runbook de venta: una tarea programada sube el ritmo de redirección justo antes del inicio, un script pausa la cola en una emergencia, la supervisión lee la configuración actual. Se aplican tres salvaguardas: una clave nunca alcanza otras salas de espera ni funciones de administración globales (pruebas de carga, programaciones, instancias) —esas solicitudes se rechazan en el servidor—; la propia gestión de claves es deliberadamente imposible con una clave —una clave filtrada nunca puede crear ni listar otras claves—; y cada cambio realizado con una clave se registra en el registro de auditoría con el nombre de la clave y su sala de espera.
# Konfiguration des zugeordneten Warteraums lesen. Jeder Key ist an genau
# einen Warteraum gebunden — die Liste enthält daher höchstens diesen einen
# Eintrag; andere Warteräume und globale Verwaltungsfunktionen sind mit
# einem Key nicht erreichbar.
curl -H "Authorization: Bearer qak_…" \
https://developers.aditus.com/api/admin/queue/sites
# Weiterleitungsrate im laufenden Betrieb anheben: Lesen -> Feld ändern -> Schreiben.
# PATCH erwartet die vollständige Konfiguration (ohne slug); unbekannte
# Felder wie id oder Zeitstempel werden serverseitig ignoriert.
KEY="qak_…"; BASE="https://developers.aditus.com/api/admin/queue"
SITE=$(curl -s -H "Authorization: Bearer $KEY" "$BASE/sites" \
| jq '.sites[0]')
echo "$SITE" | jq '.ratePerMinute = 300' | curl -s -X PATCH \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d @- "$BASE/sites/$(echo "$SITE" | jq -r .id)"
# Zugeordneten Warteraum pausieren (keine Weiterleitung, keine neuen Nummern):
# active = false
echo "$SITE" | jq '.active = false' | curl -s -X PATCH \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d @- "$BASE/sites/$(echo "$SITE" | jq -r .id)"# .github/workflows/onsale.yml — Weiterleitungsrate zum Vorverkaufsstart anheben.
# Den API-Key als Repository-Secret ADITUS_QUEUE_API_KEY hinterlegen. Der Key
# ist an den Warteraum des Vorverkaufs gebunden — mehr kann er nicht.
name: Weiterleitungsrate zum On-Sale anheben
on:
schedule:
- cron: "55 8 14 3 *" # 14. März, 08:55 UTC — kurz vor dem On-Sale
workflow_dispatch: {}
jobs:
raise-rate:
runs-on: ubuntu-latest
steps:
- name: Rate auf 300/min anheben
env:
KEY: ${{ secrets.ADITUS_QUEUE_API_KEY }}
run: |
BASE="https://developers.aditus.com/api/admin/queue"
# Der Key sieht nur seinen gebundenen Warteraum — .sites[0] genügt.
SITE=$(curl -sf -H "Authorization: Bearer $KEY" "$BASE/sites" \
| jq '.sites[0]')
echo "$SITE" | jq '.ratePerMinute = 300' \
| curl -sf -X PATCH \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d @- "$BASE/sites/$(echo "$SITE" | jq -r .id)"