Initial Commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# `@suaveplan/api-tenant-provider-memory` — In-memory TenantProvider
|
||||
|
||||
**Package**: `@suaveplan/api-tenant-provider-memory`
|
||||
**Status**: PROPOSED
|
||||
**Type**: new-package
|
||||
**Stage**: 4 (Base adapters) — see umbrella `openspec/changes/api-plugin-foundation/`
|
||||
|
||||
## Why
|
||||
|
||||
Per design doc §5.4, `perTenant: true` cron jobs require the host to enumerate tenants. `tenant.provider` is the capability that exposes that enumeration. Shipping a v1 in-memory reference implementation matters for two reasons:
|
||||
|
||||
1. It pins the contract — every later DB-backed adapter (Stage 8 or later) implements the same `TenantProvider` interface, so retrofitting tenant enumeration into a stable contract doesn't have to happen later (§5.4 last sentence).
|
||||
2. It's the default for the testing kit (`createTestHost` Stage 5) and for any deployment whose tenant list is small + static.
|
||||
|
||||
The provider returns an iterable/async-iterable of `TenantContext`. Designed to be both production-grade for static deployments AND a reference for the more elaborate Stage-8 DB-backed adapter.
|
||||
|
||||
Stage 4 invariant: ships direct AND worker-proxy surfaces; both pass `runTenantProviderConformance` (§5.2a, §13.4). (Conformance suite is owned by `api-conformance-suites` this stage.)
|
||||
|
||||
## What changes
|
||||
|
||||
Net-new package depending on `@suaveplan/api-tenant-provider` (contract), `@suaveplan/api-types`, `@suaveplan/api-worker-rpc`, `@suaveplan/error`, `zod`.
|
||||
|
||||
- ADDED: `createMemoryTenantProvider(opts)` — direct-surface factory returning a `TenantProvider`.
|
||||
- ADDED: `createMemoryTenantProviderWorkerProxy(port, opts)` — proxy-surface factory.
|
||||
- ADDED: `MemoryTenantProviderOptions` — Zod schema with `tenants: TenantContext[]` (initial set), `mutable: boolean` (default true — allow runtime `add`/`remove`/`update`).
|
||||
- ADDED: Mutation API (when `mutable: true`): `add(tenant)`, `remove(tenantId)`, `update(tenantId, patch)`.
|
||||
- ADDED: `list()` returns an array snapshot; `listAsync()` returns an `AsyncIterable<TenantContext>` for symmetry with future DB-backed adapter.
|
||||
- ADDED: `get(tenantId)` returns `TenantContext | undefined`.
|
||||
- ADDED: `TENANT_PROVIDER_MEMORY_*` error codes (`TENANT_PROVIDER_MEMORY_DUPLICATE_ID`, `TENANT_PROVIDER_MEMORY_NOT_FOUND`, `TENANT_PROVIDER_MEMORY_IMMUTABLE`, `TENANT_PROVIDER_MEMORY_INVALID_OPTIONS`).
|
||||
|
||||
## Out of scope
|
||||
|
||||
- DB-backed enumeration — Stage 8 (or later) `api-tenant-provider-postgres` / `api-tenant-provider-surrealdb`.
|
||||
- Hierarchical tenants — flat model only at this stage.
|
||||
- Tenant-level feature flags — `@suaveplan/feature-flags` consumes the provider, not the other way round.
|
||||
|
||||
## Source mapping
|
||||
|
||||
Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`.
|
||||
|
||||
| Requirement | Design doc section |
|
||||
|---|---|
|
||||
| `tenant.provider` ships in v1 | §5.4 |
|
||||
| In-memory reference impl | §5.4 |
|
||||
| Worker-proxy variant | §5.2a |
|
||||
| Conformance both surfaces | §13.4 |
|
||||
|
||||
## Verification approach
|
||||
|
||||
- `src/factory/create-memory-tenant-provider.test.ts` — list, get, mutation, duplicate-id rejection, immutability when `mutable: false`.
|
||||
- `src/factory/create-memory-tenant-provider.spec-conformance.test.ts` — `runTenantProviderConformance("memory-direct", ...)`.
|
||||
- `src/proxy/create-memory-tenant-provider-worker-proxy.test.ts` — proxy unit tests; async iteration across MessagePort.
|
||||
- `src/proxy/create-memory-tenant-provider-worker-proxy.spec-conformance.test.ts` — `runTenantProviderConformance("memory-worker-proxy", ...)`.
|
||||
|
||||
## Migration impact
|
||||
|
||||
None — additive only.
|
||||
Reference in New Issue
Block a user