feat(managementapi): emit the repository-created usage event (S23 Step 5)

What

S23 Step 5 of the usage-data foundation plan: the first catalog event, artifact_registry_repository_created.

  • internal/managementapi/create.go emits the event on the create handler's success path, after the row has committed and serialized cleanly and right before the 201 write, so a persisted-but-unserializable row emits nothing. Dimensions come from the resolved ADR-007 namespace anchor (via the Step 4 requestNamespace seam) and the created repository; the two container-image wire formats (docker, oci) collapse to the context's single container member. A namespace without a parseable (organization, entity_id) anchor emits nothing and logs at Error: ADR-007 guarantees the anchor, so that branch firing in production is a data defect, and the tracker's drop counter cannot see a skip that never reaches Track.
  • The event name ships as the managementapi.EventRepositoryCreated constant; the handler consumes the tracker through a consumer-side UsageTracker interface (mirroring RepositoryCreator), threaded through Deps and wireManagementAPI from the Step 3 w.usageData seam, with nil-guards at every layer.
  • docs/dev/usage-data.md (pre-anticipated by the plan) documents local verification with Snowplow Micro: the GDK recipe, a standalone container with the GitLab iglu resolver the image lacks by default, the development usage_data config, and how to read /micro/good.

Stacked on !934 (merged) (Step 3) — this MR targets jdrpereira/s23-usage-data-foundation-step-2's successor branch jdrpereira/s23-usage-data-foundation-step-3 and must merge after !912 (merged) and !934 (merged); GitLab retargets automatically as the stack merges.

Spec coverage

Spec: docs/specs/S23-usage-data-collection.md

This MR owns AC-9. All other rows are owned by the earlier steps of the same plan: Step 1 (!910 (merged)), Step 2 (!912 (merged)), Step 3 (!934 (merged)), Step 4 (!932 (merged)).

# Criterion Tests
AC-9 Repository create emits exactly one first event with the expected dimensions; failed creates emit none TestCreateHandler_EmitsRepositoryCreatedEvent (per-format table incl. the docker/oci → container collapse, anchor and repository dimensions, correlation-ID forwarding), TestCreateHandler_FailurePaths_EmitNoEvent (400/409/422/500/nil-row/serialization failure), TestCreateHandler_UnattributableAnchor_EmitsNoEvent (guard clauses isolated per row, incl. the non-integer entity_id parse), TestCreateHandler_UnknownSlug_EmitsNoEvent

Manual acceptance (a create against a local service shows the event in Snowplow Micro's /micro/good) is documented step-by-step in the new docs/dev/usage-data.md. Verified against a live Micro on this branch: 1 good, 0 bad, both com.gitlab contexts pass iglu validation. The doc's Option C points at the Caproni rig counterpart, gitlab-com/gl-infra/sandbox/caproni-demo!220 (merged), which deploys Micro in-cluster pre-wired.

Notes

  • The first commit is the documented test-first --no-verify carve-out; every other commit ran the full hook chain.
  • The two merge commits at the base of the branch cascade main (which now contains Step 4, !932 (merged)) down the stack so this diff builds on the anchor seam; they disappear from the diff as the stack merges.

Related to #272 (closed)

Edited by João Pereira

Merge request reports

Loading
Loading