diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 16ae21aa7..b9bbae586 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -507,7 +507,7 @@ method, or protocol. | `CLUSTER_MAX_CRASHES` | No | `5` | Maximum unexpected worker exits allowed inside the crash window before the primary exits non-zero. | | `CLUSTER_SHUTDOWN_TIMEOUT_MS` | No | `10000` | Time the cluster primary waits for worker disconnect during shutdown before forcing exit. | | `REDIS_URL` | No | unset | Shared Redis URL used automatically for rate limiting when `RATE_LIMIT_STORE=auto` and no explicit `RATE_LIMIT_REDIS_URL` is provided. | -| `SCRAPER_REQUEST_TIMEOUT_MS` | No | `10000` | Timeout for outbound page fetches and provider HTTP calls. | +| `SCRAPER_REQUEST_TIMEOUT_MS` | No | `10000` | Timeout for outbound page fetches and provider HTTP calls. The Render service raises this to `90000`: hosted vision models routinely take more than 10s per image, and the free-tier instance is slower still. | | `SCRAPER_MAX_REDIRECTS` | No | `5` | Redirect limit for outbound page fetches. | | `SCRAPER_MAX_CONTENT_LENGTH_BYTES` | No | `2097152` | Maximum response body size accepted when scraping HTML. | @@ -610,7 +610,7 @@ At least one provider must be configured at startup: `REPLICATE_API_TOKEN`, Azur - `/api/health` is the readiness signal used by Render. It returns `200` while the instance is ready and `503` once graceful shutdown begins. - Status routes use their own limiter so health probes are protected without sharing the main API request budget. - Clustered mode (`WORKER_COUNT > 1`) requires a Redis-backed limiter. Startup validation fails fast if clustered mode is enabled without `RATE_LIMIT_STORE=redis|auto` and a resolvable Redis endpoint. -- The current Render deployment keeps `RATE_LIMIT_REDIS_TOPOLOGY=external`, so the future pod-local Redis path is explicitly disabled for now. +- The current Render deployment runs the `external` topology — it does not set `RATE_LIMIT_REDIS_TOPOLOGY` at all, and `external` is the code default (`config/rateLimitStore.js`) — so the future pod-local Redis path is inactive for now. - Horizontal instance scaling should use an external/shared Redis-backed limiter, and `STATUS_RATE_LIMIT_MAX` should be sized for the aggregate health-probe budget across instances. - The future `RATE_LIMIT_REDIS_TOPOLOGY=unit-local` mode is meant for a Docker/Kubernetes-style resilient unit where several worker processes intentionally share one pod-local Redis instance. - Redis-backed limiter errors fail open at request time to preserve availability, but startup still fails fast when Redis is explicitly required and unreachable during bootstrap. diff --git a/README.md b/README.md index 7f1984dfe..e483939a1 100644 --- a/README.md +++ b/README.md @@ -270,10 +270,12 @@ GET `/api/accessibility/description` or `/api/v1/accessibility/description` - fast providers return `200` with the description array immediately - slow async providers such as `replicate` can return `202` with `jobId`, `status`, `pollAfterMs`, and `statusUrl` -Example: +Example — replace `` with a provider you configured in `.env`. +A provider registers only when its keys are set, and an unregistered one returns +`400 UNKNOWN_MODEL`: ```bash -curl -sk "https://localhost:8443/api/accessibility/description?image_source=https%3A%2F%2Fwww.google.com%2Fimages%2Fbranding%2Fgooglelogo%2F1x%2Fgooglelogo_color_272x92dp.png&model=replicate" +curl -sk "https://localhost:8443/api/accessibility/description?image_source=https%3A%2F%2Fwww.google.com%2Fimages%2Fbranding%2Fgooglelogo%2F1x%2Fgooglelogo_color_272x92dp.png&model=" ``` GET `/api/accessibility/description-jobs/:jobId` or `/api/v1/accessibility/description-jobs/:jobId` @@ -304,7 +306,7 @@ GET `/api/accessibility/descriptions` or `/api/v1/accessibility/descriptions` Example: ```bash -curl -sk "https://localhost:8443/api/accessibility/descriptions?url=https%3A%2F%2Fdeveloper.chrome.com%2F&model=replicate" +curl -sk "https://localhost:8443/api/accessibility/descriptions?url=https%3A%2F%2Fdeveloper.chrome.com%2F&model=" ``` GET `/api/accessibility/page-description-jobs/:jobId` or `/api/v1/accessibility/page-description-jobs/:jobId` diff --git a/docs/postman-standards.md b/docs/postman-standards.md index 952d54d06..4a609e073 100644 --- a/docs/postman-standards.md +++ b/docs/postman-standards.md @@ -12,7 +12,8 @@ Use the Postman/Newman layer for external HTTP contract validation, not for re-t - Fast deterministic checks required on pull requests - Covers core health/docs/routing, protected-endpoint auth, and one representative provider path - `full` - - Full deterministic harness for `main` and `production` + - Full deterministic harness. Runs on manual dispatch, weekly schedule, and paths-filtered push/PR to `main` (`Local Provider Integration`) + - Not run on `production` — CI runs the `smoke` tier there - Adds broader contract, negative-path, and page-description coverage - `live` - Manual or scheduled validation against real providers