feat(npm): wire route table to real handlers (S11 Step 26)

Part 2 of 2 of the npm hosted planStep 26: wire the format route table to the real handlers.

🗂️ Stacked MRs

Split into 2 stacked MRs to reduce review load. This part targets part 1's branch (dm/npm-step26-dispatcher), so its diff is only the wiring slice — retarget to main once part 1 merges. Review and merge bottom-up.

📦 What this part adds

Flips the npm mount from the interim 501 base dispatcher to the real per-action handlers — the Step 26 behavior change.

  • wireNPM / buildNpmDispatcherwireNPM now takes the shared BlobStore and the npm config; buildNpmDispatcher constructs the download, packument, dist-tags, publish, deprecate, and unpublish handlers from the production datastore stores and threads NewDispatchHandlerWithHandlers.
  • Composition-root adapters — the dual-store LastDownloadedBumper (bumps both the version and the package off the request path) and the PublishPrechecker (package, version, and tag consumer interfaces) answering the publish pre-check's three reads, keyset-iterating the tag list for the new-tags-only cap check. public_registry_url is threaded into the packument handler and the cache rebuilder.
  • Metrics and pairing guardnpm.RegisterMetrics is called beside oci's at the composition root, so the gitlab_artifact_registry_npm_* series register at boot regardless of handler wiring; NewPublishHandler now panics when a blob store is wired without a committer, so the interim-200 fake-success becomes a boot-time error rather than a silent runtime one.
  • Godoc — the deprecate, dist-tags, and unpublish handlers now document that they are wired, and the deprecate body-cap comment attributes the cap to the production dispatcher.

Test coverage: the production entry-point signature, nil-dependency boot guards, the bumper and prechecker adapter delegation, the publish/deprecate split through BodySizeMiddleware, and a boot smoke test driving every route against a real database.

⚠️ Known gap

Publish is wired with QuotaChecker left nil (admits every publish) because the per-request npm quota subsystem is not built yet. This is a known, tracked gap - not a permanent decision - followed up in #260. Surfaced by the automated AppSec review.

📚 References

Related to #238 (closed)

Edited by Dzmitry (Dima) Meshcharakou

Merge request reports

Loading
Loading