Skip to content

feat(server): add modular implementations and typed error policies - #231

Merged
andrewzolotukhin merged 2 commits into
developmentfrom
feat/contract-implementations
Sep 29, 2026
Merged

andrewzolotukhin merged 2 commits into
developmentfrom
feat/contract-implementations

Conversation

@andrewzolotukhin

@andrewzolotukhin andrewzolotukhin commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Description

Original request

Implement Framework consumer-experience points 1.1 (contract-bound implementations) and 1.2 (shared error translation) in a separate PR targeting development. Large APIs must retain strongly typed handlers in separate files. Include JSDoc, documentation, unit/integration/type tests, and a minor changeset. Xpenser adoption follows this PR's merge and beta publication.

What changed

  • Added immutable implement(api) scopes: group(), pick(), withHandlers(), use(), and complete(). Configured scope.endpoints provide types for separately exported Handler<typeof scope.endpoints.operation> functions.
  • Added group/operation service injection, authorization and metadata options while retaining wire schemas, cache settings, uploads, subscriptions, and existing registration machinery.
  • Check missing operations, duplicate bindings, unknown keys and incompatible modules at compile time and at runtime where appropriate. Original endpoint identity permits compatible contract slices without accepting unrelated contracts.
  • Added immutable errorMap().on() policies and standalone withErrors(). Policies require explicit endpoint responses and check mapped status/body compatibility, including bodyless responses. Unknown failures remain unchanged.
  • Added a complete multi-file implementation guide in the existing server README, public JSDoc, and documentation-site examples.
  • Added runtime/type regressions, real HTTP integration coverage, OpenAPI-equivalence coverage, and a generated 1,000-operation consumer compilation/declaration-emission fixture.
  • Added a minor changeset for @cleverbrush/server. No dependency upgrades, Xpenser changes, or temporary consumer-experience document are included.

Reasoning

The modular-only API keeps contracts independent from implementations and lets applications organize handlers by file or module without a single large callback chain. It reuses existing Handler, SubscriptionHandler, HandlerMapping, and result APIs rather than introducing a parallel request pipeline.

Service precedence is contract → group → operation. Module composition preserves contract operation coverage until complete(). Error policies remain application-owned and intercept handler invocation only; authentication, validation, middleware and dependency-resolution failures are not accidentally translated. Translators cannot bypass the endpoint's declared response contract.

The generated consumer fixture checks the emitted package declarations in a realistic multi-file layout. One local full-suite run measured TypeScript check time of 16.53s for equivalent existing registration and 11.09s for modular registration; these are illustrative measurements, not performance guarantees or timing assertions.

Review follow-up (6b628e1f)

  • Moved the full guide into libs/server/README.md and deleted the standalone guide. The documentation-site link now targets the README section.
  • Restored the package's published-files list to ["dist"]; npm still includes the README automatically.
  • Removed the entire standalone type-fixtures tree. Its positive/negative assertions now live in the existing type-test file; the generated multi-file compiler helper lives directly in its consumer test.
  • Preserved all 4,100 tests, including generated 1,000-operation cross-file compilation/declaration emission. No runtime or public API changes were made in this follow-up.
  • Refreshed the local documentation screenshot. The existing minor changeset is unchanged.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactor / internal improvement

Blog post

Skipped: this is a developer-library API change, not a shipped Xpenser end-user feature. The release is documented in the existing server README and documentation-site examples instead.

Screenshots / preview evidence

Framework has no configured per-PR application deployment. Local browser QA verified the documentation section, code examples and updated README-section link at /server#modular-implementations. HTTP integration tests exercise the actual server behavior.

Local documentation QA

This screenshot is from the local docs site, not a deployed preview.

Validation

  • npm ci — lockfile unchanged.
  • npm run lint — 671 files checked.
  • npm run build — all 21 tasks passed.
  • npm run test — 180 test files / 4,100 tests passed, no type errors.
  • npm run typecheck:schema-site
  • npm run typecheck:docs-site
  • npx typedoc --out /tmp/framework-contract-api-docs — 0 errors; 255 documentation/link warnings remain.
  • npm pack --dry-run --json --workspace @cleverbrush/server — new declarations and consolidated README included; no separate docs directory or test fixtures.
  • Local documentation browser QA and committed screenshot.
  • git diff --check
  • GitHub Lint, Build & Test (Node 24) — passed for review-update commit 6b628e1f.
  • GitHub PostgreSQL Query Integration — passed for review-update commit 6b628e1f.
  • Preview deployment: not configured for this repository; local docs QA and HTTP integration used.
  • SigNoz: skipped; no application preview or telemetry configuration in this Framework repository.
  • PR-ready notification: skipped. The configured notifier requires a preview/deployed environment URL, and this library repository has no applicable deployment. No placeholder environment URL was sent.

Checklist

  • Tests added/updated for changed behavior.
  • npm run lint passes.
  • npm run test passes.
  • Changeset added for package changes (minor, not major).

Merge and beta publication are intentionally left to the reviewer/release workflow.

Comment thread libs/server/docs/implementations.md Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need a separate file for that, let's just use readme.md file that we already have

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6b628e1. The complete multi-file guide now lives in the existing libs/server/README.md under “Large APIs and shared error handling”; the separate guide is removed. Configuration, handler files, composition, error policies, and migration details are preserved. The documentation-site link now points to that README section and was checked locally in the browser.

Comment thread libs/server/package.json Outdated
"files": [
"dist"
"dist",
"docs"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same, we don't need it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6b628e1. Restored files to ["dist"], so libs/server/package.json no longer differs from the PR base. Verified with npm pack --dry-run: the consolidated README is still included automatically, and there is no separate docs directory or test-fixture content in the package.

Comment thread libs/server/type-fixtures/server.ts Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel like we need this type-fixtures at all if it's just illustration how it works. Let's better update existing documentation with this information if these are just examples

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6b628e1 using the agreed consolidation. These were executable type-test inputs rather than illustration-only files, so their assertions were preserved in Implementation.test-d.ts. The standalone type-fixtures tree is removed, the generated 1,000-operation cross-file compiler helper now lives directly in Implementation.consumer.test.ts, and the multi-file usage guide is in the existing README. All 4,100 local tests still pass with no type errors; the new GitHub checks are running.

@andrewzolotukhin
andrewzolotukhin merged commit 81593c0 into development Sep 29, 2026
2 checks passed
@andrewzolotukhin
andrewzolotukhin deleted the feat/contract-implementations branch September 29, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant