Skip to content

refactor: Replace HookRegistry + DynamicPackageLoader with @RegisterClass middleware pattern#2157

Merged
jordanfanapour merged 3 commits intonextfrom
JF_server_middleware
Mar 17, 2026
Merged

refactor: Replace HookRegistry + DynamicPackageLoader with @RegisterClass middleware pattern#2157
jordanfanapour merged 3 commits intonextfrom
JF_server_middleware

Conversation

@jordanfanapour
Copy link
Copy Markdown
Collaborator

@jordanfanapour jordanfanapour commented Mar 17, 2026

Summary

  • Replace HookRegistry and DynamicPackageLoader with the standard @RegisterClass + ClassFactory pattern used everywhere else in MJ. Server middleware now self-registers via @RegisterClass(BaseServerMiddleware, key) and is discovered by serve() via ClassFactory.GetAllRegistrations().
  • New BaseServerMiddleware abstract class — single contract for server middleware with slots for Express middleware (pre-auth, post-auth, post-route), Apollo plugins, schema transformers, resolver paths, and data hooks (PreRunView, PostRunView, PreSave).
  • New MJTenantFilterMiddleware — MJ's built-in multi-tenancy refactored as a BaseServerMiddleware subclass. BCSaaS extends and replaces it via same-key registration.
  • New GetResolverPaths() method — middleware classes can contribute TypeGraphQL resolver glob paths that serve() auto-discovers and merges into buildSchema(). Replaces manual getBCSaaSResolverPaths() wiring.
  • Simplified dataHooks.ts — replaces the ~160-line HookRegistry with two thin functions (RegisterDataHook/GetDataHooks) backed by GetGlobalObjectStore().
  • Deleted: HookRegistry, DynamicPackageLoader, DynamicPackageResult, ServerExtensibilityOptions, mergeExtensibilityOptions(), MERGEABLE_KEYS, registerHookEntry(), hooks.ts

Test plan

  • npm run build in MJServer — compiles cleanly
  • npm run test in MJServer — 160 passed, 56 skipped (expected: BCSaaS integration tests need DB)
  • Verify BCSaaS middleware replacement: ClassFactory.GetRegistration(BaseServerMiddleware, 'mj:tenantFilter') returns BCSaaSMiddleware when BCSaaS is installed
  • Verify GetResolverPaths() — BCSaaS resolvers (BCFeatureFlagResolver, BCSettingsResolver, etc.) are discovered and included in the Apollo schema
  • Verify middleware without GetResolverPaths() override — no resolvers added (empty array default)
  • End-to-end: multi-tenant PreRunView/PreSave hooks fire correctly through the new pipeline

🤖 Generated with Claude Code

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 17, 2026

🦋 Changeset detected

Latest commit: f72b538

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 190 packages
Name Type
@memberjunction/core Patch
@memberjunction/global Patch
@memberjunction/server Patch
@memberjunction/server-bootstrap Patch
@memberjunction/codegen-lib Patch
@memberjunction/component-registry-server Patch
@memberjunction/component-registry-client-sdk Patch
@memberjunction/content-autotagging Patch
@memberjunction/db-auto-doc Patch
@memberjunction/doc-utils Patch
@memberjunction/encryption Patch
@memberjunction/external-change-detection Patch
@memberjunction/generic-database-provider Patch
@memberjunction/graphql-dataprovider Patch
@memberjunction/interactive-component-types Patch
@memberjunction/cli Patch
@memberjunction/core-entities Patch
@memberjunction/core-entities-server Patch
@memberjunction/data-context Patch
@memberjunction/data-context-server Patch
@memberjunction/queue Patch
@memberjunction/storage Patch
@memberjunction/metadata-sync Patch
@memberjunction/postgresql-dataprovider Patch
@memberjunction/query-gen Patch
@memberjunction/query-processor Patch
@memberjunction/redis-provider Patch
@memberjunction/sqlserver-dataprovider Patch
@memberjunction/server-bootstrap-lite Patch
@memberjunction/skip-types Patch
@memberjunction/version-history Patch
@memberjunction/actions-apollo Patch
@memberjunction/actions-base Patch
@memberjunction/code-execution Patch
@memberjunction/actions-content-autotag Patch
@memberjunction/core-actions Patch
@memberjunction/actions Patch
@memberjunction/scheduled-actions Patch
@memberjunction/scheduled-actions-server Patch
@memberjunction/actions-bizapps-accounting Patch
@memberjunction/actions-bizapps-crm Patch
@memberjunction/actions-bizapps-formbuilders Patch
@memberjunction/actions-bizapps-lms Patch
@memberjunction/actions-bizapps-social Patch
@memberjunction/a2aserver Patch
@memberjunction/ai-cli Patch
@memberjunction/ai-agents Patch
@memberjunction/ai-engine-base Patch
@memberjunction/computer-use Patch
@memberjunction/ai-core-plus Patch
@memberjunction/aiengine Patch
@memberjunction/ai-mcp-client Patch
@memberjunction/ai-mcp-server Patch
@memberjunction/computer-use-engine Patch
@memberjunction/ai-prompts Patch
@memberjunction/ai-reranker Patch
@memberjunction/ai-recommendations-rex Patch
@memberjunction/ai-vectors-pinecone Patch
@memberjunction/ai-recommendations Patch
@memberjunction/ai-vectors Patch
@memberjunction/ai-vectordb Patch
@memberjunction/ai-vector-dupe Patch
@memberjunction/ai-vectors-memory Patch
@memberjunction/ai-vector-sync Patch
@memberjunction/ai-agent-manager-actions Patch
@memberjunction/ai-agent-manager Patch
@memberjunction/communication-types Patch
@memberjunction/communication-engine Patch
@memberjunction/entity-communications-base Patch
@memberjunction/entity-communications-client Patch
@memberjunction/entity-communications-server Patch
@memberjunction/notifications Patch
@memberjunction/communication-ms-graph Patch
@memberjunction/communication-gmail Patch
@memberjunction/communication-sendgrid Patch
@memberjunction/communication-twilio Patch
@memberjunction/templates-base-types Patch
@memberjunction/templates Patch
@memberjunction/ng-bootstrap Patch
@memberjunction/ng-auth-services Patch
@memberjunction/ng-base-application Patch
@memberjunction/ng-core-entity-forms Patch
@memberjunction/ng-dashboards Patch
@memberjunction/ng-entity-form-dialog Patch
@memberjunction/ng-entity-permissions Patch
@memberjunction/ng-explorer-app Patch
@memberjunction/ng-explorer-core Patch
@memberjunction/ng-explorer-settings Patch
@memberjunction/ng-link-directives Patch
@memberjunction/ng-list-detail-grid Patch
@memberjunction/ng-shared Patch
@memberjunction/ng-simple-record-list Patch
@memberjunction/ng-workspace-initializer Patch
@memberjunction/ng-testing Patch
@memberjunction/ng-action-gallery Patch
@memberjunction/ng-actions Patch
@memberjunction/ng-agent-requests Patch
@memberjunction/ng-agents Patch
@memberjunction/ng-ai-test-harness Patch
@memberjunction/ng-artifacts Patch
@memberjunction/ng-base-forms Patch
@memberjunction/ng-base-types Patch
@memberjunction/ng-chat Patch
@memberjunction/ng-code-editor Patch
@memberjunction/ng-container-directives Patch
@memberjunction/ng-conversations Patch
@memberjunction/ng-credentials Patch
@memberjunction/ng-dashboard-viewer Patch
@memberjunction/ng-data-context Patch
@memberjunction/ng-deep-diff Patch
@memberjunction/ng-entity-communications Patch
@memberjunction/ng-entity-relationship-diagram Patch
@memberjunction/ng-entity-viewer Patch
@memberjunction/ng-file-storage Patch
@memberjunction/ng-filter-builder Patch
@memberjunction/ng-find-record Patch
@memberjunction/ng-flow-editor Patch
@memberjunction/ng-join-grid Patch
@memberjunction/ng-list-management Patch
@memberjunction/ng-notifications Patch
@memberjunction/ng-query-viewer Patch
@memberjunction/ng-react Patch
@memberjunction/ng-record-changes Patch
@memberjunction/ng-record-selector Patch
@memberjunction/ng-resource-permissions Patch
@memberjunction/ng-scheduling Patch
@memberjunction/ng-shared-generic Patch
@memberjunction/ng-tasks Patch
@memberjunction/ng-timeline Patch
@memberjunction/ng-trees Patch
@memberjunction/ng-user-avatar Patch
@memberjunction/ng-versions Patch
@memberjunction/react-runtime Patch
@memberjunction/react-test-harness Patch
@memberjunction/scheduling-actions Patch
@memberjunction/scheduling-engine-base Patch
@memberjunction/scheduling-engine Patch
@memberjunction/testing-cli Patch
@memberjunction/testing-engine Patch
@memberjunction/testing-engine-base Patch
@memberjunction/credentials Patch
@memberjunction/api-keys-base Patch
@memberjunction/api-keys Patch
@memberjunction/open-app-engine Patch
@memberjunction/integration-actions Patch
@memberjunction/integration-connectors Patch
@memberjunction/integration-engine-base Patch
@memberjunction/integration-engine Patch
@memberjunction/unit-testing Patch
@memberjunction/ai Patch
@memberjunction/ai-anthropic Patch
@memberjunction/ai-azure Patch
@memberjunction/ai-bedrock Patch
@memberjunction/ai-betty-bot Patch
@memberjunction/ai-blackforestlabs Patch
@memberjunction/ai-cerebras Patch
@memberjunction/ai-cohere Patch
@memberjunction/ai-elevenlabs Patch
@memberjunction/ai-fireworks Patch
@memberjunction/ai-gemini Patch
@memberjunction/ai-groq Patch
@memberjunction/ai-heygen Patch
@memberjunction/ai-lmstudio Patch
@memberjunction/ai-local-embeddings Patch
@memberjunction/ai-minimax Patch
@memberjunction/ai-mistral Patch
@memberjunction/ai-ollama Patch
@memberjunction/ai-openai Patch
@memberjunction/ai-openrouter Patch
@memberjunction/ai-vertex Patch
@memberjunction/ai-zhipu Patch
@memberjunction/ai-xai Patch
@memberjunction/scheduling-base-types Patch
@memberjunction/integration-schema-builder Patch
@memberjunction/ng-forms Patch
@memberjunction/ai-provider-bundle Patch
@memberjunction/ng-explorer-modules Patch
@memberjunction/ng-tabstrip Patch
@memberjunction/config Patch
@memberjunction/export-engine Patch
@memberjunction/installer Patch
@memberjunction/sql-converter Patch
@memberjunction/sql-dialect Patch
@memberjunction/sqlglot-ts Patch
@memberjunction/ng-kendo-modules Patch
@memberjunction/ng-export-service Patch
@memberjunction/ng-generic-dialog Patch
@memberjunction/ng-markdown Patch
@memberjunction/ng-pagination Patch
@memberjunction/integration-ui-types Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@claude
Copy link
Copy Markdown

claude bot commented Mar 17, 2026

Claude finished @jordanfanapour's task —— View job


Todo List:

  • Start a pending review
  • Get list of changed files in PR
  • Check for SQL migration files in migrations/ directory
  • Submit review as COMMENT type

Review Completed

I've reviewed this PR and found that it contains no SQL migration files. All 24 changed files are TypeScript files related to the refactoring of server middleware from HookRegistry + DynamicPackageLoader to a @RegisterClass pattern.

Since there are no migration files to review, there are no INSERT statements or stored procedures to check for hard-coded UUID compliance. The review has been submitted as a non-blocking COMMENT type as requested.

Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

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

This PR does not contain any SQL migration files. All changes are TypeScript refactoring related to replacing HookRegistry and DynamicPackageLoader with the @RegisterClass middleware pattern. Therefore, there are no INSERT statements or stored procedures to review for hard-coded UUID compliance.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 17, 2026

✅ Dependency Check Results

All dependencies are properly declared!

No missing dependencies detected in this PR.

jordanfanapour and others added 3 commits March 16, 2026 21:35
…lass + ClassFactory middleware pattern

Replaces the ad-hoc HookRegistry + DynamicPackageLoader + config-bag-threading
approach with MJ's standard @RegisterClass + ClassFactory pattern for server
middleware extensibility.

Key changes:
- Add BaseServerMiddleware abstract class with pipeline slots (PreAuth, PostAuth,
  PostRoute, Apollo plugins, schema transformers, data hooks, ConfigureExpressApp)
- Add MJTenantFilterMiddleware as config-driven multi-tenancy default
- Replace HookRegistry with thin RegisterDataHook/GetDataHooks/ClearAllDataHooks
  functions backed by GetGlobalObjectStore()
- Delete DynamicPackageLoader (class manifest handles discovery)
- Delete ServerExtensibilityOptions interface and hooks.ts
- Simplify ServerBootstrap to remove mergeExtensibilityOptions and MERGEABLE_KEYS
- serve() now discovers middleware via ClassFactory.GetAllRegistrations() with
  key-based deduplication (same key = higher priority wins)
- Update all tests to match new API surface (1,352 tests passing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add resolver discovery to the middleware pipeline so that middleware
classes (e.g., BCSaaSMiddleware) can contribute their own TypeGraphQL
resolvers to the Apollo schema without manual wiring in MJAPI.

- BaseServerMiddleware: new GetResolverPaths() method (default: [])
- serve(): collects resolver globs from all active middleware,
  resolves via fast-glob, dynamically imports, and merges into the
  resolvers array passed to buildSchemaSync()

This replaces the manual getBCSaaSResolverPaths() approach described
in OPEN_APP_RESOLVERS.md with self-registration via the middleware
pipeline — consistent with the @RegisterClass pattern used everywhere.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sterClass middleware pattern and add GetResolverPaths()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jordanfanapour jordanfanapour merged commit 75b5f51 into next Mar 17, 2026
3 checks passed
@jordanfanapour jordanfanapour deleted the JF_server_middleware branch March 17, 2026 02:38
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