# @suaveplan/api-tenant-provider - Abstract `TenantProvider` contract for the Suaveplan API plugin system. Enumerates the universe of tenants known to a host so per-tenant cron / queued jobs (manifest `perTenant: true`) and admin tooling can fan out one invocation per tenant. Ships the interface, the `TenantRecord` Zod schema, the `ListOpts` pagination shape, the `CapabilityId` augmentation contributing `"tenant.provider"`, the frozen `TENANT_PROVIDER_CODES` error registry, and a reusable `runTenantProviderConformance(factory)` harness — no concrete source (in-memory, DB, directory-service adapters land in sibling packages). Abstract `TenantProvider` contract for the Suaveplan API plugin system. Enumerates the universe of tenants known to a host so per-tenant cron / queued jobs (manifest `perTenant: true`) and admin tooling can fan out one invocation per tenant. ## Documentation tree - [capability-id](./src/capability-id/capability-id.md) — `@suaveplan/api-types/capabilities` exports `CapabilityId`, the open union derived from the `CapabilityIdRegistry` inte… - [capability-id](./src/capability-id/capability-id.md) — `@suaveplan/api-types/capabilities` exports `CapabilityId`, the open union derived from the `CapabilityIdRegistry` inte… - [chain](./src/chain/chain.md) — The chain module closes the gap between the inventory-side contract (`TenantProvider`, owned by this package) and the p… - [chain](./src/chain/chain.md) — The chain module closes the gap between the inventory-side contract (`TenantProvider`, owned by this package) and the p… - [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/api-tenant-provider` raises every failure through a single `SuaveplanError` subclass — `TenantProviderError… - [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/api-tenant-provider` raises every failure through a single `SuaveplanError` subclass — `TenantProviderError… - [pagination](./src/pagination/pagination.md) — `TenantProvider.list(opts?)` is `AsyncIterable` — callers iterate one tenant at a time without caring whe… - [pagination](./src/pagination/pagination.md) — `TenantProvider.list(opts?)` is `AsyncIterable` — callers iterate one tenant at a time without caring whe… - [provider](./src/provider/provider.md) — `TenantProvider` is the abstract contract every concrete tenant source implements. The API plugin host consumes it for… - [provider](./src/provider/provider.md) — `TenantProvider` is the abstract contract every concrete tenant source implements. The API plugin host consumes it for… - [tenant-record](./src/tenant-record/tenant-record.md) — A `TenantRecord` is one row from the host's tenant inventory. Every concrete `TenantProvider` — whether it reads from m… - [tenant-record](./src/tenant-record/tenant-record.md) — A `TenantRecord` is one row from the host's tenant inventory. Every concrete `TenantProvider` — whether it reads from m… - [testing](./src/testing/conformance.md) — Every concrete `TenantProvider` — the in-memory reference impl (`api-tenant-provider-memory`, ), the host-DB-bac… - [conformance](./src/testing/conformance.md) — Every concrete `TenantProvider` — the in-memory reference impl (`api-tenant-provider-memory`, ), the host-DB-bac… ## What ships | Subpath | Module | Doc | |---|---|---| | `./provider` | `TenantProvider` interface — `list / count / lookup / dispose` | [`src/provider/provider.md`](src/provider/provider.md) | | `./tenant-record` | `TenantRecord` + `tenantRecordSchema` (strict Zod) | [`src/tenant-record/tenant-record.md`](src/tenant-record/tenant-record.md) | | `./pagination` | `ListOpts`, `encodeCursor` / `decodeCursor` | [`src/pagination/pagination.md`](src/pagination/pagination.md) | | `./capability-id` | `TENANT_PROVIDER_CAPABILITY_ID` + widened `CapabilityId` | [`src/capability-id/capability-id.md`](src/capability-id/capability-id.md) | | `./error-codes` | `TENANT_PROVIDER_CODES` + `TenantProviderError` | [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) | | `./testing` | `runTenantProviderConformance(opts)` | [`src/testing/conformance.md`](src/testing/conformance.md) | ## Out of scope - Concrete sources — `api-tenant-provider-memory` (), DB-backed sources are deployment-specific. - Tenant CREATE / UPDATE / DELETE — that's an admin concern. - Per-request tenant extraction — that's `TenantResolver` in `@suaveplan/api-types/tenant-resolver` + `@suaveplan/api-tenant-resolver-*` adapters. ## Why a separate package `TenantProvider` answers "what tenants does this host know about" — distinct from `TenantResolver`, which answers "which tenant is making this request right now". Both contracts coexist in the api-stack but live in separate packages so adapters depend on the narrower one they need. Per design doc §5.4, the per-tenant job scheduler depends only on `TenantProvider`; HTTP middleware depends only on `TenantResolver`. ## Stage Contracts of the API plugin system umbrella.