Initial Commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# `api-types` — Foundation gap 5 cleanup: nullable tenant on RequestContext
|
||||
|
||||
**Package**: `@suaveplan/api-types`
|
||||
**Status**: PROPOSED
|
||||
**Type**: type-soundness-fix
|
||||
|
||||
## Why
|
||||
|
||||
The `foundation-fix-gap-5-default-tenant` change widened the runtime
|
||||
behaviour: when the resolver chain misses and no `defaultTenant` is
|
||||
configured, `RequestContext.tenant` / `RequestContext.tenantId` are
|
||||
`null` at runtime. The static types in `@suaveplan/api-types` were NOT
|
||||
updated — they still declared `tenant: TenantContext` and
|
||||
`tenantId: TenantId` as non-nullable.
|
||||
|
||||
Consequences observed in `request-pipeline-helpers.ts`:
|
||||
|
||||
```ts
|
||||
tenantId: (args.tenant?.id ?? null) as never,
|
||||
tenant: (args.tenant ?? null) as never,
|
||||
```
|
||||
|
||||
The `as never` is a documented escape hatch — but it is a type lie that
|
||||
defeats every handler-side guard the type system was supposed to
|
||||
enforce. Out-of-spec debt; resolved before moving on per the user's
|
||||
directive.
|
||||
|
||||
## What changes
|
||||
|
||||
MODIFIED: `RequestContext<Caps>` field types in
|
||||
`@suaveplan/api-types/plugin-context`:
|
||||
|
||||
```ts
|
||||
readonly tenantId: TenantId | null;
|
||||
readonly tenant: TenantContext | null;
|
||||
```
|
||||
|
||||
Existing `tenant`/`tenantId` consumers in the monorepo already use the
|
||||
null-safe `?.` access pattern (verified across `e2e/foundation-stack`,
|
||||
`apps/demo`, `apps/testbed`, and every `api-plugin-*`). No handler
|
||||
needed a code change beyond stripping the now-redundant casts.
|
||||
|
||||
The `JobContext` and `ConnectionContext` flavours are NOT widened.
|
||||
Per-tenant jobs and connection-scoped contexts only exist after a
|
||||
tenant has been resolved — their resolver chain runs separately and
|
||||
never returns `null` to the handler. Widening those would force a
|
||||
spurious null-check on every job/connection handler.
|
||||
|
||||
The `as never` casts in `request-pipeline-helpers.ts` lines 143-150 are
|
||||
removed. The two remaining `as` casts at the same site are
|
||||
generic-erasure points (capabilities/instruments resolve to typed
|
||||
slices at the route handler call-site, not at the untyped pipeline
|
||||
seam); they now use the explicit
|
||||
`as RequestContext["capabilities"]` form with a multi-line code comment
|
||||
explaining the boundary instead of a blanket `as never`.
|
||||
|
||||
## Impact
|
||||
|
||||
- `@suaveplan/api-types` — spec MODIFIED Requirement (this delta).
|
||||
- `@suaveplan/api-host` — `as never` casts stripped from
|
||||
`buildRequestContext`; generic-erasure casts retained with the
|
||||
documented boundary comment.
|
||||
- E2E foundation-stack: 11 Playwright tests still green; no handler
|
||||
changes needed since fixture plugin already used `ctx.tenant?.id`.
|
||||
|
||||
## Verification
|
||||
|
||||
```
|
||||
bunx turbo lint typecheck test build --filter=@suaveplan/api-types --filter=@suaveplan/api-host
|
||||
bunx turbo test:coverage --filter=@suaveplan/api-host --filter=@suaveplan/api-types
|
||||
cd e2e/foundation-stack && bunx playwright test # 11/11
|
||||
```
|
||||
|
||||
All green. No `as never` remains for `tenant`/`tenantId` in
|
||||
`request-pipeline-helpers.ts`. No `biome-ignore` / `@ts-ignore` /
|
||||
`@ts-expect-error` added anywhere.
|
||||
Reference in New Issue
Block a user