You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(insights): add getInstanceStats to MaestroProcesses and Cases [PLT-103276] (#478)
* feat(insights): add getInstanceCountByStatus to MaestroProcesses and Cases [PLT-103276]
Add InstanceCountByStatus endpoint returning instance counts broken down
by status (running, completed, faulted, etc.) and average duration.
- Rename buildElementCountByStatusBody to buildInsightsCommonBody (reused)
- Add InstanceCountByStatusResponse type
- Add service method, bound method, and JSDoc on both services
- Comprehensive tests in processes, minimal in cases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(insights): rename getInstanceCountByStatus to getInstanceStats
- Rename method: getInstanceCountByStatus → getInstanceStats
- Rename type: InstanceCountByStatusResponse → InstanceStats
- Extract DurationStats interface (shared by ElementStats + InstanceStats)
- Add p50/p95/p99 + min/max duration percentiles to InstanceStats
- Rename SDK count fields (countOf* → *Count) with InstanceStatsMap transform
- API names (countOf*, endpoint constants) unchanged
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove stale PIMS scope and align integration tests with ElementStats pattern
- Remove spurious PIMS scope from getElementStats in oauth-scopes.md
- Extract testGetInstanceStats + expectValidInstanceStats helpers
- Simplify cases/processes integration tests to use the helper (matches getElementStats pattern)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(tests): add getInstanceStats to beforeEach mock setup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(insights): improve JSDoc examples for getElementStats/getInstanceStats
- Show how to obtain processKey, packageId, packageVersion via getAll()
- Include bound method usage in the same @example block (matches getStagesSlaSummary pattern)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(insights): use ProcessStatsRequest object for getElementStats/getInstanceStats
5 positional params at the service layer hurt readability. Bundle them into a
single ProcessStatsRequest type. Bound entity methods stay positional (3 params
each — the entity auto-fills processKey and packageId).
- Add ProcessStatsRequest type in insights.types.ts (shared by both methods on
MaestroProcesses and Cases)
- buildInsightsCommonBody now takes the request object
- Service-level getElementStats/getInstanceStats: (request: ProcessStatsRequest)
- Bound process/case methods unchanged signature: (startTime, endTime, packageVersion)
- Establish Request/Options two-suffix convention in agent_docs/conventions.md:
Options = optional-fields bag (existing), Request = required-fields bag,
used only when 4+ required values cluster semantically
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(insights): rename ProcessStatsRequest to MaestroProcessStatsRequest
Disambiguate from Orchestrator's Process resource, which lives in the same
public type namespace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(insights): assert raw countOf* keys absent in getInstanceStats result
Matches the transform-completeness pattern already used by getTopRunCount
(processes.test.ts:322). Cases test stays differential — comprehensive
absence checks live on the processes side only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(maestro): drop dead inline mock overrides in bound-method tests
beforeEach already registers getElementStats and getInstanceStats as
vi.fn(). The inline mockResolvedValue reassignments shadowed those
without changing behavior — none of the tests assert on the return
value, so the resolved value was never observed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: agent_docs/conventions.md
+9-2Lines changed: 9 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,8 +32,15 @@
32
32
-**Final response type**: `type {Entity}GetResponse = Raw{Entity}GetResponse & {Entity}Methods` — defined in `*.models.ts`, combining raw data with bound methods.
33
33
-**Options types**: `{Entity}GetAllOptions`, `{Entity}GetByIdOptions`, `{Entity}{Operation}Options` (e.g., `TaskAssignmentOptions`, `ProcessInstanceOperationOptions`). Compose with `RequestOptions & PaginationOptions & { ... }` for list methods.
34
34
-**Common base types**: `BaseOptions` (expand, select), `RequestOptions` (extends BaseOptions with filter, orderby), `OperationResponse<TData>` (success + data) — all from `src/models/common/types.ts`.
35
-
-**Use "Options" not "Request"** for parameter types — the entire SDK uses `{Entity}{Operation}Options`.
36
-
-**Required parameters are always positional; Options objects are reserved for optional parameters only.** Required values (IDs, keys, data) are positional arguments. Options objects are always the last parameter, always marked `?`, and contain only optional fields. E.g., `getOutput(jobKey: string)` not `getOutput(options: { jobKey: string })`, `close(instanceId, folderKey, options?)` not `close(options: { instanceId, folderKey })`.
35
+
-**Parameter type naming — two parallel suffixes:**
36
+
-`{Entity}{Operation}Options` — bag of **optional** fields. Always the last parameter. Always marked `?`. Contains only optional fields.
37
+
-`{Entity}{Operation}Request` — bag of **required** fields. Pairs naturally with the existing `{Entity}{Operation}Response`. Convention param name is `request`. Use this **only** when a method has **4+ required values that semantically cluster** (e.g., a process scope + time range). Below that threshold, keep required params positional.
38
+
-**NEVER** use `Request` as the suffix for an optional-fields bag — that slot is `Options`. The two suffixes are not interchangeable.
39
+
-**Required parameters: positional by default, `Request` object only at 4+.**
- 4+ required params that cluster semantically → single `{Entity}{Operation}Request` object. E.g., `getElementStats(request: ProcessStatsRequest)` where `ProcessStatsRequest` bundles `processKey`, `packageId`, `packageVersion`, `startTime`, `endTime`.
42
+
-**Shared `Request` type across methods is allowed** when the exact same shape is used by 2+ methods with no natural method-specific anchor — name it after the concept it represents (e.g., `ProcessStatsRequest` is shared by `getElementStats` and `getInstanceStats`). Same rule that already applies to shared response types.
43
+
-**The same ≤3 / 4+ rule applies to bound entity methods independently.** Bound methods often have fewer required params than their service-level counterparts because the entity auto-fills some fields (e.g., `processKey`, `packageId`). Count what's left after the entity-supplied fields. E.g., service-level `getElementStats` has 5 required → uses `ProcessStatsRequest`. Bound `process.getElementStats(packageVersion, startTime, endTime)` has 3 required → stays positional. The factory delegate constructs the `Request` from the positional args plus the entity's fields before calling the service.
37
44
-**NEVER** duplicate fields across option types — extend existing ones. If `CaseInstanceOperationOptions` already has `comment`, extend it instead of re-declaring. When the shape is identical, use `extends` (e.g., `export interface EntityUpdateRecordByIdOptions extends EntityGetRecordByIdOptions {}`).
38
45
-**Use `Omit` only when a field must not appear in a type at all.** When a field has a server-side default and is simply not required by callers, mark it `?` optional instead. Using `Omit` implies the field would cause an error if included — it misleads callers into thinking they cannot pass the field. Example: if `assignmentCriteria` defaults to `SingleUser` on the server, the options type should declare it as `assignmentCriteria?: TaskAssignmentCriteria`, not `Omit<BaseOptions, 'assignmentCriteria'>`.
39
46
-**Always use `type` for response types** (intersections, unions, composed types). The only place `interface extends` is required is single-type aliases (`type X = Y`), which break TypeDoc — use `export interface EntityUpdateRecordResponse extends EntityRecord {}` instead.
0 commit comments