Description
Replace the extension's direct provider calls with calls to the deployed backend proxy. Today app/src/lib/openai.ts calls OpenAI from the browser (dangerouslyAllowBrowser: true) with a dev-only proxy at /api/openai. The production proxy now exists and is live: POST /ai/generate (staging https://optia-backend-staging.paul-130.workers.dev, production https://api.optia-api.com) — entitlement-gated, metered, served by Anthropic (claude-haiku-4-5), response shape { checkId, recommendation, model, quota }.
Split out of the #7 audit: #7 covered the server side and is closed; #8/#9/#12 imply this switch but none owns it. This issue owns it.
Why
The free tier only works if the provider key stays server-side, and metering is only enforceable at the proxy — a client still calling the provider directly bypasses both. This is the single networking change the entitlement layer (#8), gating (#9), and paywall (#10) all sit on top of.
Acceptance Criteria
Resources
Description
Replace the extension's direct provider calls with calls to the deployed backend proxy. Today
app/src/lib/openai.tscalls OpenAI from the browser (dangerouslyAllowBrowser: true) with a dev-only proxy at/api/openai. The production proxy now exists and is live:POST /ai/generate(staginghttps://optia-backend-staging.paul-130.workers.dev, productionhttps://api.optia-api.com) — entitlement-gated, metered, served by Anthropic (claude-haiku-4-5), response shape{ checkId, recommendation, model, quota }.Split out of the #7 audit: #7 covered the server side and is closed; #8/#9/#12 imply this switch but none owns it. This issue owns it.
Why
The free tier only works if the provider key stays server-side, and metering is only enforceable at the proxy — a client still calling the provider directly bypasses both. This is the single networking change the entitlement layer (#8), gating (#9), and paywall (#10) all sit on top of.
Acceptance Criteria
POST {API_BASE}/ai/generatewith{ checkId, keyword, context, installId? }— no direct provider call and nodangerouslyAllowBrowserin hosted modeX-Optia-Entitlementheader; free installs sendinstallIdonlyAPI_BASEconfigurable per build target (staging/production), never localhost in release buildsquotafrom the response feeds the entitlement layer'saiQuotaRemaining(Add client-side entitlement layer and feature-flag system #8)429 QUOTA_EXCEEDED→ over-quota upgrade prompt (Build paywall and upgrade UI in the side panel #10);429 RATE_LIMITED→ retry-later message;401→ entitlement refresh, one retry;502 UPSTREAM_ERROR→ friendly provider-error message (no dead ends)Authorizationpassthrough is removed (PMDevSolutions/optia-backend#17), so hosted-mode requests never send anAuthorizationheader; a Pro user's own Anthropic key goes straight from the extension to the provider (Retain bring-your-own Anthropic key as a Pro option #12). Product is Anthropic-only — no OpenAIResources
app/src/lib/openai.ts(current direct client),app/src/lib/storage.tssrc/routes/ai.tsandsrc/types/index.ts(aiGenerateSchema) inPMDevSolutions/optia-backend