# `@alvera-ai/platform-sdk`

Typed TypeScript SDK for the Alvera platform API — manage datalakes, data
sources, tools, AI agents, interoperability contracts, data activation clients,
workflows, and more, all from a single typed client.

## Install

```sh
npm install @alvera-ai/platform-sdk
# or: pnpm add / bun add / yarn add @alvera-ai/platform-sdk
```

## Quick start

Authentication is two steps — mint a session, then build a typed client:

```ts
import {
  createSession,
  createIsolatedPlatformApi,
  type PlatformApi,
} from '@alvera-ai/platform-sdk'

// 1. mint a session (pass tenantSlug to scope it to a tenant)
const session = await createSession({
  baseUrl: 'https://api.alvera.ai',
  email,
  password,
  tenantSlug,
})

// 2. build a typed client
const api: PlatformApi = createIsolatedPlatformApi({
  baseUrl: 'https://api.alvera.ai',
  sessionToken: session.sessionToken,
})

// 3. call resources — every nested resource is tenant + datalake scoped
const { data: datalake } = await api.datalakes.create(tenantSlug, {
  name: 'Production Lake',
  type: 'raw',
  // …db_reader_* / db_writer_* + cloud_storage credentials…
})

const { data, meta } = await api.tools.list(tenantSlug, datalake.slug)
```

### Session scopes

`createSession` mints one of three scopes:

- **root** — Alvera root admin (user signup + confirmation).
- **tenantless** — an authenticated user with no tenant yet; used once to create
  a tenant, or to accept an invitation. Omit `tenantSlug`.
- **tenant-scoped** — the canonical bearer for tenant operations. Pass
  `tenantSlug`.

Holding more than one client in the same process (e.g. a test or an app serving
multiple users)? Use `createIsolatedPlatformApi` — it builds a fresh, private
client. `createPlatformApi` mutates a shared singleton and is only safe for a
single bearer.

### A few things to know

- **`update()` replaces the whole resource** — there is no partial update; send
  the full body.
- **List endpoints return `{ data, meta }`** — destructure, don't iterate the
  response directly.
- **Slugs are server-derived** — read `slug` off a `create()` response; never
  pre-compute it.
- **The SDK validates nothing client-side** — a bad body comes back as a thrown
  `422 AlveraApiError` with a `source.pointer` to the offending field.

## TypeScript configuration

The SDK uses [`@hey-api/client-fetch`](https://heyapi.dev/openapi-ts/clients/fetch),
whose generated code references WHATWG fetch types — `BodyInit`, `RequestInit`,
`Headers`, `FormData`, etc. Those names live in `lib.dom.d.ts`, not
`@types/node`, so a Node-only consumer with `"lib": ["ES2022"]` in its
`tsconfig.json` will see errors like `Cannot find name 'BodyInit'` when
typechecking.

The fix is to add `DOM` and `DOM.Iterable` to your `lib`:

```jsonc
// tsconfig.json
{
  "compilerOptions": {
    "lib": ["ES2022", "DOM", "DOM.Iterable"]
    //               ^^^^^^^^^^^^^^^^^^^^^^^
    // Required by @hey-api/client-fetch — see hey-api/openapi-ts#2539.
    // Type-only: adds NOTHING to the runtime — Node 18+ provides real
    // fetch independently of these declarations.
  }
}
```

This is the workaround for hey-api's open issue
[#2539](https://github.com/hey-api/openapi-ts/issues/2539); drop the `DOM`
entries again once the upstream fix emits self-contained types. Browser
consumers (React, Vue, Next, Nuxt, Remix) already enable `DOM` /
`DOM.Iterable` by default — no change needed.

## Environments

Base URLs ship with the package, derived at build time from the `servers[]`
block of the committed OpenAPI spec and exported as `ENVIRONMENTS`:

```ts
import { ENVIRONMENTS, DEFAULT_ENVIRONMENT } from '@alvera-ai/platform-sdk'

ENVIRONMENTS.local.base_url // http://localhost:4000
ENVIRONMENTS.demo.base_url  // https://demo.alvera.ai
ENVIRONMENTS.prod.base_url  // https://app.alvera.ai

DEFAULT_ENVIRONMENT // 'prod'
```

Pass the chosen `base_url` into `createSession` and `createIsolatedPlatformApi`.

## Resources

Every resource is a typed namespace on the client (`api.<resource>.<verb>`):

| Resource                     | Operations                                                                                                                                  |
|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `ping`                       | health check                                                                                                                                |
| `sessions`                   | `verify`                                                                                                                                     |
| `auth`                       | `signUp`                                                                                                                                     |
| `admin`                      | `confirmUser`                                                                                                                                |
| `tenants`                    | `list`, `create`                                                                                                                             |
| `invitations`                | `list`, `create`, `accept`                                                                                                                   |
| `datasets`                   | `search`, `metadata`, `createUserSearch`                                                                                                     |
| `datalakes`                  | `list`, `get`, `create`, `metadata`, `migrate`, `createUploadLink`, `createDownloadLink`, `textToSql`, `executeSql`                          |
| `dataSources`                | `list`, `create`, `update`                                                                                                                   |
| `tools`                      | `list`, `get`, `create`, `update`, `delete`, `testInvocation`                                                                                |
| `genericTables`              | `list`, `create`                                                                                                                             |
| `actionStatusUpdaters`       | `list`, `create`, `update`                                                                                                                   |
| `aiAgents`                   | `list`, `get`, `create`, `update`, `delete`, `invoke`                                                                                        |
| `authenticatedLinks`         | `exchange`, `updateMessageTracking`                                                                                                          |
| `dataActivationClients`      | `list`, `get`, `create`, `update`, `delete`, `metadata`, `runManually`, `ingest`, `ingestFile`, `logs.list`, `logs.get`                      |
| `interoperabilityContracts`  | `list`, `get`, `create`, `update`, `delete`, `metadata`, `run`                                                                               |
| `mdm`                        | `verify`                                                                                                                                     |
| `workflows`                  | `list`, `get`, `create`, `update`, `delete`, `metadata`, `execute`, `run`, `workflowLogs.list/get/download`, `batchLogs.list/get/start/stop/refresh` |

Tenant and datalake provisioning are performed by Alvera admins — contact your
representative to onboard a new tenant.

## For coding agents

This package ships an **agent-docs corpus** under `.agent/` — it lands at
`node_modules/@alvera-ai/platform-sdk/.agent/` after install, and an agent that
walks `node_modules` discovers it automatically. It is self-sufficient for
building an app or a test suite against the SDK:

- [`.agent/AGENTS.md`](./.agent/AGENTS.md) — the index + per-resource reference.
- [`.agent/cookbook/`](./.agent/cookbook/) — validated, runnable recipes:
  business cookbooks (one outcome each) and capability docs (one capability
  each, e.g. `bulk-ingest`, `ai-agent-invoke`, `custom-tables`, `invite-team`).

To wire a pointer to the corpus into your own project's `AGENTS.md` (and a
`@AGENTS.md` import into `CLAUDE.md`), run — no global install needed:

```sh
npx @alvera-ai/platform-sdk llm-export
```

It writes an idempotent managed block; re-running replaces only that block.

## Documentation

- [`.agent/`](./.agent/AGENTS.md) — consumer reference + cookbooks (ships in the package)
- [`docs/sdk-architecture.md`](../../docs/sdk-architecture.md) — the SDK's design

## License

MIT — see [LICENSE](./LICENSE).
