#3770·quartznet

One operation catalogue in core, and HttpScheduler over a transport seam

Author: lahmaCreated Sep 11, 2026Updated Sep 19, 2026
Labelsfeature4.x

The 61 HTTP API endpoint bodies are thin lambdas over IScheduler and the core DTO factories, and HttpScheduler is a second, hand-maintained mapping of IScheduler to the same paths. An agent that answers operation requests over a dial-out connection would need a third. #3361 is what happens when two mappings of one contract exist and nothing exercises the drift.

Shape

  • internal static class SchedulerOperations in Quartz.HttpApiContract: one method per endpoint, (IScheduler, request DTO) → response DTO. 41 routes move verbatim; the 12 listing/matcher routes share one ListingParameters parse that owns MaxPageSize, the one-matcher rule and state=Any; the three reads that are 404 when absent return nullable and the carrier maps; the three job-carrying bodies keep materialization in the carrier (JobDetailDto.AsIJobDetail() is [RequiresUnreferencedCode] and core allows no new IL2026 line); GetAllSchedulers takes the authorization predicate from the carrier. Roughly 500 lines move and 300 are written.
  • IWireTransport.Send(method, path, jsonBody) → (status, body) under HttpScheduler; HttpWireTransport is today's HttpClient path, unchanged in behaviour, and HttpClientExtensions' exception mapping stays the single source.
  • A WireCarrierEquivalenceTest drives the request rows of StatusCodesFollowTheApiConventions through WebApplicationFactory and through the catalogue's route table and asserts identical (status, body).

Done means

  • WireFormatSnapshotTest and the status-code conventions pass without a snapshot change.
  • No public API change; the trim baselines do not grow.

Depends on the PR-1 of #3387. Precedes the agent target, which is the second carrier.

Part of #3387 — see the design record there for how this fits the whole.