Skip to content

feat: [FME-19300]: add metric and event_type nouns, with owners/tags mutation - #250

Merged
puthrayaharness merged 6 commits into
harness:mainfrom
apetruccelli:FME-19300-metrics
Sep 30, 2026
Merged

puthrayaharness merged 6 commits into
harness:mainfrom
apetruccelli:FME-19300-metrics

Conversation

@apetruccelli

@apetruccelli apetruccelli commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

  • Ticket FME-19300 asks for metric list/get, on the premise that create/update/delete don't exist in v4 yet. That premise is stale — v4 already exposes full CRUD (POST/GET /fme/api/v4/metrics, GET/PATCH/DELETE /fme/api/v4/metrics/{metric-id}), and the MCP server already ships all five operations for fme_metric.
  • metric noun, full CRUD: list, get, create, update, delete against v4.
    • Metrics are addressed by id, not name (v4 path param is {metric-id}), unlike feature_flag/segment which use name.
    • name and trafficType are immutable; update rejects both.
    • create metric accepts -f metric.json as a full alternative to --traffic-type/--event-type/--set; values already present in the file are not overridden.
    • update metric accepts -f patch.json as a full alternative to --set/--del; the file is sent as-is as the merge-patch document, with no GET or update_body_pick involved.
  • event_type noun, read-only: list, get — mirrors the existing traffic_type lookup pattern. Needed because baseEventTypes is a required field on create metric and there is otherwise no way to discover a valid event type id from the CLI.
  • tags/owners are fully mutable, wired onto the fme:owners/fme:tags field types (--add/--del tags.<name>, --add/--del owners.user:<email|id>, --add/--del owners.group:<identifier>) — no new Go code, the handlers are noun-agnostic. update metric's update_body_pick carries both collections so a mutation on one preserves the other.
  • cap.*, filterEventType, and triggerEventType are mutable via dotted --set fields (cap_metric_value, cap_base_event_count, cap_base_event_sum, cap_base_event_value, cap_filter_event_count, cap_filter_event_sum, cap_filter_event_value, cap_granularity, filter_event_type, filter_aggregation, trigger_event_type) — flat scalars against v4's MetricCap/FilterEventType/TriggerEventType DTOs, no new Go code. trigger_event_type is the wire representation of the product UI's "before event" filter dimension. The server applies genuine RFC 7396 recursive merge-patch, so setting one cap/filterEventType sub-field via --set preserves untouched siblings on update.
  • Full unit test coverage for both nouns, including owners/tags add/del, first-touch --add on create, cap/filterEventType/triggerEventType scalar --set on create and update, and -f-supplied create/update fields.

Commands

  • harness list event_type [--name <substring>] [--traffic-type <id-or-name>]
  • harness create metric <name> --traffic-type <type> --event-type <event-type-id> --set format=NUMBER --set aggregation=COUNT --set is_positive=true --add tags.<name> --add owners.user:<email>
  • harness create metric <name> --traffic-type <type> --event-type <event-type-id> --set format=NUMBER --set aggregation=COUNT --set is_positive=true --set cap_metric_value=100 --set cap_granularity=DAYS --set filter_event_type=<event-type-id> --set filter_aggregation=COUNT --set trigger_event_type=<event-type-id>
  • harness create metric <name> -f metric.json, where metric.json is:
    {"trafficType":"user","baseEventTypes":[{"eventTypeId":"signup"}],"format":"NUMBER","aggregation":"COUNT","isPositive":true,"cap":{"metricValueCap":100,"granularity":"DAYS"},"filterEventType":{"eventTypeId":"checkout","filterAggregation":"COUNT"},"triggerEventType":{"eventTypeId":"signed-up"}}
  • harness list metric [--name <substring>] [--event-type-id <id>] [--tag <name>]
  • harness get metric <metric-id>
  • harness update metric <metric-id> --add owners.group:<identifier> --del owners.user:<id> --add tags.<name> --del tags.<name>
  • harness update metric <metric-id> --set cap_metric_value=250 --set cap_base_event_count=10 --set trigger_event_type=<event-type-id>
  • harness update metric <metric-id> -f patch.json, where patch.json is any subset of mutable fields, e.g. {"cap":{"metricValueCap":250}}
  • harness delete metric <metric-id> --force

Testing

  • go build ./... and go test ./pkg/... pass
  • Live end-to-end against qa0: create/list/get/update/delete metric, list/get event_type, immutable-field rejection (name, traffic_type), hard-delete-then-404 behavior
  • Live end-to-end owners/tags on metric: create with tags+owners in one call, add a GROUP owner and a tag, delete the original USER owner and the original tag, confirmed final state
  • Live end-to-end -f metric.json on create metric and -f patch.json on update metric against qa0, with no --traffic-type/--event-type/--set/--del on the command line
  • Live end-to-end cap/filterEventType via both --set and -f on create metric and update metric, confirming the merge-patch preserves untouched sibling fields (e.g. cap.granularity survives a cap.metricValueCap-only update)
  • Confirmed backend accepts and correctly stores boolean fields sent via --set as strings (Jackson lenient coercion), so no CLI-side type coercion was needed

🤖 Generated with Claude Code

@apetruccelli apetruccelli changed the title feat: [FME-19300]: add metric and event_type nouns feat: [FME-19300]: add metric and event_type nouns, with owners/tags mutation Sep 29, 2026
apetruccelli and others added 6 commits September 30, 2026 13:49
Rebased onto main post-harness#257 merge: the fme:owners/fme:tags framework
this built on top of already landed via harness#257's squash merge, so this
carries only the metric/event_type-specific additions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wire metric's tags/owners fields onto the existing fme:owners/fme:tags
field types (no new Go code), widen update metric's update_body_pick
to carry both collections, and add unit tests mirroring the
feature_flag/segment coverage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…eate metric

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tric

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@puthrayaharness
puthrayaharness merged commit eda9fc8 into harness:main Sep 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants