# Build an integration console

Run this integration code on the server unless the example explicitly mounts a browser button. `tokenVault`, `savePendingOAuthState`, `loadQentrahSession`, and event callbacks are application integration points, not exports supplied by the SDK. Implement them with your storage and user-session model.

## Headless Integration Harness

The harness gives you reusable data models for a developer console without forcing a React component or a specific app layout.

```ts
import {
  createQentrahPartnerConsoleService,
  qentrahPartnerSections,
} from "@qentrah/auth-sdk/partner/harness";

const consoleService = createQentrahPartnerConsoleService({
  workspaceBaseUrl: process.env.QENTRAH_WORKSPACE_BASE_URL!,
  redirectUri: process.env.QENTRAH_PARTNER_REDIRECT_URI!,
  requestedScopes: ["organization:read", "client:read", "client:create"],
  session: await loadQentrahSession(userId),
});

const sections = consoleService.sections();
const lifecycle = consoleService.lifecycle();
const credentialSnapshot = consoleService.credentials();
const clientsQuery = consoleService.searchParams("clients", {
  limit: 25,
  search: "Acme",
  status: "active",
});
```

The harness can:

- Return the available console sections and the scopes each section needs.
- Detect missing scopes and reauthorization needs.
- Build OAuth lifecycle metadata for docs or UI.
- Build query parameters for list filters.
- Convert API responses into compact render rows.
- Normalize operation results for Test Results views.
- Sanitize nested payloads before rendering them.

Example rendering flow:

```ts
const result = await consoleService.runResourceOperation({
  sectionId: "clients",
  operation: "read",
  resource: "client",
  options: { limit: 25, search: "Acme" },
});

const rows = consoleService.renderRows("clients", result.responseSummary);
const safeResult = consoleService.result({
  sectionId: "clients",
  operation: "read",
  method: "GET",
  path: "/api/qentrah/clients",
  status: result.status,
  response: result.responseSummary,
  error: result.error,
});
```

Render `rows`, `sections`, `lifecycle`, `credentialSnapshot`, and `safeResult` with your own UI framework.

## WordPress And Server-Backed Apps

For WordPress or PHP-backed products, keep the same separation of responsibilities:

- Enqueue the browser button script in the admin screen or integration settings page.
- Point the button at a server route that starts OAuth.
- Store pending OAuth state in a server-side session or database table.
- Complete the callback on the server and save token data in encrypted storage.
- Proxy Qentrah resource calls through server endpoints.
- Render only sanitized connection status, section readiness, request summaries, and result summaries in the admin UI.

If your WordPress plugin uses a Node service or build step, you can use this package directly in that server layer. If your backend is pure PHP, mirror the same OAuth, webhook, and storage contract server-side, and use the browser bundle only for the connect button.