3.0 KiB
3.0 KiB
OpenSpec Change: enterprise-api-plugin-tenant
- Change ID: enterprise-api-plugin-tenant
- Package:
@suaveplan/api-plugin-tenant - Category: api/auth
- Target path:
api/auth/api-plugin-tenant - Status: PROPOSED
- Date: 2026-04-24
Summary
Deliver @suaveplan/api-plugin-tenant on the genesis branch from scratch at enterprise quality. The plugin provides multi-tenant management: tenant provisioning (create/update/suspend/delete), member invitation and role management, per-tenant feature flag overrides via @suaveplan/feature-flags, per-tenant settings/branding, and a tenant-scoped audit trail. Routes mounted under /tenants. Events: tenant:created, tenant:suspended, tenant:deleted, tenant:member:invited, tenant:member:removed.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/api (workspace:^) |
definePlugin |
@suaveplan/api-shared (workspace:^) |
Helpers |
@suaveplan/api-plugin-auth (workspace:^) |
requireAuth, requireRole |
@suaveplan/api-plugin-database (workspace:^) |
SurrealDB |
@suaveplan/feature-flags (workspace:^) |
Per-tenant flag overrides |
@suaveplan/audit-logging (workspace:^) |
Tenant audit trail |
@suaveplan/events (workspace:^) |
Event bus |
@suaveplan/error (workspace:^) |
TenantError hierarchy |
@suaveplan/rate-limiter (workspace:^) |
Rate limits |
hono + @hono/zod-openapi + zod |
Routes/schemas |
@opentelemetry/api |
OTel |
Public API surface
function createTenantPlugin(config?: TenantPluginConfig): PluginDescriptor<TenantPluginConfig>
class TenantService {
createTenant(data: CreateTenantInput): Promise<Tenant>
getTenant(id: string): Promise<Tenant>
updateTenant(id: string, data: UpdateTenantInput): Promise<Tenant>
suspendTenant(id: string, reason: string): Promise<void>
deleteTenant(id: string): Promise<void>
inviteMember(tenantId: string, email: string, role: string): Promise<TenantInvite>
acceptInvite(token: string): Promise<void>
removeMember(tenantId: string, userId: string): Promise<void>
listMembers(tenantId: string): Promise<TenantMember[]>
getSettings(tenantId: string): Promise<TenantSettings>
updateSettings(tenantId: string, settings: Partial<TenantSettings>): Promise<TenantSettings>
}
Error codes
type TenantErrorCode =
| "TENANT_NOT_FOUND"
| "TENANT_SUSPENDED"
| "TENANT_INVITE_EXPIRED"
| "TENANT_INVITE_INVALID"
| "TENANT_MEMBER_NOT_FOUND"
| "TENANT_MEMBER_ALREADY_EXISTS"
File layout
api/auth/api-plugin-tenant/
package.json tsconfig.json vitest.config.ts
surql/ (tenant, tenant_member, tenant_invite, tenant_settings tables)
src/
index.ts events.ts
types/ errors/
services/tenant/
routes/tenants/
tests/integration.test.ts
Impact
Prerequisites: @suaveplan/api, @suaveplan/api-plugin-auth, @suaveplan/api-plugin-database, @suaveplan/feature-flags, @suaveplan/audit-logging.