Files
2026-05-27 23:29:53 +01:00

3.4 KiB

Tasks — add-api-tenant

1. Scaffold

  • 1.1 Create packages/api/api-tenant/ with src/{types,resolver,cache,context,middleware,rate-limit,lifecycle,storage,error-codes}/ + tests/setup/
  • 1.2 package.json v0.1.0. Deps: @suaveplan/error @suaveplan/api-plugin @suaveplan/events @suaveplan/types tslib, hono (catalog:server), zod (catalog:forms), @opentelemetry/api (catalog:observability). Dev: standard testing set. ~9 subpath exports.
  • 1.3 tsconfig.json + tsconfig.lib.json
  • 1.4 vite.config.ts (externals incl. hono)
  • 1.5 vitest.config.ts (100/100/100/100, forks)
  • 1.6 tests/setup/polyfills.ts

2. Implementation

  • 2.1 src/error-codes.ts + .md + test — 7 TENANT.* codes + TenantError
  • 2.2 src/types/tenant.{ts,md,test.ts,index.ts} — canonical Tenant + status/role/permissions + hasPermission
  • 2.3 src/resolver/resolver.{ts,test.ts,md,index.ts} — 6 resolvers + ChainedTenantResolver
  • 2.4 src/cache/cache.{ts,test.ts,md,index.ts} — TenantCache.wrap(resolver, options) with TTL + negative cache + request coalescing
  • 2.5 src/context/context.{ts,test.ts,md,index.ts} — createTenantContext(tenant); NullTenantContext fail-closed
  • 2.6 src/middleware/middleware.{ts,test.ts,md,index.ts} — createTenantMiddleware, one canonical c.set("tenant"), Hono ContextVariableMap augmentation
  • 2.7 src/middleware/require-plugin.{ts,test.ts,md} — fail-closed when no tenant
  • 2.8 src/middleware/require-feature.{ts,test.ts,md} — fail-closed when no tenant
  • 2.9 src/rate-limit/rate-limit.{ts,test.ts,md,index.ts} — tenantRateLimit + pluggable RateLimitStore + bounded MemoryRateLimitStore
  • 2.10 src/lifecycle/lifecycle.{ts,test.ts,md,index.ts} — TenantAwarePluginDescriptor + tenantScopes opt-out + hook dispatch via @suaveplan/api-plugin HookExecutor
  • 2.11 src/storage/storage.{ts,test.ts,md,index.ts} — opt-in withTenantStorage ALS support
  • 2.12 src/index.ts — named re-exports

3. Tests

  • 3.1 Co-located *.test.ts per spec scenario
  • 3.2 src/api-tenant.spec-conformance.test.ts — every TENANT.* thrown; expectTypeOf on c.get("tenant"); module-augmentation pinned
  • 3.3 tests/integration/tenant-middleware-roundtrip.test.ts — real Hono app + real ChainedTenantResolver + real TenantCache + real MemoryRateLimitStore
  • 3.4 tests/property.test.ts — fast-check cache TTL invariant (entry expires exactly at ttlMs boundary)
  • 3.5 tests/dep-graph.test.ts — deps + subpaths + sibling .md
  • 3.6 All tests via @suaveplan/testing/runner, { timeout: 5000 } (30000 for integration)

4. Documentation

  • 4.1 Sibling .md per impl (≥200 words)
  • 4.2 README.md — resolver examples, cache config, rate-limit store pluggability, ALS opt-in

5. Gates

  • 5.1 bunx turbo lint typecheck test --filter=@suaveplan/api-tenant --force
  • 5.2 bunx turbo test:coverage --filter=@suaveplan/api-tenant --force 100/100/100/100
  • 5.3 bun scripts/openspec-conformance.ts @suaveplan/api-tenant
  • 5.4 bunx turbo build --filter=@suaveplan/api-tenant --force
  • 5.5 Banned-pattern grep; no export *; no direct vitest/bun:test imports

6. Archive

  • 6.1 Fold spec → openspec/specs/api-tenant/spec.md
  • 6.2 mv change → openspec/archive/<date>-add-api-tenant/
  • 6.3 MANIFEST + STATUS refresh