Skip to content

Onboard getIncidentsTimeline method on MaestroProcesses and Cases services #485

@ninja-shreyash

Description

@ninja-shreyash

Summary

Onboard a new SDK method getIncidentsTimeline on both MaestroProcesses and Cases services, backed by the existing IncidentsByTimeWindow Insights API. Follow the same pattern as getInstanceStatusTimeline and extend the shared TimelineOptions type to expose the process-level filters the backend already supports — for both methods.

Motivation

The current SDK has no way to retrieve incident counts over time. getIncidents(processKey, folderKey) returns full incident records for a single process, and getInstanceStatusTimeline returns instance status counts over time — neither answers "how many incidents happened per hour/day/week?"

This is the timeline chart data shape (e.g., "Incidents over the last 30 days") that drives monitoring dashboards.

Backend API

Endpoint: POST /AgenticInstanceStatus/IncidentsByTimeWindow
Insights-monitoring controller: AgenticInstanceStatusController.GetIncidentsByTimeWindow
SQL: AgenticOrchestrationQuery.IncidentsByTimeWindowQuery

Request

{
  "commonParams": {
    "startTime": <epoch ms>,
    "endTime": <epoch ms>,
    "packageId": "...",       // optional filter
    "version": "...",         // optional filter
    "processKey": "...",      // optional filter
    "processKeys": ["..."],   // optional allowlist filter
    "isCaseManagement": false // true for Cases, false for MaestroProcesses
  },
  "timeSliceUnit": "HOUR" | "DAY" | "WEEK",
  "timezoneOffset": <minutes from UTC, optional>
}

Response

{
  "dataPoints": [
    { "count": 0,   "startTime": "2026-04-27T00:00:00", "endTime": "2026-05-04T00:00:00" },
    { "count": 26,  "startTime": "2026-05-04T00:00:00", "endTime": "2026-05-11T00:00:00" },
    { "count": 129, "startTime": "2026-05-11T00:00:00", "endTime": "2026-05-18T00:00:00" }
    // … all buckets in range, zero-padded
  ]
}

Why expose on both MaestroProcesses and Cases?

The backend already accepts an isCaseManagement flag and uses it to filter PROCESSRUNS.CASEINSTANCEID IS NOT NULL/NULL — same pattern as TopProcessesByRunCount, TopProcessesByDuration, InstanceStatusByDate. So this method can be cleanly type-pure on both services:

  • MaestroProcesses.getIncidentsTimeline(...) → sends isCaseManagement: false
  • Cases.getIncidentsTimeline(...) → sends isCaseManagement: true

SDK design

Method signature

Match getInstanceStatusTimeline exactly for symmetry:

```ts
getIncidentsTimeline(
startTime: Date,
endTime: Date,
options?: TimelineOptions,
): Promise<IncidentTimelinePoint[]>;
```

Response type (new)

/**
 * Incident count within a specific time bucket.
 */
export interface IncidentTimelinePoint {
  /** Start of the time bucket (ISO timestamp) */
  startTime: string;
  /** End of the time bucket (ISO timestamp) */
  endTime: string;
  /** Number of incidents in this bucket */
  count: number;
}

Note: endTime is technically derivable from startTime + groupBy, but the backend returns it explicitly to handle DST / timezone edge cases cleanly. We pass it through.

Extend TimelineOptions (shared with getInstanceStatusTimeline)

Both backend endpoints (InstanceStatusByDate and IncidentsByTimeWindow) accept the identical filter set, but the SDK's TimelineOptions currently only exposes groupBy. Extend it once so both methods benefit:

```ts
export interface TimelineOptions {
/**

  • How to group data points on the time axis.
  • @default TimeInterval.Day
    */
    groupBy?: TimeInterval;

/** Filter by package ID */
packageId?: string;

/** Filter by package version */
version?: string;

/** Filter by process key */
processKey?: string;

/** Filter by a list of process keys (allowlist) */
processKeys?: string[];
}
```

Wiring this through fetchInstanceStatusTimeline (and the new fetchIncidentsTimeline) is straightforward — they just pass these fields into commonParams.

Service-level model

  • New file: src/models/maestro/incidents-timeline.types.ts (or co-locate in insights.types.ts next to InstanceStatusTimelineResponse)
  • Add getIncidentsTimeline to both MaestroProcessesServiceModel and CasesServiceModel
  • Implement in src/services/maestro/insights.ts as fetchIncidentsTimeline(), mirroring the existing fetchInstanceStatusTimeline()
  • Both processes.ts and cases.ts services delegate to it, supplying isCaseManagement

Endpoint constant

Add to src/utils/constants/endpoints/maestro.ts:

```ts
INCIDENTS_BY_TIME_WINDOW: \${INSIGHTS_RTM_BASE}/agenticInstanceStatus/IncidentsByTimeWindow,
```

Notable design decisions

  • No timezoneOffset exposed (initially) — matches getInstanceStatusTimeline precedent. Can be added later under TimelineOptions for both methods if demanded.
  • Pass through endTime in the response — backend includes it, costs little, avoids DST math on the consumer side.
  • @track('MaestroProcesses.GetIncidentsTimeline') and @track('Cases.GetIncidentsTimeline') on the public methods.
  • Integration test for both services in tests/integration/shared/maestro/.
  • Unit tests in tests/unit/services/maestro/processes/ and tests/unit/services/maestro/cases/.
  • Update docs/oauth-scopes.md with the new method's scopes.

Out of scope

  • topInstancesSummary onboarding (deferred — see internal notes; needs backend isCaseManagement filter first).
  • Adding timezoneOffset to TimelineOptions — defer until there's a concrete consumer need.

References

  • Insights-monitoring controller: RealtimeMonitoring/RealTimeDashboards/src/Controllers/AgenticInstanceStatusController.cs (lines 909–957)
  • SQL: RealtimeMonitoring/RealTimeDashboards/src/DataAccessor/Queries/AgenticOrchestrationQuery.ProcessAndInstances.cs (IncidentsByTimeWindowQuery, lines 479+)
  • Existing precedent: getInstanceStatusTimeline on both services

Metadata

Metadata

Assignees

No one assigned

    Labels

    minionAutonomous Claude Code agent will implement this issue

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions