Repository navigation
feat(api): límite de 20 preguntas por minuto por usuario (RNF-04) - #23
Merged
Merged
Conversation
POST /conversations/:id/messages rechaza con 429 (RATE_LIMIT_EXCEEDED y cabecera Retry-After) la pregunta número 21 dentro de un minuto, que es el criterio de aceptación de la sección 8. El límite es por userId, así que un usuario que lo agota no afecta a los demás. Ventana fija de 60 s en Redis con INCR y EXPIRE NX dentro del mismo MULTI: el primer intento abre la ventana y las ráfagas no la alargan. Es código propio en vez de @fastify/rate-limit porque la clave es el userId del token, que solo existe después de authenticate. Las respuestas desde caché también cuentan como pregunta. El límite se configura con RATE_LIMIT_QUESTIONS_PER_MINUTE (por defecto 20) y el README pasa la sección de RNF-04 de "pendiente" a implementada. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resumen
POST /conversations/:id/messagesrechaza con 429 (RATE_LIMIT_EXCEEDED, cabeceraRetry-After) la pregunta número 21 dentro de un minuto. Cubre el criterio de aceptación de la sección 8. El límite es poruserId: agotarlo no afecta a otros usuarios.modules/rate-limit/con el puertoRateLimitereninterfaces/y el adaptadorRedisRateLimiterenrepositories/. Se engancha comopreHandlerjusto después deauthenticate, solo en ese endpoint: RNF-04 limita preguntas, no peticiones en general.INCR+EXPIRE NX+TTLen un soloMULTI. El primer intento abre la ventana y las ráfagas no la alargan.@fastify/rate-limit: la clave es eluserIddel token, que solo existe después deauthenticate, y el contador comparte el Redis que ya usan la caché y la cola.RATE_LIMIT_QUESTIONS_PER_MINUTE(por defecto 20, con valor por defecto, así que no rompe ningún.env). El frontend no necesita cambios: ya muestra elmessagede la API en el banner de error. Solo se añade el código al tipoApiErrorCode.Base: #22 (Groq). Toca las mismas líneas de
config.ts/dependencies.ts, así que va apilada. Al mergear #22, GitHub la redirige amain.Test plan
pnpm lint/pnpm typecheck(los tres paquetes)pnpm test: tests unitarios del adaptador (comandos Redis, límite, TTL ausente, transacción abortada) y test de ruta (dos preguntas OK, tercera 429 conRetry-After, otro usuario sigue en 200)pnpm --filter @docqa/api test:coverage(100% en dominio)pnpm --filter @docqa/api test:integration(318 passed, Mongo real)docker compose: 1-20 permitidas, la 21 rechazada conretryAfterSeconds: 60, TTL de 60 s tras la ráfaga (no se alarga)🤖 Generated with Claude Code