Initial Commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# foundation-fix-gap-1-pipeline-router
|
||||
|
||||
## Summary
|
||||
|
||||
Close foundation-coherence Gap #1: `@suaveplan/api-router-hono`'s
|
||||
`HonoRouter` did not satisfy `@suaveplan/api-host`'s `PipelineRouter`
|
||||
contract. The two `match()` shapes diverged (`RouteMatch` vs
|
||||
`PipelineRoute`), forcing every host-pipeline consumer to hand-roll a
|
||||
shim — the E2E `foundation-stack` server's `createFixtureRouter()` was
|
||||
the canonical example. This change adds a second, additive facet to
|
||||
`HonoRouter` (`registerPipelineRoute` / `matchPipeline` /
|
||||
`unregisterPipelinePlugin` / `listPipelineRoutes`) that produces values
|
||||
structurally assignable to the host's `PipelineRoute` interface, and
|
||||
ships a canonical `runPipelineRouterConformance(factory)` test harness
|
||||
in `@suaveplan/api-host/testing` so every concrete adapter has a single
|
||||
contract to pass.
|
||||
|
||||
## Motivation
|
||||
|
||||
Empirically the gap caused two failure modes:
|
||||
|
||||
1. **Hand-rolled shims** in every consumer — the E2E `foundation-stack`
|
||||
server's `createFixtureRouter()` was 80 lines of router logic that
|
||||
should have lived inside `api-router-hono`. Every new host-pipeline
|
||||
consumer was on track to write the same shim.
|
||||
2. **No conformance suite** — `api-router-hono` passes
|
||||
`runRouterConformance` against the abstract `Router`, but no harness
|
||||
existed for the host's `PipelineRouter` surface. Adapter drift would
|
||||
only surface during a real E2E run.
|
||||
|
||||
The fix is additive — the existing abstract-`Router` surface is
|
||||
preserved verbatim; the pipeline facet lives next to it as a parallel
|
||||
metadata sidecar. No breaking changes to existing consumers.
|
||||
|
||||
## Scope
|
||||
|
||||
- `@suaveplan/api-router-hono`:
|
||||
- new `src/pipeline/` feature module (`PipelineRouteTable`,
|
||||
`HonoPipelineRoute`, `HonoPipelineRegistration`,
|
||||
`HonoPipelineRouteOptions`, `HonoPipelineHandler`).
|
||||
- `HonoRouter` gains `registerPipelineRoute`,
|
||||
`unregisterPipelineRoute`, `unregisterPipelinePlugin`,
|
||||
`listPipelineRoutes`, `matchPipeline`.
|
||||
- new error code `ROUTER_HONO.PIPELINE_ROUTE_COLLISION`.
|
||||
- new subpath export `./pipeline`.
|
||||
- dev-dep on `@suaveplan/api-host` (testing-only).
|
||||
- vite config emits `index.js` per subpath (closes a pre-existing
|
||||
`./adapter` resolution bug).
|
||||
- `@suaveplan/api-host`:
|
||||
- `./testing` subpath populated with
|
||||
`runPipelineRouterConformance(factory)` +
|
||||
`PipelineRouterConformanceFactory` /
|
||||
`PipelineRouteRegistration` types.
|
||||
- vite config switched to multi-entry so the dist actually emits
|
||||
`testing/testing.js` (closes a pre-existing dead-export bug).
|
||||
- `e2e/foundation-stack`:
|
||||
- drop hand-rolled `createFixtureRouter` body; replace with the real
|
||||
`HonoRouter` pipeline facet.
|
||||
|
||||
## Verification
|
||||
|
||||
- Unit + integration: `bunx turbo lint typecheck test build
|
||||
--filter=@suaveplan/api-router-hono --filter=@suaveplan/api-host` →
|
||||
green; 75 unit tests across `api-router-hono`, 252 across `api-host`.
|
||||
- Coverage: `api-router-hono` 100/100/100/100 on every touched module
|
||||
(`adapter`, `pipeline`, `error-codes`).
|
||||
- E2E: `cd e2e/foundation-stack && bunx playwright test` — all 10
|
||||
test groups pass (`livez`/`readyz`, plugin routes, tenant resolver,
|
||||
domain error envelope, 404 envelope, secrets, admin plugins/details,
|
||||
admin capabilities, rate-limit, idempotency).
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Migrating `api-router-worker-bridge` to the pipeline facet — that
|
||||
adapter will adopt the same harness in a follow-up.
|
||||
- Wiring the `HonoRouter` pipeline facet into the host's
|
||||
`LifecycleDriver.mount-routes` op — currently consumers register
|
||||
manually; threading through the lifecycle is a follow-up change.
|
||||
Reference in New Issue
Block a user