feat(npm): dist-tag PUT/DELETE handler (step 21, 2/2)

Part 2 of 2 of the npm hosted planStep 21: dist-tag PUT / DELETE.

🗂️ Stacked MRs

Split into 2 stacked MRs to keep each within the review size limit (~600 ideal reviewable LoC). Each part targets the previous one (part 1 → main); review and merge bottom-up.

📦 What this part adds

Implements the dist-tag write endpoints on DistTagsHandler, consuming the datastore writer/adjusters from part 1/2 (!771 (merged)):

  • PUT binds a tag to a version: validates the bare-JSON-string body, rejects semver-shaped tag names, enforces the per-package tag cap on new names before version resolution, then upserts and force-expires the cache in one transaction.
  • DELETE removes the tag: 204; 404 on a missing or empty tag; 404 on a missing package.
  • After commit: exactly one packument rebuild is enqueued and the buffered tags_count is adjusted, both off the request path.
  • Adds the tag_name_invalid / tag_not_found error codes.

ℹ️ Known gap — handler not yet wired into the route table. The route mount stays deferred to Step 23: the handler ships built and tested, but is not yet in the production mux.

Spec coverage

Acceptance criterion Test
AC 21 — PUT writes the tag, fires one rebuild → 204 TestDistTagsIntegration_WritePutSetsTag
AC 22 — DELETE removes the tag, fires one rebuild → 204 TestDistTagsIntegration_WriteDelete
AC 23 — semver-shaped tag → 422 tag_name_invalid TestDistTagsIntegration_WritePutTagNameInvalid
AC 27 — cache invalidated (one rebuild enqueued post-commit) TestDistTagsIntegration_WritePutSetsTag, …WriteDelete
AC 31 — new tag at cap → 422 tag_count_exceeded (before version check) TestDistTagsIntegration_WritePutTagCountExceeded
AC 34 — missing/soft-deleted package → 404 package_not_found TestDistTagsIntegration_WritePackageNotFound
AC 35 — missing/soft-deleted version → 404 version_not_found TestDistTagsIntegration_WritePutVersionNotFound
AC 36 — tag missing on DELETE → 404 tag_not_found TestDistTagsIntegration_WriteDelete
AC 58 — write refused without a Resolution TestDistTagsIntegration_WriteMissingResolution
Malformed PUT body → 400 bad_request TestDistTagsIntegration_WritePutBodyInvalid
Writer error → 500, no post-commit events TestDistTagsIntegration_WriteWriterError
Unwired write deps → 500 (not a nil panic) TestDistTagsIntegration_WriteNotWired
Empty tag on DELETE → 404 tag_not_found (no transaction) TestDistTagsIntegration_WriteDeleteEmptyTag

📚 References

Related to #139 (closed)

Edited by Dzmitry (Dima) Meshcharakou

Merge request reports

Loading
Loading