Repository navigation
feat(docs): complete the OpenAPI documentation and harden the agent rate limits - #459
Merged
Cjay-Cyber-2 merged 2 commits intoOct 21, 2026
Conversation
…ate limits Closes ASTROIDX556#448 Closes ASTROIDX556#443 Swagger documentation (ASTROIDX556#448) The OpenAPI document only described the success status of most endpoints: the response schema was systematically dropped and the error responses had no body, so the document could not be used to generate a client. - The success schema was lost because @ApiEnvelope always wrote a 200 response while the route documented its own status, and @ApiPaginationQuery replaced the response of the list endpoints instead of adding the X-Total-Count header to it. Both decorators now compose: @ApiEnvelope takes the status, the description and the response headers, @ApiPaginatedEnvelope documents a list response with its total-count header, and @ApiPaginationQuery only documents the query parameters. - New @ApiErrorResponses decorator references a shared ApiErrorEnvelopeDto (the RFC 9457 problem-details body every error returns) instead of repeating an empty response per status code. - Every endpoint of the 21 domain modules now documents its success schema, its request body and the error statuses it can answer with; 34 response DTOs were added where none existed. - Every property of every schema carries a description and, where it helps, an example. - src/openapi.spec.ts grew from a smoke test into a documentation check: every operation needs a tag, a summary, a documented success schema and error responses, every $ref has to resolve and every schema property has to be documented. It runs as `npm run docs:check` and as a CI step. Agent transaction rate limiting (ASTROIDX556#443) - The sliding-window limiter that guards transaction submission now buckets per acting agent (route parameter, body, query or x-agent-id header) before the API key, the organization and the IP, so one agent can no longer exhaust the budget of the other agents of the same organization. The agent identity resolution moved into a shared helper used by both limiters. - The agent command routes (pause, resume, suspend, wallet assignment) are rate limited as well. - Retry-After was always 1 second because it was derived from the window start. The oldest member of the window is now read in the same atomic transaction, so the header points at the moment the next request is accepted. - Tests cover normal requests, limit violations, the Retry-After value, per-agent bucketing and concurrent requests (the window is applied in a MULTI/EXEC transaction, so exactly `limit` requests of a burst are accepted).
|
@billcode124 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
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.
Summary
Completes the OpenAPI/Swagger documentation across every domain module and hardens the Redis-backed rate limiting of the agent-facing endpoints.
Closes #448
Closes #443
Type of change
Why
#448 — Swagger documentation. The generated document described the status of most endpoints but not their shape: the success schema was systematically dropped and the error responses had no body at all, so the document could not be used to generate a client.
The success schema was lost for two reasons, both inside the shared decorators:
@ApiEnvelopealways wrote a 200 response while the route documented its own status (201 for creations), so the envelope landed on a status the endpoint never answers with;@ApiPaginationQueryreplaced the response of the list endpoints instead of adding theX-Total-Countheader to it, wiping the envelope schema of every list route.Both decorators now compose:
@ApiEnvelope(model, { isArray, status, description, headers })owns the success response (status, description and schema) and is the only decorator that may describe it;@ApiPaginatedEnvelope(model)documents a list response together with its total-count header;@ApiPaginationQuery()documents only the query parameters;@ApiErrorResponses({ validation, unauthorized, forbidden, notFound, conflict, unprocessable, tooManyRequests, serverError })references a sharedApiErrorEnvelopeDto— the RFC 9457 problem-details body every error returns — instead of repeating an empty response per status code. A string instead oftrueoverrides the default description.With that in place every endpoint of the 21 domain modules documents its success schema, its request body and the error statuses it can answer with; 34 response DTOs were added where the module had none, and every property of every schema now carries a description (and an example where it helps).
src/openapi.spec.tsgrew from a smoke test into a documentation check: every operation needs a tag, a summary, a documented success schema and error responses, every$refhas to resolve to a schema that exists (no missing type definitions) and every schema property has to be documented. It runs asnpm run docs:checkand as a dedicated CI step.#443 — agent transaction rate limiting. The Redis sliding-window limiter that guards transaction submission bucketed by organization, so one noisy agent could exhaust the budget of every other agent of the same organization.
x-agent-idheader) first, then per API key, per organization and finally per IP. The identity resolution moved into a shared helper (resolve-agent-id) used by both limiters, so the two cannot drift apart again.Retry-Afterwas always1second: it was derived from the window start instead of the oldest request in the window. The oldest member is now read in the same atomicMULTI/EXECtransaction, so the header points at the moment the next request is accepted.Testing
src/common/guards/sliding-window-throttler.guard.spec.ts— normal requests, limit violations, the HTTP 429 status, theRetry-Aftervalue, per-agent bucketing and concurrent requests (a fake Redis with an atomicMULTI/EXECproves that exactlylimitrequests of a burst are accepted).src/modules/agents/tests/agent-rate-limiter.spec.ts— the per-agent limiter, including concurrent requests and per-agent windows.src/openapi.spec.ts— the documentation validity check (8 tests).Checklist
npm run buildpassesnpm testpassesnpm run lintpassesnpm run typecheckpassesnpm run docs:checkpassesnpm run db:verifypasses (no schema change in this PR)