AI Agents SDE Task Viewer
      • Context
      • Plan
      • Prd
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-551
  5. plan
  6. plan.md
plan.md(4.4 KB)· Apr 23, 2026· 3 min read
  • Summary
  • Files
  • Steps
  • Verification
  • Risks
  • Open Questions

Plan — BJ-11: Tenant config routing (platform → service triple)#

Summary#

Add platform-aware service lookup to TenantConfigService so a task's platform field resolves to the correct { adapter, service, authProvider } triple. Refactor dispatch-path consumers to resolve services via tenant config instead of importing GitHubService directly.

Files#

PathActionPurpose
src/tenant/tenant-config.service.tsmodifyAdd getPlatformServices(platform) returning { adapter, service, authProvider }. Inject AdapterRegistry, PLATFORM_AUTH_PROVIDER, and a new PLATFORM_SERVICES map.
src/tenant/platform-services.tscreateNew file: export PLATFORM_SERVICES injection token and PlatformServicesMap type.
src/tenant/tenant.module.tsmodifyRegister PLATFORM_SERVICES as a factory providing { github: GitHubService }. Import WebhookAdapters module (or re-provide AdapterRegistry) so it is injectable here.
src/phase-router/phase-router.service.tsmodifyReplace GitHubService injection with TenantConfigService; resolve via getPlatformServices(event.source).service.
src/hooks/phase-hooks.service.tsmodifySame refactor; task.repo + event source drives platform lookup (default github until platform threads through PhaseTask).
src/hooks/compound.service.tsmodifySame refactor.
src/tenant/tenant-config.service.spec.tscreateUnit tests for getPlatformServices: valid platform, unknown platform throws, missing platform throws.
src/phase-router/phase-router.service.spec.tsmodifyUpdate DI mocks: swap GitHubService provider for TenantConfigService returning a stub triple.
src/hooks/phase-hooks.service.spec.tsmodifySame spec update.
src/hooks/compound.service.spec.tsmodifySame spec update.

Steps#

  1. Add PLATFORM_SERVICES token + PlatformServicesMap type in a new file under src/tenant/.
  2. Extend TenantConfigService constructor to inject AdapterRegistry, PLATFORM_AUTH_PROVIDER, and PLATFORM_SERVICES; implement getPlatformServices(platform) that returns the triple, throwing BadRequestException on missing and NotFoundException on unknown platform.
  3. Register PLATFORM_SERVICES provider in TenantModule with { github: GitHubService } and ensure AdapterRegistry is resolvable (import from WebhookModule or move registry to a shared module if circular).
  4. Refactor PhaseRouterService to drop GitHubService import; resolve service via tenantConfigService.getPlatformServices(event.source ?? 'github').service.
  5. Refactor PhaseHooksService and CompoundService the same way; default to 'github' where the current PhaseTask has no platform field (add a platform? field on PhaseTask if a caller can supply it without scope creep).
  6. Update the three spec files to inject a TenantConfigService stub returning { adapter, service, authProvider } instead of mocking GitHubService directly.
  7. Run npm run lint and npm run test — fix any breaks; ensure zero warnings.

Verification#

  • grep -r "from '../github/github.service'" src/phase-router src/hooks src/dispatch returns zero matches.
  • TenantConfigService.getPlatformServices('github') returns a non-null triple; 'bitbucket' throws NotFoundException; undefined/'' throws BadRequestException.
  • All existing unit tests pass; phase-router, phase-hooks, compound specs verify service calls route through the resolved provider.

Risks#

  • PlatformProvider interface is currently minimal (postComment, closePR, deleteBranch) and dispatch consumers call many more GitHubService methods (addLabel, mergePR, getCheckStatus, createPR, …). Typing service as the concrete GitHubService for the github key preserves existing method access without expanding PlatformProvider — PlatformProvider expansion is deferred to sibling Wave 3 tickets.
  • AdapterRegistry currently lives in WebhookModule; importing it into TenantModule may introduce a circular dependency. If so, promote AdapterRegistry to a shared module (src/platform/) in this PR.

Open Questions#

  • Should PhaseTask gain a platform field now, or do we hard-default to 'github' at call sites and wire platform through in a follow-up? (Current default keeps diff small and matches the single-platform reality on rc/atlassian-integration.)
ContextPrd