54 lines
3.4 KiB
Markdown
54 lines
3.4 KiB
Markdown
# 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
|