# Backend Integration Details

Last Updated: 2026-08-19

This is the current plugin-side integration contract. Historical CloudPanel/Apache `/v1` deployment notes and license-key/PayPal onboarding are retired and MUST NOT be used as implementation guidance. Backend deployment itself is owned by the backend project/lane.

## Production architecture

- Public API origin: `https://api.press.zone` unless the plugin's supported backend-base override is explicitly configured.
- Runtime API: Cloudflare Worker.
- Account/onboarding: Connect authorization + social identity + Stripe.
- Site authentication: one backend-issued API credential per connected WordPress site, stored encrypted by `includes/Connect/CredentialStore.php`. The browser never receives or renders this credential.
- Retired: license keys, `ActivationManager`/`LicenseClient`/`LicenseValidator`, password onboarding, PayPal onboarding, CloudPanel-era `/v1` translation routes, and JobReceiver/JobSender callback delivery.

## Connect flow

Plugin-side REST namespace: `international-press-zone/v1/connect`.

Server-side `includes/Connect/ConnectService.php` owns the Worker exchange:

1. `begin_connect()` creates OAuth state + PKCE verifier and sends the administrator to `{backend}/connect`.
2. `complete_connect()` exchanges the authorization code at `POST {backend}/oauth/token`.
3. The successful exchange returns the site API credential and site identity in the response envelope; `CredentialStore` encrypts/persists them server-side.
4. Authenticated account operations use `Authorization: Bearer <site-api-key>`.
5. `GET {backend}/api/connect/status` refreshes subscription/site state; a Worker `401` purges the unusable local credential.
6. Disconnect uses `POST {backend}/api/connect/disconnect`; billing cancellation is separate.

The Account UI is `admin/src/pages/account.js`. It exposes Connect/status/checkout/portal/disconnect actions, never a credential field.

## Translation data plane

`includes/Integration/TranslationAPI.php` is authoritative for plugin requests:

- sync translation: `POST /api/plugin/international`
- async/bulk submit: `POST /api/plugin/international/jobs`
- async lifecycle: poll/finalize/cancel through the current Worker job contract

Requests carry the connected-site bearer credential plus plugin/version/site headers. Stable idempotency keys must be preserved across retries. Do not add old callback endpoints.

`TranslationAPI::isAvailable()` intentionally means that a connected-site credential exists. An E2E stack that has no provisioned Connect credential must fail this availability check; tests must provision a valid credential rather than bypassing the runtime gate.

## E2E

All WordPress/browser integration runs through the canonical remote mechanism in `.claude/skills/ipz-e2e.md`. Never run Playwright, WordPress containers, dependency builds, or browser diagnostics locally.

Real integration evidence must distinguish:

- UI-only Connect tests with mocked REST;
- isolated WordPress tests with a server-side provisioned credential;
- true real-Worker tests where the credential was issued by the current backend and translation/job requests reach the Worker.

Never print site API keys, OAuth codes/verifiers, Stripe secrets, or bearer values in commands, logs, test output, screenshots, or browser-visible fixtures.

## Source of truth

For plugin behavior, prefer current code and `docs/specs/2026-08-15-translation-data-plane-design.md` plus the Connect implementation/plan. Do not infer the current Worker from the checked-in legacy `press-zone-backend/` implementation.
