Skip to content

Commit dab4dcf

Browse files
brovenclaude
andauthored
feat: rectifier, OpenAI format support, React admin panel & observability (#23)
* feat: Add OpenAI format provider support (#11) * feat: add OpenAI format provider support Add bidirectional format conversion for OpenAI Chat Completions API, enabling fallback providers like OpenRouter, Together AI, and any OpenAI-compatible endpoint. Changes: - Add format field to ProviderConfig (anthropic|openai) - Implement request/response conversion with tool_use support - Add streaming SSE conversion via TransformStream - Update admin UI with format selector - Add 37 comprehensive tests (259 total passing) - Validate format field at API boundary Co-Authored-By: Claude Haiku 4.5 <[email protected]> * test: improve format-converter coverage to 99%+ Add tests for edge cases: non-string/non-array content, invalid JSON in stream, interleaved text+tool_calls, flush with remaining buffer, and usage in regular chunks. * chore: add Codecov configuration with relaxed thresholds Allow coverage to decrease by up to 5% and set patch target to 70% to prevent CI failures on minor coverage fluctuations. Co-Authored-By: Claude Sonnet 4.5 <[email protected]> * feat: test multiple Claude models in testConnection with mapping suggestions Refactor testProvider to test 4 models (Sonnet, Opus 4, Opus 4.6, Haiku) in parallel instead of a single hardcoded model. Shows per-model results in the admin UI and suggests adding model mappings when models fail without one configured. Also adds claude-opus-4-6-20250415 to CLAUDE_MODELS. * feat: add provider disable/enable toggle in admin panel Show Anthropic primary API as fixed first entry with toggle switch. Replace reorder arrow buttons with enable/disable toggles on all providers. Disabled providers are skipped during request routing. * test: add tests for provider disable/enable skipping behavior Verify disabled Anthropic primary and fallback providers are skipped during request routing, and that 502 is returned when all are disabled. --------- Co-authored-by: Claude Haiku 4.5 <[email protected]> * chore: model rename * chore: change model name * chore: add more log info * chore: add more log * Refactor code for consistency and readability; update import styles, error messages, and logging format. Adjust provider configurations and enhance circuit breaker functionality. Remove DEBUG variable from wrangler configuration. * feat: new fallback algo (#13) * feat: implement sliding window circuit breaker with tiered backoff (#14) * feat: new fallback algo * docs: update documentation for circuit breaker implementation - Update CLAUDE.md with circuit breaker architecture details - Expand README.md with setup instructions - Add comprehensive testing guide - Update environment variables documentation - Add contribution guidelines - Expand runbook with troubleshooting steps Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]> * feat: add debug curl logging and structured observability (#15) * feat: add structured logging and observability Implements comprehensive observability with structured JSON logging: - Add structured logger utility with JSON format output - Generate unique Request ID for end-to-end tracing - Return Request ID in response headers (X-Request-ID) - Support client-provided Request ID via header - Replace all console.log with structured events - Track latency for all provider attempts - Add 11 event types: request.*, provider.*, circuit_breaker.*, safety_valve.*, auth.*, config.* All logs include: - timestamp (ISO 8601) - level (debug/info/warn/error) - event type - requestId - structured data (provider, model, status, latency, error) Benefits: - Full request tracing via Request ID - Easy querying in Cloudflare Dashboard - Ready for Logpush to Grafana/Datadog/Sentry - Automatic tracing integration (already enabled in wrangler.jsonc) Documentation: - Added docs/observability.md with usage guide - Updated CLAUDE.md with observability section Co-Authored-By: Claude Sonnet 4.5 <[email protected]> * fix: correct Headers type for x-request-id response header Convert Record<string, string> from cleanHeaders to Headers object before calling .set() method. * chore: update * feat: log reproducible curl command on request failure When all providers fail, emit a `request.debug_curl` log entry containing a copy-paste ready curl command that reproduces the original request to the proxy. Accessible via `npm run tail` for local debugging. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.5 <[email protected]> * feat: redirect / to /admin Replace the health check endpoint at / with a 302 redirect to /admin, preparing for login page support on the admin panel. Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: add login page handler Add loginPage export to admin.ts that renders a standalone login form. The page validates the admin token against /admin/config, stores it in localStorage for session persistence, and redirects to the admin panel on success. Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: redirect unauthenticated /admin to login page Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: persist admin token in localStorage with logout Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: use Authorization header for admin API calls Switch admin panel fetch calls from passing token as query parameter to using Authorization: Bearer header. This is more secure as tokens in query params can leak via server logs and referrer headers. Co-Authored-By: Claude Opus 4.6 <[email protected]> * chore: add script * fix: id * feat: add circuit breaker status display and manual reset to admin panel (#16) * feat: add GET /admin/provider-states endpoint Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: add CSS for circuit breaker status badges Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: show circuit breaker status badges on admin provider cards Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: add manual reset button for provider circuit breaker Co-Authored-By: Claude Opus 4.6 <[email protected]> * docs: add implementation plan for admin circuit breaker status --------- Co-authored-by: Claude Opus 4.6 <[email protected]> * feat(rectifier): implement Anthropic API rectifier system (#18) * feat(rectifier): add type definitions for rectifier system * feat(rectifier): implement Anthropic API rectifier system Add automatic rectifier that detects and fixes Anthropic API request compatibility issues with third-party providers. Includes thinking signature rectification (removes thinking blocks, redacted_thinking blocks, and signature fields) and thinking budget rectification (adjusts budget_tokens and max_tokens to valid ranges). Each rectifier retries once per request to prevent infinite loops. Configurable via admin API endpoints with KV persistence. Co-Authored-By: Claude Opus 4.6 <[email protected]> * docs: add rectifier implementation plans Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]> * Broven/admin cb status (#17) * feat: add GET /admin/provider-states endpoint Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: add CSS for circuit breaker status badges Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: show circuit breaker status badges on admin provider cards Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat: add manual reset button for provider circuit breaker Co-Authored-By: Claude Opus 4.6 <[email protected]> * docs: add implementation plan for admin circuit breaker status * fix: syntax error in reset button onclick handler --------- Co-authored-by: Claude Opus 4.6 <[email protected]> * update: don't cooldown when there is only one provider in there * fix: implement thinking signature rectification for primary Anthropic API (#19) * feat: refact admin page (#21) * request_idrequest_id * fix: correct login redirect path to /admin/login (#22) * feat: implement provider retry mechanism with exponential backoff - Add `retry` field to ProviderConfig in types - Implement retry loop in `src/utils/provider.ts` for network and 5xx errors - Add retry configuration UI to Admin Panel provider modal - Exclude 4xx/429 errors from retry logic - Add exponential backoff (500ms * 2^attempt) Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: apply signature rectification in safety valve mechanism When the safety valve is triggered (all providers in cooldown), the request was bypassing the thinking signature rectification logic. This caused 400 Invalid Signature errors to persist even when using the safety valve. This change adds the rectification logic to the safety valve execution path, ensuring that invalid thinking blocks are removed before retrying the request. * test: add test case for safety valve signature rectification * fix: prevent binary garbage in logs by stripping accept-encoding header Updates request handling to remove the 'accept-encoding' header before forwarding requests to upstream providers. This ensures that the runtime handles compression negotiation automatically, preventing issues where the worker receives compressed error responses (like 403s) and logs them as binary garbage. Changes: - Added `cleanRequestHeaders` in `src/utils/headers.ts` to filter unsafe headers including `accept-encoding`. - Updated `src/index.ts` to use `cleanRequestHeaders` for primary and fallback requests. - Updated `src/utils/provider.ts` to exclude `accept-encoding` and use `cleanHeaders` for error responses. - Updated `src/admin.ts` to strip unsafe headers in provider testing. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: strip cch parameter from billing header to improve caching The x-anthropic-billing-header system message contains a 'cch' parameter that changes with every request, preventing effective prompt caching. This change strips that parameter while preserving the rest of the header. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: increase rectifier retry timeout and fallback on timeout Rectifier retry was using 30s timeout which was too short for large request bodies after stripping thinking blocks. When timeout occurred, the original 400 error was returned directly instead of trying fallback providers. Now uses 120s timeout and sets status to 504 on timeout so the request continues to fallback providers. Co-Authored-By: Claude Opus 4.6 <[email protected]> * chore: update CLAUDE.md * stop tracking .dev.vars * stop tracking .dev.vars * chore: add debug log * docs: update README with new features (rectifier, OpenAI format, admin panel, observability) Co-Authored-By: Claude Opus 4.6 <[email protected]> * feat(rectifier): add tool-use concurrency rectifier (RECT-003) Auto-detect orphaned tool_use blocks missing corresponding tool_result and inject dummy error tool_result to unblock the request. Integrated into primary, safety valve, and fallback provider flows. Also unify debug-skip header filtering (x-ccf-* prefix) and add error snippet to failure logs. Co-Authored-By: Claude Opus 4.6 <[email protected]> * ci: auto create github release on tag * test: add config coverage for rectifier and admin flags * chore: trigger PR head refresh --------- Co-authored-by: Claude Haiku 4.5 <[email protected]>
1 parent 56a403b commit dab4dcf

91 files changed

Lines changed: 18071 additions & 1778 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/wt.toml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Worktrunk Project Configuration
2+
# Copy to: <repo>/.config/wt.toml
3+
#
4+
# Project-specific hooks that run automatically during worktree operations.
5+
# Check this file into git to share hooks across all developers.
6+
7+
# ============================================================================
8+
# Hook Formats
9+
# ============================================================================
10+
# All hooks support two formats:
11+
#
12+
# Single command:
13+
# post-create = "npm install"
14+
#
15+
# Named table (multiple commands):
16+
# [post-create]
17+
# deps = "npm install"
18+
# build = "npm run build"
19+
#
20+
# Named commands appear in output, making it easier to identify failures.
21+
22+
# ============================================================================
23+
# Template Variables — see https://worktrunk.dev/hook/#template-variables
24+
# ============================================================================
25+
# Common variables:
26+
# {{ repo }} - Repository directory name (e.g., "myproject")
27+
# {{ branch }} - Branch name (e.g., "feature/auth")
28+
# {{ worktree_path }} - Absolute path to worktree
29+
# {{ primary_worktree_path }} - Main worktree (or default branch worktree for bare repos)
30+
# {{ default_branch }} - Default branch name (e.g., "main")
31+
# {{ target }} - Target branch (merge hooks only)
32+
#
33+
# Filters:
34+
# {{ branch | sanitize }} - Replace / and \ with - (e.g., "feature-auth")
35+
# {{ branch | sanitize_db }} - Database-safe identifier with hash suffix (e.g., "feature_auth_x7k")
36+
# {{ branch | hash_port }} - Deterministic port 10000-19999
37+
38+
# ============================================================================
39+
# Hooks
40+
# ============================================================================
41+
42+
# Post-Create: Runs after worktree creation, BLOCKS until complete
43+
# Use for: installing dependencies, setting up databases, copying configs
44+
#
45+
# [post-create]
46+
# deps = "npm ci"
47+
# env = "cp .env.example .env"
48+
49+
# Post-Start: Runs in BACKGROUND after worktree creation (parallel)
50+
# Use for: dev servers, file watchers, background builds
51+
# Output logged to .git/wt-logs/{branch}-project-post-start-{name}.log
52+
#
53+
# [post-start]
54+
# server = "npm run dev -- --port {{ branch | hash_port }}"
55+
# watch = "npm run watch"
56+
57+
# Post-Switch: Runs in BACKGROUND after every switch (parallel)
58+
# Use for: terminal tab naming, tmux window titles, IDE notifications
59+
#
60+
# post-switch = "echo -ne '\\033]0;{{ branch }}\\007'"
61+
62+
# Pre-Commit: Runs before committing during merge, BLOCKS (fail-fast)
63+
# Use for: formatters, linters, quick checks
64+
#
65+
# [pre-commit]
66+
# format = "npm run format:check"
67+
# lint = "npm run lint"
68+
69+
# Pre-Merge: Runs before merging to target, BLOCKS (fail-fast)
70+
# Use for: tests, build verification
71+
#
72+
# [pre-merge]
73+
# test = "npm test"
74+
# build = "npm run build"
75+
76+
# Post-Merge: Runs after successful merge, BLOCKS
77+
# Use for: deployment, notifications
78+
#
79+
# post-merge = "echo 'Merged {{ branch }} to {{ target }}'"
80+
81+
# Pre-Remove: Runs before worktree removal, BLOCKS (fail-fast)
82+
# Use for: cleanup, stopping services
83+
#
84+
# pre-remove = "docker compose down"
85+
86+
# ============================================================================
87+
# Dev Server URL (shown in `wt list`)
88+
# ============================================================================
89+
# [list]
90+
# url = "http://localhost:{{ branch | hash_port }}"
91+
92+
# ============================================================================
93+
# CI Platform Override
94+
# ============================================================================
95+
# Override CI platform detection for GitHub Enterprise or self-hosted GitLab
96+
# with custom domains where URL detection fails.
97+
#
98+
# [ci]
99+
# platform = "github" # or "gitlab"
100+
[post-start]
101+
copy = "wt step copy-ignored"
102+
server = "npm run dev -- --port {{ branch | hash_port }}"

.github/workflows/release.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Create GitHub Release
16+
uses: softprops/action-gh-release@v2
17+
with:
18+
generate_release_notes: true

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ logs.db
77
providers.yaml
88
.claude/
99
.env
10-
.wrangler/
10+
.wrangler/
11+
.dev.vars

CLAUDE.md

Lines changed: 79 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
55
## Commands
66

77
- **Dev**: `npm run dev` (runs Wrangler local dev server on port 8787)
8-
- **Deploy**: `npm run deploy` (deploys to Cloudflare Workers)
8+
- **Build Frontend**: `npm run build:frontend` (builds the React frontend and embeds it into the Worker)
9+
- **Deploy**: `npm run deploy` (builds frontend and deploys to Cloudflare Workers)
910
- **Type Check**: `npx tsc --noEmit`
1011
- **Tail Logs**: `npm run tail` (streams production logs from Cloudflare)
1112
- **Set Secrets**: `npx wrangler secret put ADMIN_TOKEN` (set authentication token)
@@ -15,56 +16,82 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1516

1617
## Architecture
1718

18-
Cloudflare Workers-based fallback proxy for Claude Code. Intercepts Anthropic API requests and routes to alternative providers when the primary API returns 401, 403, 429, or 5xx errors. Provider configuration is stored in Cloudflare KV and managed via web-based admin panel.
19+
Cloudflare Workers-based fallback proxy for Claude Code. Intercepts Anthropic API requests and routes to alternative providers when the primary API returns 401, 403, 429, or 5xx errors.
20+
21+
The Admin Panel is built as a **Single Page Application (SPA)** using React, Vite, and Tailwind CSS. It is bundled into a single HTML file and embedded directly into the Worker logic, allowing for a zero-dependency deployment (no separate asset storage required).
22+
23+
Implements a **Sliding Window Circuit Breaker (Plan C)** to track provider health and prevent cascading failures.
24+
- **State Storage**: `provider-state:{name}` in KV (JSON format).
25+
- **Tiered Cooldowns**: 0s (<3 failures), 30s (<5 failures), 60s (<10 failures), 300s (10+ failures).
26+
- **Safety Valve**: If all providers are in cooldown, the one with the earliest expiry is tried to prevent total service outage.
1927

2028
### Core Components
2129

2230
- **`src/index.ts`** — Main Worker entry point. Hono app with routes for `/` (health check), `/v1/messages` (proxy), and `/admin/*` (management).
23-
- **`src/admin.ts`** — Admin panel and API handlers. Provides HTML UI for managing providers, handles token authentication, and KV storage operations.
24-
- **`src/config.ts`** — KV-based configuration loading and saving. Reads provider configuration from Cloudflare KV.
25-
- **`src/types.ts`** — TypeScript interfaces for provider config, app config, and Worker bindings (KV, ADMIN_TOKEN, DEBUG).
26-
- **`src/utils/provider.ts`** — Implements provider request logic with model mapping, header filtering, and custom auth.
27-
- **`src/utils/headers.ts`** — Utilities for filtering and cleaning HTTP headers for safe forwarding.
31+
- **`src/admin.ts`** — Admin panel and API handlers. Serves the React SPA (`ADMIN_HTML`) and handles API requests.
32+
- **`src/config.ts`** — KV-based configuration loading and saving.
33+
- **`src/utils/circuit-breaker.ts`** — Sliding window circuit breaker implementation with tiered backoff.
34+
- **`src/types.ts`** — TypeScript interfaces for `ProviderConfig`, `AppConfig`, `ProviderState`, and bindings.
35+
- **`src/utils/provider.ts`** — Implements provider request logic with model mapping and header filtering.
36+
- **`src/utils/rectifier/`** — Request rectification module. Auto-fixes incompatible requests (e.g., invalid thinking signatures, budget issues) and retries.
37+
- `thinking-signature.ts` — Detects and strips invalid `thinking`/`redacted_thinking` blocks and `signature` fields.
38+
- `thinking-budget.ts` — Detects and adjusts `budget_tokens`/`max_tokens` values.
39+
- **`frontend/`** — React source code for the admin panel.
40+
- **`scripts/build-frontend.sh`** — Builds the frontend and embeds it into `src/admin-html.ts`.
2841

2942
### Fallback Logic
3043

3144
1. Try primary Anthropic API (`https://api.anthropic.com/v1/messages`)
32-
2. On 401, 403, 429, or 5xx errors → iterate through configured fallback providers
33-
3. Return first successful response or last error
45+
2. On 400 errors: **Rectifier** auto-detects thinking signature / budget issues, strips problematic blocks, and retries with 120s timeout. If rectifier retry also fails/times out, continues to fallback providers.
46+
3. On 401, 403, 429, or 5xx errors:
47+
- Check circuit breaker state for each provider.
48+
- Skip providers currently in cooldown.
49+
- Iterate through available providers in configured order.
50+
- If all providers in cooldown, trigger **Safety Valve** (try least recently failed).
51+
4. Return first successful response or last error.
3452

3553
### KV Configuration
3654

37-
Provider configs are stored as JSON array in Cloudflare KV namespace `CONFIG_KV` under key `providers`:
38-
39-
```json
40-
[
41-
{
42-
"name": "openrouter",
43-
"baseUrl": "https://openrouter.ai/api/v1/chat/completions",
44-
"apiKey": "sk-...",
45-
"authHeader": "Authorization",
46-
"modelMapping": {
47-
"claude-sonnet-4-5-20250929": "anthropic/claude-sonnet-4"
48-
}
49-
}
50-
]
51-
```
55+
1. **Provider Configs** (`providers` key):
56+
```json
57+
[
58+
{
59+
"name": "openrouter",
60+
"baseUrl": "https://openrouter.ai/api/v1/chat/completions",
61+
"apiKey": "sk-...",
62+
"authHeader": "Authorization",
63+
"modelMapping": {
64+
"claude-sonnet-4-5-20250929": "anthropic/claude-sonnet-4"
65+
}
66+
}
67+
]
68+
```
69+
70+
2. **Provider State** (`provider-state:{name}` keys):
71+
```json
72+
{
73+
"consecutiveFailures": 0,
74+
"lastFailure": null,
75+
"lastSuccess": 1715432100000,
76+
"cooldownUntil": null
77+
}
78+
```
5279

5380
## Configuration
5481

5582
### Environment Variables
5683

57-
- **`ADMIN_TOKEN`** (required) — Secret token for protecting admin panel. Set via Cloudflare Dashboard or `wrangler secret put`.
84+
- **`ADMIN_TOKEN`** (required) — Secret token for protecting admin panel.
5885
- **`DEBUG`** (optional, default: `false`) — Enable debug logging.
5986

6087
### KV Namespace
6188

62-
- **`CONFIG_KV`** — Binding to Cloudflare KV namespace storing provider configurations.
89+
- **`CONFIG_KV`** — Binding to Cloudflare KV namespace storing provider configurations and circuit breaker state.
6390

6491
### wrangler.jsonc
6592

6693
Main configuration file. Contains:
67-
- KV namespace binding (requires namespace id from `npx wrangler kv:namespace create CONFIG`)
94+
- KV namespace binding (requires namespace id)
6895
- Environment variables
6996
- Development port (8787)
7097

@@ -74,15 +101,27 @@ Access at: `https://your-worker.workers.dev/admin?token=YOUR_ADMIN_TOKEN`
74101

75102
Features:
76103
- **Visual Editor**: Add/edit/delete providers with form UI
77-
- **JSON Editor**: Direct JSON editing for advanced users
78-
- **Real-time Save**: Changes persist immediately to KV
79-
- **Token Authentication**: Secured with `ADMIN_TOKEN` environment variable
104+
- **JSON Editor**: Direct JSON editing
105+
- **Circuit Breaker Settings**: Configure max cooldown duration
106+
- **Token Authentication**: Secured with `ADMIN_TOKEN`
107+
108+
## Observability
80109

81-
### API Endpoints
110+
The proxy outputs **structured JSON logs** with Request ID tracking for full observability. See [docs/observability.md](./docs/observability.md) for details.
82111

83-
- `GET /admin` — Admin panel UI (requires token)
84-
- `GET /admin/config` — Get current provider config as JSON (requires token)
85-
- `POST /admin/config` — Update provider config (requires token, expects JSON array)
112+
**Quick Start:**
113+
```bash
114+
# View real-time logs
115+
npm run tail
116+
117+
# Logs are automatically collected in: Dashboard → Observability
118+
```
119+
120+
Every log includes:
121+
- Unique `requestId` for tracing requests end-to-end
122+
- `event` type (e.g., `provider.success`, `provider.failure`)
123+
- Performance metrics (`latency`, `status`)
124+
- Provider and model information
86125

87126
## Deployment Workflow
88127

@@ -108,15 +147,6 @@ Features:
108147
https://your-worker.workers.dev/admin?token=YOUR_TOKEN
109148
```
110149

111-
## Local Development
112-
113-
```bash
114-
npm run dev
115-
# Visit http://localhost:8787/admin?token=123456 (default token in wrangler.jsonc)
116-
```
117-
118-
When running locally with `npx wrangler kv:namespace create CONFIG --preview`, you can test KV operations with preview binding.
119-
120150
## Provider Configuration
121151

122152
Each provider requires:
@@ -129,33 +159,20 @@ Optional fields:
129159
- **`headers`** — Additional custom headers
130160
- **`modelMapping`** — Map model names (e.g., `claude-3-opus-20240229``openai/gpt-4`)
131161

132-
## Type System
133-
134-
Main types in `src/types.ts`:
135-
- `ProviderConfig` — Single provider configuration
136-
- `AppConfig` — Runtime config with debug flag and provider list
137-
- `Bindings` — Worker environment bindings (DEBUG, ADMIN_TOKEN, CONFIG_KV)
138-
139162
## Testing
140163

141-
The project has a comprehensive test suite with 142 tests and 99%+ coverage.
164+
The project has a comprehensive test suite with **367 tests**.
142165

143166
### Test Structure
144167

145168
```
146169
src/__tests__/
147170
fixtures/ # Test data and mock responses
148-
providers.ts # Provider configurations
149-
requests.ts # API request/response fixtures
150-
mocks/ # Mock implementations
151-
kv.ts # Mock KV namespace
152-
fetch.ts # Mock fetch utilities
153-
utils/ # Unit tests for utilities
154-
headers.test.ts
155-
provider.test.ts
156-
config.test.ts # Config module tests
157-
admin.test.ts # Admin panel tests
158-
index.test.ts # Integration tests
171+
mocks/ # Mock KV and fetch implementations
172+
utils/ # Unit tests (headers, provider, circuit-breaker, rectifier)
173+
config.test.ts # Config module tests
174+
admin.test.ts # Admin panel tests
175+
index.test.ts # Integration tests
159176
```
160177

161178
### Running Tests
@@ -170,34 +187,3 @@ npm run test:watch
170187
# Run with coverage report
171188
npm run test:coverage
172189
```
173-
174-
### Test Coverage
175-
176-
The test suite maintains high coverage across all modules:
177-
- **Statements**: 99.28%
178-
- **Branches**: 98.48%
179-
- **Functions**: 94.73%
180-
- **Lines**: 100%
181-
182-
Coverage thresholds are enforced at 80% for all metrics.
183-
184-
### Writing Tests
185-
186-
Tests use Vitest with Cloudflare Workers pool for accurate Workers environment simulation:
187-
188-
```typescript
189-
import { describe, it, expect } from 'vitest';
190-
import { createMockBindings } from './__tests__/mocks/kv';
191-
192-
describe('my feature', () => {
193-
it('should work correctly', async () => {
194-
const env = createMockBindings();
195-
// Test implementation
196-
});
197-
});
198-
```
199-
200-
Key testing utilities:
201-
- `createMockBindings()` — Creates mock Worker bindings (KV, env vars)
202-
- `createMockResponse()` — Creates mock Response objects
203-
- Test fixtures in `__tests__/fixtures/` — Reusable test data

0 commit comments

Comments
 (0)