ADR-0022: Activity view-modes are a single enum parameter

The activity feed selects its view (all / my objects / upstream / downstream) with one ActivityType enum parameter dispatched server-side, rather than a separate endpoint per view.

Status

Accepted. Reconstructed from the codebase on 2026-05-30; the decision is live in the source today.

Context

The activity feed offers several views of the same stream: everything, only the caller's own objects, and the upstream/downstream lineage neighbourhood of the caller's objects. There are two ways to expose those views over HTTP: one endpoint per view (/api/activity/mine, /api/activity/upstream, …), or a single endpoint with a parameter that selects the view. The platform had to pick one shape for the activity feed.

Decision

The activity feed exposes its view-modes as a single ActivityType enum parameter on GET /api/activity, dispatched server-side — not as separate endpoints. The enum has four members (ALL, MY_OBJECTS, DOWNSTREAM, UPSTREAM); the service layer switches on the value to the matching query (fetchAllActivities, fetchMyActivities, fetchDependentActivities for the two lineage directions). An unset type falls through to the ALL behaviour.

This is a deliberate divergence from the owner-scoped reads on DataEntityController, which expose the structurally similar "my / my-upstream / my-downstream" views as separate endpoints (/my, /my/upstream, /my/downstream). The same platform uses parameter-dispatch for the activity feed and separate-endpoints for data-entity listings — the activity feed's view dimension is a query parameter; the data-entity feed's is a path.

Consequences

  • Adding a new activity view-mode is an enum addition plus a switch arm — one endpoint stays the single entry point; no new routes, no new generated interface methods.

  • The view dimension is a parameter callers must know about rather than a discoverable URL, and the four modes are not currently spelled out on the activity-feed feature page — the affordance is in the API contract, not the prose.

  • The platform carries two shapes for "scope this feed to me / my lineage": enum-parameter (activity) and separate-endpoints (data-entity owner reads). A contributor extending either should follow the local shape, not assume one global convention — the divergence is real and intentional, not an oversight.

  • type unset and type=ALL both route to the all-activities query through distinct branches; they are equivalent today, which is worth knowing for anyone later adding scoping to one of those paths.

Evidence

  • odd-platform-api/.../controller/ActivityController.java:32getActivity(... final ActivityType type, ...): the view-mode is one enum parameter on the single endpoint.

  • odd-platform-api/.../service/activity/ActivityServiceImpl.java:103-117 — the dispatch: if (type == null) return fetchAllActivities(...); then switch (type) { case MY_OBJECTS -> fetchMyActivities(...); case DOWNSTREAM -> fetchDependentActivities(..., DOWNSTREAM); case UPSTREAM -> fetchDependentActivities(..., UPSTREAM); case ALL -> fetchAllActivities(...); }.

  • The generated ActivityType enum (api.contract.model.ActivityType) carries exactly the four members ALL / MY_OBJECTS / DOWNSTREAM / UPSTREAM, imported at ActivityController.java:10.

See also

Last updated