@thinkai/tai-api-contract 2.62.0 → 2.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/openapi.d.ts +978 -0
- package/dist/generated/openapi.d.ts.map +1 -1
- package/dist/index.d.ts +187 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -1
- package/openapi/openapi.yaml +1017 -17
- package/package.json +1 -1
- package/src/generated/openapi.ts +978 -0
- package/src/index.ts +277 -0
package/openapi/openapi.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.0.3
|
|
2
2
|
info:
|
|
3
3
|
title: ThinkAI API
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.64.0
|
|
5
5
|
description: >
|
|
6
6
|
Contract surface for the AI Driven SDLC backend used by ThinkAI.
|
|
7
7
|
Workspace-scoped routes use `/workspaces/{workspaceId}/...`.
|
|
@@ -54,6 +54,14 @@ tags:
|
|
|
54
54
|
description: Agentic Foundation pillars (epic #278); reads stored repository readiness snapshots
|
|
55
55
|
- name: YourAiJourney
|
|
56
56
|
description: Your AI Journey dashboard aggregators (epic #267); composes readiness, metrics, and AI-spend data for the /dashboard page
|
|
57
|
+
- name: SdlcInsights
|
|
58
|
+
description: SDLC Engineering Health insights — DORA, CI, collaboration, security, governance, and operational metrics for `/insights/sdlc/overview`.
|
|
59
|
+
- name: InsightsRecommendations
|
|
60
|
+
description: >
|
|
61
|
+
Cross-analysis Insights & Recommendations page (`/insights-recommendations`).
|
|
62
|
+
Seven workspace-scoped GET resources under `/insights/recommendations-page/*`
|
|
63
|
+
with shared date/org/provider filters. Numbers are computed from dashboard metrics,
|
|
64
|
+
AI-tool usage/spend, org chart, and readiness — never mock payloads.
|
|
57
65
|
- name: WorkspaceActivity
|
|
58
66
|
description: Workspace-wide lifecycle activity log — repo add/remove/re-add and integration lifecycle events (issue #515).
|
|
59
67
|
- name: PlatformAdmin
|
|
@@ -2610,6 +2618,412 @@ paths:
|
|
|
2610
2618
|
"404":
|
|
2611
2619
|
description: Workspace does not exist or malformed workspaceId
|
|
2612
2620
|
|
|
2621
|
+
/workspaces/{workspaceId}/insights/sdlc/overview:
|
|
2622
|
+
get:
|
|
2623
|
+
tags: [SdlcInsights]
|
|
2624
|
+
summary: SDLC insights — Engineering Health overview
|
|
2625
|
+
description: >
|
|
2626
|
+
Engineering Health dashboard for `/insights/sdlc/overview`. Returns precomputed
|
|
2627
|
+
DORA, CI, collaboration, security, governance, and operational metrics aggregated
|
|
2628
|
+
at calendar-day granularity for the selected window. Filter params mirror other
|
|
2629
|
+
Measure insights routes plus optional `repoIds` scope.
|
|
2630
|
+
operationId: getSdlcInsightsOverview
|
|
2631
|
+
parameters:
|
|
2632
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2633
|
+
- $ref: "#/components/parameters/InsightsSdlcRangeId"
|
|
2634
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
2635
|
+
- name: team
|
|
2636
|
+
in: query
|
|
2637
|
+
description: Team name filter; send `All teams` to include every team.
|
|
2638
|
+
schema:
|
|
2639
|
+
type: string
|
|
2640
|
+
default: All teams
|
|
2641
|
+
- name: repoIds
|
|
2642
|
+
in: query
|
|
2643
|
+
description: Comma-separated internal repo ids; omit or empty for all repos.
|
|
2644
|
+
schema:
|
|
2645
|
+
type: string
|
|
2646
|
+
responses:
|
|
2647
|
+
"200":
|
|
2648
|
+
description: Engineering Health overview payload
|
|
2649
|
+
content:
|
|
2650
|
+
application/json:
|
|
2651
|
+
schema:
|
|
2652
|
+
$ref: "#/components/schemas/SdlcOverviewDto"
|
|
2653
|
+
"400":
|
|
2654
|
+
description: Invalid query parameters
|
|
2655
|
+
content:
|
|
2656
|
+
application/json:
|
|
2657
|
+
schema:
|
|
2658
|
+
type: object
|
|
2659
|
+
required: [error]
|
|
2660
|
+
properties:
|
|
2661
|
+
error: { type: string, example: invalid_query }
|
|
2662
|
+
"401":
|
|
2663
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2664
|
+
"403":
|
|
2665
|
+
$ref: "#/components/responses/Forbidden"
|
|
2666
|
+
"404":
|
|
2667
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2668
|
+
|
|
2669
|
+
/workspaces/{workspaceId}/insights/sdlc/drilldown/{metricId}:
|
|
2670
|
+
get:
|
|
2671
|
+
tags: [SdlcInsights]
|
|
2672
|
+
summary: SDLC insights — metric drill-down entities
|
|
2673
|
+
description: >
|
|
2674
|
+
Paginated entity list for a single Engineering Health metric (failed workflow runs,
|
|
2675
|
+
PRs, alerts, etc.). Available only when the overview marks `drilldownAvailable: true`.
|
|
2676
|
+
operationId: getSdlcInsightsDrilldown
|
|
2677
|
+
parameters:
|
|
2678
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2679
|
+
- name: metricId
|
|
2680
|
+
in: path
|
|
2681
|
+
required: true
|
|
2682
|
+
schema:
|
|
2683
|
+
$ref: "#/components/schemas/SdlcMetricId"
|
|
2684
|
+
- $ref: "#/components/parameters/InsightsSdlcRangeId"
|
|
2685
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
2686
|
+
- name: team
|
|
2687
|
+
in: query
|
|
2688
|
+
schema:
|
|
2689
|
+
type: string
|
|
2690
|
+
default: All teams
|
|
2691
|
+
- name: repoIds
|
|
2692
|
+
in: query
|
|
2693
|
+
schema:
|
|
2694
|
+
type: string
|
|
2695
|
+
- name: cursor
|
|
2696
|
+
in: query
|
|
2697
|
+
description: Opaque pagination cursor from a prior response.
|
|
2698
|
+
schema:
|
|
2699
|
+
type: string
|
|
2700
|
+
- name: limit
|
|
2701
|
+
in: query
|
|
2702
|
+
schema:
|
|
2703
|
+
type: integer
|
|
2704
|
+
minimum: 1
|
|
2705
|
+
maximum: 100
|
|
2706
|
+
default: 25
|
|
2707
|
+
responses:
|
|
2708
|
+
"200":
|
|
2709
|
+
description: Drill-down page
|
|
2710
|
+
content:
|
|
2711
|
+
application/json:
|
|
2712
|
+
schema:
|
|
2713
|
+
$ref: "#/components/schemas/SdlcDrilldownDto"
|
|
2714
|
+
"400":
|
|
2715
|
+
description: Invalid query parameters
|
|
2716
|
+
content:
|
|
2717
|
+
application/json:
|
|
2718
|
+
schema:
|
|
2719
|
+
type: object
|
|
2720
|
+
required: [error]
|
|
2721
|
+
properties:
|
|
2722
|
+
error: { type: string, example: invalid_query }
|
|
2723
|
+
"401":
|
|
2724
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2725
|
+
"403":
|
|
2726
|
+
$ref: "#/components/responses/Forbidden"
|
|
2727
|
+
"404":
|
|
2728
|
+
description: Workspace or metric not found
|
|
2729
|
+
|
|
2730
|
+
/workspaces/{workspaceId}/insights/recommendations-page/verdict-summary:
|
|
2731
|
+
get:
|
|
2732
|
+
tags: [InsightsRecommendations]
|
|
2733
|
+
summary: Insights recommendations — verdict summary cards
|
|
2734
|
+
description: >
|
|
2735
|
+
Top status cards for `/insights-recommendations`. `productivityMultiplier` is the
|
|
2736
|
+
merged-PR volume ratio versus the previous equal-length window (not AI-active vs
|
|
2737
|
+
non-users). `ciFailRatePct` is portfolio CI fail rate percent. Cost statuses compare
|
|
2738
|
+
AI spend per merged PR to the prior window. Status thresholds match the product UI:
|
|
2739
|
+
productivity ≥1.5 healthy / ≥1.0 watch / else at-risk; CI fail <15 healthy / ≤30 watch /
|
|
2740
|
+
else at-risk; cost change ≤0 healthy / <20% watch / else at-risk (prev≤0 → watch).
|
|
2741
|
+
operationId: getInsightsRecommendationsVerdictSummary
|
|
2742
|
+
parameters:
|
|
2743
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2744
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2745
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2746
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2747
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2748
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2749
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2750
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2751
|
+
responses:
|
|
2752
|
+
"200":
|
|
2753
|
+
description: Verdict summary with `_meta.isMock=false`
|
|
2754
|
+
content:
|
|
2755
|
+
application/json:
|
|
2756
|
+
schema:
|
|
2757
|
+
$ref: "#/components/schemas/InsightsRecommendationsVerdictSummaryResponse"
|
|
2758
|
+
"400":
|
|
2759
|
+
description: Invalid filter or date range
|
|
2760
|
+
content:
|
|
2761
|
+
application/json:
|
|
2762
|
+
schema:
|
|
2763
|
+
type: object
|
|
2764
|
+
required: [error]
|
|
2765
|
+
properties:
|
|
2766
|
+
error: { type: string, example: invalid_query }
|
|
2767
|
+
"401":
|
|
2768
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2769
|
+
"403":
|
|
2770
|
+
$ref: "#/components/responses/Forbidden"
|
|
2771
|
+
"404":
|
|
2772
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2773
|
+
|
|
2774
|
+
/workspaces/{workspaceId}/insights/recommendations-page/roi-quadrant:
|
|
2775
|
+
get:
|
|
2776
|
+
tags: [InsightsRecommendations]
|
|
2777
|
+
summary: Insights recommendations — AI spend vs delivery output
|
|
2778
|
+
description: >
|
|
2779
|
+
Per-engineer AI spend (USD) and merged PR counts for the scatter / ROI quadrant.
|
|
2780
|
+
Includes engineers with spend>0 or mergedPrs>0. Medians are over the returned set
|
|
2781
|
+
(n<2 uses the single point or zeros when empty). `id` is the stable org person id.
|
|
2782
|
+
operationId: getInsightsRecommendationsRoiQuadrant
|
|
2783
|
+
parameters:
|
|
2784
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2785
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2786
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2787
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2788
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2789
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2790
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2791
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2792
|
+
responses:
|
|
2793
|
+
"200":
|
|
2794
|
+
description: ROI quadrant payload
|
|
2795
|
+
content:
|
|
2796
|
+
application/json:
|
|
2797
|
+
schema:
|
|
2798
|
+
$ref: "#/components/schemas/InsightsRecommendationsRoiQuadrantResponse"
|
|
2799
|
+
"400":
|
|
2800
|
+
description: Invalid filter or date range
|
|
2801
|
+
content:
|
|
2802
|
+
application/json:
|
|
2803
|
+
schema:
|
|
2804
|
+
type: object
|
|
2805
|
+
required: [error]
|
|
2806
|
+
properties:
|
|
2807
|
+
error: { type: string, example: invalid_query }
|
|
2808
|
+
"401":
|
|
2809
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2810
|
+
"403":
|
|
2811
|
+
$ref: "#/components/responses/Forbidden"
|
|
2812
|
+
"404":
|
|
2813
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2814
|
+
|
|
2815
|
+
/workspaces/{workspaceId}/insights/recommendations-page/velocity-quality:
|
|
2816
|
+
get:
|
|
2817
|
+
tags: [InsightsRecommendations]
|
|
2818
|
+
summary: Insights recommendations — velocity vs quality weekly series
|
|
2819
|
+
description: >
|
|
2820
|
+
Weekly merged PR volume and CI fail rate for the filter window. Weeks follow the
|
|
2821
|
+
Measure calendar-week bucket convention. `targetFailRatePct` is the org target (15).
|
|
2822
|
+
`volumeGrowthPct` is percent change vs the prior equal-length period.
|
|
2823
|
+
operationId: getInsightsRecommendationsVelocityQuality
|
|
2824
|
+
parameters:
|
|
2825
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2826
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2827
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2828
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2829
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2830
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2831
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2832
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2833
|
+
responses:
|
|
2834
|
+
"200":
|
|
2835
|
+
description: Velocity vs quality payload
|
|
2836
|
+
content:
|
|
2837
|
+
application/json:
|
|
2838
|
+
schema:
|
|
2839
|
+
$ref: "#/components/schemas/InsightsRecommendationsVelocityQualityResponse"
|
|
2840
|
+
"400":
|
|
2841
|
+
description: Invalid filter or date range
|
|
2842
|
+
content:
|
|
2843
|
+
application/json:
|
|
2844
|
+
schema:
|
|
2845
|
+
type: object
|
|
2846
|
+
required: [error]
|
|
2847
|
+
properties:
|
|
2848
|
+
error: { type: string, example: invalid_query }
|
|
2849
|
+
"401":
|
|
2850
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2851
|
+
"403":
|
|
2852
|
+
$ref: "#/components/responses/Forbidden"
|
|
2853
|
+
"404":
|
|
2854
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2855
|
+
|
|
2856
|
+
/workspaces/{workspaceId}/insights/recommendations-page/review-pipeline:
|
|
2857
|
+
get:
|
|
2858
|
+
tags: [InsightsRecommendations]
|
|
2859
|
+
summary: Insights recommendations — review bottleneck funnel
|
|
2860
|
+
description: >
|
|
2861
|
+
Review funnel stages `open-review`, `review-approval`, `approval-merge`, and `merged`.
|
|
2862
|
+
Wait stages use delivery-health hours (`avgReviewWaitHours`, `avgApprovalHours`, and
|
|
2863
|
+
approval→merge as max(0, avgTimeToMergeHours − wait − approval)). The `merged` stage
|
|
2864
|
+
uses `medianHours=0` (volume is not hours). `bottleneckStageId` is the wait stage with
|
|
2865
|
+
the highest median hours. `reviewerLoad` comes from persisted `deliveryHealth.topReviewers`
|
|
2866
|
+
when available; otherwise an empty array (never invented reviewers).
|
|
2867
|
+
operationId: getInsightsRecommendationsReviewPipeline
|
|
2868
|
+
parameters:
|
|
2869
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2870
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2871
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2872
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2873
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2874
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2875
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2876
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2877
|
+
responses:
|
|
2878
|
+
"200":
|
|
2879
|
+
description: Review pipeline payload
|
|
2880
|
+
content:
|
|
2881
|
+
application/json:
|
|
2882
|
+
schema:
|
|
2883
|
+
$ref: "#/components/schemas/InsightsRecommendationsReviewPipelineResponse"
|
|
2884
|
+
"400":
|
|
2885
|
+
description: Invalid filter or date range
|
|
2886
|
+
content:
|
|
2887
|
+
application/json:
|
|
2888
|
+
schema:
|
|
2889
|
+
type: object
|
|
2890
|
+
required: [error]
|
|
2891
|
+
properties:
|
|
2892
|
+
error: { type: string, example: invalid_query }
|
|
2893
|
+
"401":
|
|
2894
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2895
|
+
"403":
|
|
2896
|
+
$ref: "#/components/responses/Forbidden"
|
|
2897
|
+
"404":
|
|
2898
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2899
|
+
|
|
2900
|
+
/workspaces/{workspaceId}/insights/recommendations-page/cost-per-pr:
|
|
2901
|
+
get:
|
|
2902
|
+
tags: [InsightsRecommendations]
|
|
2903
|
+
summary: Insights recommendations — cost per merged PR by team
|
|
2904
|
+
description: >
|
|
2905
|
+
Org and per-team AI spend / merged PRs. Teams with zero merged PRs in the window are
|
|
2906
|
+
omitted. `costPerPrUsd = spendUsd / mergedPrs`. `activeAi` is distinct AI-active members
|
|
2907
|
+
on the team in the window (provider filter applied).
|
|
2908
|
+
operationId: getInsightsRecommendationsCostPerPr
|
|
2909
|
+
parameters:
|
|
2910
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2911
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2912
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2913
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2914
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2915
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2916
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2917
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2918
|
+
responses:
|
|
2919
|
+
"200":
|
|
2920
|
+
description: Cost per PR payload
|
|
2921
|
+
content:
|
|
2922
|
+
application/json:
|
|
2923
|
+
schema:
|
|
2924
|
+
$ref: "#/components/schemas/InsightsRecommendationsCostPerPrResponse"
|
|
2925
|
+
"400":
|
|
2926
|
+
description: Invalid filter or date range
|
|
2927
|
+
content:
|
|
2928
|
+
application/json:
|
|
2929
|
+
schema:
|
|
2930
|
+
type: object
|
|
2931
|
+
required: [error]
|
|
2932
|
+
properties:
|
|
2933
|
+
error: { type: string, example: invalid_query }
|
|
2934
|
+
"401":
|
|
2935
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2936
|
+
"403":
|
|
2937
|
+
$ref: "#/components/responses/Forbidden"
|
|
2938
|
+
"404":
|
|
2939
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2940
|
+
|
|
2941
|
+
/workspaces/{workspaceId}/insights/recommendations-page/adoption-gap:
|
|
2942
|
+
get:
|
|
2943
|
+
tags: [InsightsRecommendations]
|
|
2944
|
+
summary: Insights recommendations — AI adoption gap by team
|
|
2945
|
+
description: >
|
|
2946
|
+
Headcount vs AI-active contributors and per-team readiness/output. `readinessPct` is the
|
|
2947
|
+
mean latest overallScore of repos with matching `teamId` (workspace mean fallback).
|
|
2948
|
+
`outputPerEngPerWeek` is team merged PRs / headcount / weeks in window. `upliftPct`
|
|
2949
|
+
estimates additional PR volume if non-adopters matched leader-team output
|
|
2950
|
+
(teams with >50% adoption).
|
|
2951
|
+
operationId: getInsightsRecommendationsAdoptionGap
|
|
2952
|
+
parameters:
|
|
2953
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2954
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2955
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2956
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
2957
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
2958
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
2959
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
2960
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
2961
|
+
responses:
|
|
2962
|
+
"200":
|
|
2963
|
+
description: Adoption gap payload
|
|
2964
|
+
content:
|
|
2965
|
+
application/json:
|
|
2966
|
+
schema:
|
|
2967
|
+
$ref: "#/components/schemas/InsightsRecommendationsAdoptionGapResponse"
|
|
2968
|
+
"400":
|
|
2969
|
+
description: Invalid filter or date range
|
|
2970
|
+
content:
|
|
2971
|
+
application/json:
|
|
2972
|
+
schema:
|
|
2973
|
+
type: object
|
|
2974
|
+
required: [error]
|
|
2975
|
+
properties:
|
|
2976
|
+
error: { type: string, example: invalid_query }
|
|
2977
|
+
"401":
|
|
2978
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2979
|
+
"403":
|
|
2980
|
+
$ref: "#/components/responses/Forbidden"
|
|
2981
|
+
"404":
|
|
2982
|
+
description: Workspace does not exist or malformed workspaceId
|
|
2983
|
+
|
|
2984
|
+
/workspaces/{workspaceId}/insights/recommendations-page/recommendations:
|
|
2985
|
+
get:
|
|
2986
|
+
tags: [InsightsRecommendations]
|
|
2987
|
+
summary: Insights recommendations — deterministic action items
|
|
2988
|
+
description: >
|
|
2989
|
+
Deterministic rules engine (no LLM). Emits module-anchored recommendations with
|
|
2990
|
+
`moduleId` in {mod-spend-vs-output, mod-velocity-vs-quality, mod-review-bottleneck,
|
|
2991
|
+
mod-cost-per-pr, mod-adoption-gap}. Action items must cite one AI metric and one
|
|
2992
|
+
delivery metric in `observed`. Evidence chips use kinds user-spend|team|contributor|repo|module
|
|
2993
|
+
with real target ids when available.
|
|
2994
|
+
operationId: getInsightsRecommendationsRecommendations
|
|
2995
|
+
parameters:
|
|
2996
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2997
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDepartments"
|
|
2998
|
+
- $ref: "#/components/parameters/InsightsRecommendationsTeams"
|
|
2999
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateFrom"
|
|
3000
|
+
- $ref: "#/components/parameters/InsightsRecommendationsDateTo"
|
|
3001
|
+
- $ref: "#/components/parameters/InsightsRecommendationsProvider"
|
|
3002
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeUnmapped"
|
|
3003
|
+
- $ref: "#/components/parameters/InsightsRecommendationsIncludeBots"
|
|
3004
|
+
responses:
|
|
3005
|
+
"200":
|
|
3006
|
+
description: Recommendation items
|
|
3007
|
+
content:
|
|
3008
|
+
application/json:
|
|
3009
|
+
schema:
|
|
3010
|
+
$ref: "#/components/schemas/InsightsRecommendationsListResponse"
|
|
3011
|
+
"400":
|
|
3012
|
+
description: Invalid filter or date range
|
|
3013
|
+
content:
|
|
3014
|
+
application/json:
|
|
3015
|
+
schema:
|
|
3016
|
+
type: object
|
|
3017
|
+
required: [error]
|
|
3018
|
+
properties:
|
|
3019
|
+
error: { type: string, example: invalid_query }
|
|
3020
|
+
"401":
|
|
3021
|
+
$ref: "#/components/responses/Unauthorized"
|
|
3022
|
+
"403":
|
|
3023
|
+
$ref: "#/components/responses/Forbidden"
|
|
3024
|
+
"404":
|
|
3025
|
+
description: Workspace does not exist or malformed workspaceId
|
|
3026
|
+
|
|
2613
3027
|
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/members:
|
|
2614
3028
|
get:
|
|
2615
3029
|
tags: [Workspace]
|
|
@@ -7071,32 +7485,107 @@ components:
|
|
|
7071
7485
|
name: from
|
|
7072
7486
|
in: query
|
|
7073
7487
|
description: >
|
|
7074
|
-
Inclusive start of a daily window (`YYYY-MM-DD`). When set with `to`, overrides `rangeId`
|
|
7075
|
-
for day-mode responses (max 180 days).
|
|
7488
|
+
Inclusive start of a daily window (`YYYY-MM-DD`). When set with `to`, overrides `rangeId`
|
|
7489
|
+
for day-mode responses (max 180 days).
|
|
7490
|
+
schema:
|
|
7491
|
+
type: string
|
|
7492
|
+
format: date
|
|
7493
|
+
InsightsProductivityTo:
|
|
7494
|
+
name: to
|
|
7495
|
+
in: query
|
|
7496
|
+
description: >
|
|
7497
|
+
Inclusive end of a daily window (`YYYY-MM-DD`). When set with `from`, overrides `rangeId`
|
|
7498
|
+
for day-mode responses (max 180 days).
|
|
7499
|
+
schema:
|
|
7500
|
+
type: string
|
|
7501
|
+
format: date
|
|
7502
|
+
InsightsSdlcRangeId:
|
|
7503
|
+
name: rangeId
|
|
7504
|
+
in: query
|
|
7505
|
+
description: >
|
|
7506
|
+
Day-level Measure window. Presets: `7d`, `30d`, `90d`, `180d`. Custom inclusive
|
|
7507
|
+
calendar range: `cr:YYYY-MM-DD:YYYY-MM-DD` (max span 180 days).
|
|
7508
|
+
schema:
|
|
7509
|
+
type: string
|
|
7510
|
+
default: 30d
|
|
7511
|
+
example: 30d
|
|
7512
|
+
InsightsDepartmentFilter:
|
|
7513
|
+
name: department
|
|
7514
|
+
in: query
|
|
7515
|
+
description: >
|
|
7516
|
+
Department filter; send `All departments` to include every department. Scoped using
|
|
7517
|
+
imported `thinkai_org_structure` members when present, otherwise SPA org chart
|
|
7518
|
+
`department` nodes and their descendant teams. When neither source defines the
|
|
7519
|
+
requested department, insights return no scoped teams or contributors (not org-wide
|
|
7520
|
+
data).
|
|
7521
|
+
schema:
|
|
7522
|
+
type: string
|
|
7523
|
+
default: All departments
|
|
7524
|
+
InsightsRecommendationsDepartments:
|
|
7525
|
+
name: departments
|
|
7526
|
+
in: query
|
|
7527
|
+
description: >
|
|
7528
|
+
Org-chart department ids (repeat param or comma-separated). Empty/omitted = all departments.
|
|
7529
|
+
schema:
|
|
7530
|
+
type: array
|
|
7531
|
+
items:
|
|
7532
|
+
type: string
|
|
7533
|
+
style: form
|
|
7534
|
+
explode: true
|
|
7535
|
+
InsightsRecommendationsTeams:
|
|
7536
|
+
name: teams
|
|
7537
|
+
in: query
|
|
7538
|
+
description: >
|
|
7539
|
+
Org-chart team ids (repeat param or comma-separated). Empty/omitted = all teams in department scope.
|
|
7540
|
+
schema:
|
|
7541
|
+
type: array
|
|
7542
|
+
items:
|
|
7543
|
+
type: string
|
|
7544
|
+
style: form
|
|
7545
|
+
explode: true
|
|
7546
|
+
InsightsRecommendationsDateFrom:
|
|
7547
|
+
name: dateFrom
|
|
7548
|
+
in: query
|
|
7549
|
+
description: >
|
|
7550
|
+
Inclusive window start (`YYYY-MM-DD`). Required with `dateTo`. Maps to Measure day-mode
|
|
7551
|
+
custom range (`from`/`to`). Max span 180 days.
|
|
7552
|
+
required: true
|
|
7076
7553
|
schema:
|
|
7077
7554
|
type: string
|
|
7078
7555
|
format: date
|
|
7079
|
-
|
|
7080
|
-
name:
|
|
7556
|
+
InsightsRecommendationsDateTo:
|
|
7557
|
+
name: dateTo
|
|
7081
7558
|
in: query
|
|
7082
|
-
description:
|
|
7083
|
-
|
|
7084
|
-
for day-mode responses (max 180 days).
|
|
7559
|
+
description: Inclusive window end (`YYYY-MM-DD`). Required with `dateFrom`.
|
|
7560
|
+
required: true
|
|
7085
7561
|
schema:
|
|
7086
7562
|
type: string
|
|
7087
7563
|
format: date
|
|
7088
|
-
|
|
7089
|
-
name:
|
|
7564
|
+
InsightsRecommendationsProvider:
|
|
7565
|
+
name: provider
|
|
7090
7566
|
in: query
|
|
7091
7567
|
description: >
|
|
7092
|
-
|
|
7093
|
-
imported `thinkai_org_structure` members when present, otherwise SPA org chart
|
|
7094
|
-
`department` nodes and their descendant teams. When neither source defines the
|
|
7095
|
-
requested department, insights return no scoped teams or contributors (not org-wide
|
|
7096
|
-
data).
|
|
7568
|
+
AI provider ids (e.g. `cursor`, `copilot`). Empty/omitted = all configured providers.
|
|
7097
7569
|
schema:
|
|
7098
|
-
type:
|
|
7099
|
-
|
|
7570
|
+
type: array
|
|
7571
|
+
items:
|
|
7572
|
+
type: string
|
|
7573
|
+
style: form
|
|
7574
|
+
explode: true
|
|
7575
|
+
InsightsRecommendationsIncludeUnmapped:
|
|
7576
|
+
name: includeUnmapped
|
|
7577
|
+
in: query
|
|
7578
|
+
description: Include contributors / AI rows not mapped to a team.
|
|
7579
|
+
schema:
|
|
7580
|
+
type: boolean
|
|
7581
|
+
default: true
|
|
7582
|
+
InsightsRecommendationsIncludeBots:
|
|
7583
|
+
name: includeBots
|
|
7584
|
+
in: query
|
|
7585
|
+
description: Include bot accounts in PR/CI stats.
|
|
7586
|
+
schema:
|
|
7587
|
+
type: boolean
|
|
7588
|
+
default: false
|
|
7100
7589
|
PaginationLimit:
|
|
7101
7590
|
name: limit
|
|
7102
7591
|
in: query
|
|
@@ -14185,3 +14674,514 @@ components:
|
|
|
14185
14674
|
type: string
|
|
14186
14675
|
format: date-time
|
|
14187
14676
|
description: Timestamp of the most recent contributing run (UTC).
|
|
14677
|
+
|
|
14678
|
+
SdlcModuleId:
|
|
14679
|
+
type: string
|
|
14680
|
+
enum:
|
|
14681
|
+
- dora
|
|
14682
|
+
- ci-pipeline
|
|
14683
|
+
- collaboration-pr
|
|
14684
|
+
- security-risk
|
|
14685
|
+
- governance-architecture
|
|
14686
|
+
- financial-operational
|
|
14687
|
+
|
|
14688
|
+
SdlcMetricId:
|
|
14689
|
+
type: string
|
|
14690
|
+
enum:
|
|
14691
|
+
- dora-deployment-frequency
|
|
14692
|
+
- dora-lead-time
|
|
14693
|
+
- dora-cfr
|
|
14694
|
+
- dora-mttr
|
|
14695
|
+
- ci-success-rate
|
|
14696
|
+
- ci-duration-p50-p95
|
|
14697
|
+
- ci-flakiness
|
|
14698
|
+
- ci-queue-wait
|
|
14699
|
+
- ci-cache-hit
|
|
14700
|
+
- pr-review-time
|
|
14701
|
+
- pr-bus-factor
|
|
14702
|
+
- pr-size
|
|
14703
|
+
- pr-abandonment
|
|
14704
|
+
- pr-review-depth
|
|
14705
|
+
- pr-draft-duration
|
|
14706
|
+
- pr-merge-conflicts
|
|
14707
|
+
- pr-commit-density
|
|
14708
|
+
- sec-dependabot-backlog
|
|
14709
|
+
- sec-vuln-mttr
|
|
14710
|
+
- sec-secret-scanning
|
|
14711
|
+
- sec-self-approvals
|
|
14712
|
+
- sec-unreviewed-merge
|
|
14713
|
+
- gov-branch-protection
|
|
14714
|
+
- gov-stale-branches
|
|
14715
|
+
- gov-orphaned-repos
|
|
14716
|
+
- gov-readme-health
|
|
14717
|
+
- gov-codeowners
|
|
14718
|
+
- gov-issue-pr-linkage
|
|
14719
|
+
- fin-gha-minutes
|
|
14720
|
+
- fin-copilot-utilization
|
|
14721
|
+
- fin-org-inactivity
|
|
14722
|
+
- fin-env-drift
|
|
14723
|
+
- fin-release-cadence
|
|
14724
|
+
- fin-api-rate-limit
|
|
14725
|
+
|
|
14726
|
+
SdlcMetricDataStatus:
|
|
14727
|
+
type: string
|
|
14728
|
+
enum: [live, preview, unavailable]
|
|
14729
|
+
|
|
14730
|
+
SdlcMetricHealthStatus:
|
|
14731
|
+
type: string
|
|
14732
|
+
enum: [healthy, warning, critical, unknown]
|
|
14733
|
+
|
|
14734
|
+
SdlcBenchmarkBand:
|
|
14735
|
+
type: string
|
|
14736
|
+
enum: [elite, high, medium, low]
|
|
14737
|
+
|
|
14738
|
+
SdlcMetricTrendDto:
|
|
14739
|
+
type: object
|
|
14740
|
+
required: [direction]
|
|
14741
|
+
properties:
|
|
14742
|
+
direction:
|
|
14743
|
+
type: string
|
|
14744
|
+
enum: [up, down, flat]
|
|
14745
|
+
deltaPercent:
|
|
14746
|
+
type: number
|
|
14747
|
+
|
|
14748
|
+
SdlcDailySeriesPointDto:
|
|
14749
|
+
type: object
|
|
14750
|
+
required: [date, value]
|
|
14751
|
+
properties:
|
|
14752
|
+
date:
|
|
14753
|
+
type: string
|
|
14754
|
+
format: date
|
|
14755
|
+
description: Inclusive ISO calendar day (UTC).
|
|
14756
|
+
value:
|
|
14757
|
+
type: number
|
|
14758
|
+
|
|
14759
|
+
SdlcMetricDto:
|
|
14760
|
+
type: object
|
|
14761
|
+
required: [id, name, dataStatus, healthStatus, value, drilldownAvailable]
|
|
14762
|
+
properties:
|
|
14763
|
+
id:
|
|
14764
|
+
$ref: "#/components/schemas/SdlcMetricId"
|
|
14765
|
+
name:
|
|
14766
|
+
type: string
|
|
14767
|
+
dataStatus:
|
|
14768
|
+
$ref: "#/components/schemas/SdlcMetricDataStatus"
|
|
14769
|
+
healthStatus:
|
|
14770
|
+
$ref: "#/components/schemas/SdlcMetricHealthStatus"
|
|
14771
|
+
value:
|
|
14772
|
+
oneOf:
|
|
14773
|
+
- type: number
|
|
14774
|
+
- type: string
|
|
14775
|
+
nullable: true
|
|
14776
|
+
unit:
|
|
14777
|
+
type: string
|
|
14778
|
+
secondaryValue:
|
|
14779
|
+
oneOf:
|
|
14780
|
+
- type: number
|
|
14781
|
+
- type: string
|
|
14782
|
+
nullable: true
|
|
14783
|
+
secondaryLabel:
|
|
14784
|
+
type: string
|
|
14785
|
+
trend:
|
|
14786
|
+
$ref: "#/components/schemas/SdlcMetricTrendDto"
|
|
14787
|
+
benchmarkBand:
|
|
14788
|
+
$ref: "#/components/schemas/SdlcBenchmarkBand"
|
|
14789
|
+
drilldownAvailable:
|
|
14790
|
+
type: boolean
|
|
14791
|
+
dailySeries:
|
|
14792
|
+
type: array
|
|
14793
|
+
items:
|
|
14794
|
+
$ref: "#/components/schemas/SdlcDailySeriesPointDto"
|
|
14795
|
+
unavailableReason:
|
|
14796
|
+
type: string
|
|
14797
|
+
|
|
14798
|
+
SdlcModuleDto:
|
|
14799
|
+
type: object
|
|
14800
|
+
required: [id, name, metrics]
|
|
14801
|
+
properties:
|
|
14802
|
+
id:
|
|
14803
|
+
$ref: "#/components/schemas/SdlcModuleId"
|
|
14804
|
+
name:
|
|
14805
|
+
type: string
|
|
14806
|
+
metrics:
|
|
14807
|
+
type: array
|
|
14808
|
+
items:
|
|
14809
|
+
$ref: "#/components/schemas/SdlcMetricDto"
|
|
14810
|
+
|
|
14811
|
+
SdlcOverviewDto:
|
|
14812
|
+
type: object
|
|
14813
|
+
required: [rangeId, from, to, department, team, repoIds, asOf, modules]
|
|
14814
|
+
properties:
|
|
14815
|
+
rangeId:
|
|
14816
|
+
type: string
|
|
14817
|
+
from:
|
|
14818
|
+
type: string
|
|
14819
|
+
format: date
|
|
14820
|
+
to:
|
|
14821
|
+
type: string
|
|
14822
|
+
format: date
|
|
14823
|
+
department:
|
|
14824
|
+
type: string
|
|
14825
|
+
team:
|
|
14826
|
+
type: string
|
|
14827
|
+
repoIds:
|
|
14828
|
+
type: array
|
|
14829
|
+
items:
|
|
14830
|
+
type: string
|
|
14831
|
+
asOf:
|
|
14832
|
+
type: string
|
|
14833
|
+
format: date-time
|
|
14834
|
+
modules:
|
|
14835
|
+
type: array
|
|
14836
|
+
items:
|
|
14837
|
+
$ref: "#/components/schemas/SdlcModuleDto"
|
|
14838
|
+
|
|
14839
|
+
SdlcDrilldownItemDto:
|
|
14840
|
+
type: object
|
|
14841
|
+
required: [id, title]
|
|
14842
|
+
properties:
|
|
14843
|
+
id:
|
|
14844
|
+
type: string
|
|
14845
|
+
title:
|
|
14846
|
+
type: string
|
|
14847
|
+
subtitle:
|
|
14848
|
+
type: string
|
|
14849
|
+
url:
|
|
14850
|
+
type: string
|
|
14851
|
+
format: uri
|
|
14852
|
+
occurredAt:
|
|
14853
|
+
type: string
|
|
14854
|
+
format: date-time
|
|
14855
|
+
metadata:
|
|
14856
|
+
type: object
|
|
14857
|
+
additionalProperties:
|
|
14858
|
+
oneOf:
|
|
14859
|
+
- type: string
|
|
14860
|
+
- type: number
|
|
14861
|
+
|
|
14862
|
+
SdlcDrilldownDto:
|
|
14863
|
+
type: object
|
|
14864
|
+
required: [metricId, items]
|
|
14865
|
+
properties:
|
|
14866
|
+
metricId:
|
|
14867
|
+
$ref: "#/components/schemas/SdlcMetricId"
|
|
14868
|
+
items:
|
|
14869
|
+
type: array
|
|
14870
|
+
items:
|
|
14871
|
+
$ref: "#/components/schemas/SdlcDrilldownItemDto"
|
|
14872
|
+
nextCursor:
|
|
14873
|
+
type: string
|
|
14874
|
+
|
|
14875
|
+
InsightsResponseMeta:
|
|
14876
|
+
type: object
|
|
14877
|
+
required: [syncedAt, isMock]
|
|
14878
|
+
properties:
|
|
14879
|
+
syncedAt:
|
|
14880
|
+
type: string
|
|
14881
|
+
format: date-time
|
|
14882
|
+
description: ISO timestamp when numbers were computed server-side
|
|
14883
|
+
isMock:
|
|
14884
|
+
type: boolean
|
|
14885
|
+
description: Must be false for production handlers
|
|
14886
|
+
enum: [false]
|
|
14887
|
+
|
|
14888
|
+
InsightsVerdictStatus:
|
|
14889
|
+
type: string
|
|
14890
|
+
enum: [healthy, watch, at-risk]
|
|
14891
|
+
|
|
14892
|
+
InsightsRecommendationsVerdictSummary:
|
|
14893
|
+
type: object
|
|
14894
|
+
required:
|
|
14895
|
+
- productivityMultiplier
|
|
14896
|
+
- productivityStatus
|
|
14897
|
+
- ciFailRatePct
|
|
14898
|
+
- qualityStatus
|
|
14899
|
+
- spendPerMergedPrUsd
|
|
14900
|
+
- spendPerMergedPrPrevUsd
|
|
14901
|
+
- costStatus
|
|
14902
|
+
properties:
|
|
14903
|
+
productivityMultiplier:
|
|
14904
|
+
type: number
|
|
14905
|
+
description: >
|
|
14906
|
+
Merged-PR volume ratio vs prior equal-length window (current/prior).
|
|
14907
|
+
When priorMergedPrs is 0, value is 1.0 and productivityStatus is watch.
|
|
14908
|
+
productivityStatus:
|
|
14909
|
+
$ref: "#/components/schemas/InsightsVerdictStatus"
|
|
14910
|
+
ciFailRatePct:
|
|
14911
|
+
type: number
|
|
14912
|
+
qualityStatus:
|
|
14913
|
+
$ref: "#/components/schemas/InsightsVerdictStatus"
|
|
14914
|
+
spendPerMergedPrUsd:
|
|
14915
|
+
type: number
|
|
14916
|
+
spendPerMergedPrPrevUsd:
|
|
14917
|
+
type: number
|
|
14918
|
+
costStatus:
|
|
14919
|
+
$ref: "#/components/schemas/InsightsVerdictStatus"
|
|
14920
|
+
|
|
14921
|
+
InsightsRecommendationsVerdictSummaryResponse:
|
|
14922
|
+
allOf:
|
|
14923
|
+
- $ref: "#/components/schemas/InsightsRecommendationsVerdictSummary"
|
|
14924
|
+
- type: object
|
|
14925
|
+
required: [_meta]
|
|
14926
|
+
properties:
|
|
14927
|
+
_meta:
|
|
14928
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
14929
|
+
|
|
14930
|
+
InsightsRoiEngineerPoint:
|
|
14931
|
+
type: object
|
|
14932
|
+
required: [id, name, team, spendUsd, mergedPrs]
|
|
14933
|
+
properties:
|
|
14934
|
+
id: { type: string }
|
|
14935
|
+
name: { type: string }
|
|
14936
|
+
team: { type: string }
|
|
14937
|
+
spendUsd: { type: number }
|
|
14938
|
+
mergedPrs: { type: number }
|
|
14939
|
+
|
|
14940
|
+
InsightsRecommendationsRoiQuadrant:
|
|
14941
|
+
type: object
|
|
14942
|
+
required: [medianSpendUsd, medianMergedPrs, engineers, correlationHint]
|
|
14943
|
+
properties:
|
|
14944
|
+
medianSpendUsd: { type: number }
|
|
14945
|
+
medianMergedPrs: { type: number }
|
|
14946
|
+
engineers:
|
|
14947
|
+
type: array
|
|
14948
|
+
items:
|
|
14949
|
+
$ref: "#/components/schemas/InsightsRoiEngineerPoint"
|
|
14950
|
+
correlationHint: { type: string }
|
|
14951
|
+
|
|
14952
|
+
InsightsRecommendationsRoiQuadrantResponse:
|
|
14953
|
+
allOf:
|
|
14954
|
+
- $ref: "#/components/schemas/InsightsRecommendationsRoiQuadrant"
|
|
14955
|
+
- type: object
|
|
14956
|
+
required: [_meta]
|
|
14957
|
+
properties:
|
|
14958
|
+
_meta:
|
|
14959
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
14960
|
+
|
|
14961
|
+
InsightsVelocityQualityWeek:
|
|
14962
|
+
type: object
|
|
14963
|
+
required: [weekStartIso, mergedPrs, ciFailRatePct]
|
|
14964
|
+
properties:
|
|
14965
|
+
weekStartIso: { type: string, format: date }
|
|
14966
|
+
mergedPrs: { type: number }
|
|
14967
|
+
ciFailRatePct: { type: number }
|
|
14968
|
+
|
|
14969
|
+
InsightsRecommendationsVelocityQuality:
|
|
14970
|
+
type: object
|
|
14971
|
+
required: [weeks, targetFailRatePct, volumeGrowthPct]
|
|
14972
|
+
properties:
|
|
14973
|
+
weeks:
|
|
14974
|
+
type: array
|
|
14975
|
+
items:
|
|
14976
|
+
$ref: "#/components/schemas/InsightsVelocityQualityWeek"
|
|
14977
|
+
targetFailRatePct: { type: number }
|
|
14978
|
+
volumeGrowthPct: { type: number }
|
|
14979
|
+
|
|
14980
|
+
InsightsRecommendationsVelocityQualityResponse:
|
|
14981
|
+
allOf:
|
|
14982
|
+
- $ref: "#/components/schemas/InsightsRecommendationsVelocityQuality"
|
|
14983
|
+
- type: object
|
|
14984
|
+
required: [_meta]
|
|
14985
|
+
properties:
|
|
14986
|
+
_meta:
|
|
14987
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
14988
|
+
|
|
14989
|
+
InsightsReviewStageId:
|
|
14990
|
+
type: string
|
|
14991
|
+
enum: [open-review, review-approval, approval-merge, merged]
|
|
14992
|
+
|
|
14993
|
+
InsightsReviewStage:
|
|
14994
|
+
type: object
|
|
14995
|
+
required: [id, name, medianHours, trendPct]
|
|
14996
|
+
properties:
|
|
14997
|
+
id:
|
|
14998
|
+
$ref: "#/components/schemas/InsightsReviewStageId"
|
|
14999
|
+
name: { type: string }
|
|
15000
|
+
medianHours:
|
|
15001
|
+
type: number
|
|
15002
|
+
description: Wait hours for funnel stages; 0 for the merged volume stage
|
|
15003
|
+
trendPct: { type: number }
|
|
15004
|
+
|
|
15005
|
+
InsightsReviewerLoadItem:
|
|
15006
|
+
type: object
|
|
15007
|
+
required: [id, name, reviewsCount, sharePct]
|
|
15008
|
+
properties:
|
|
15009
|
+
id: { type: string }
|
|
15010
|
+
name: { type: string }
|
|
15011
|
+
reviewsCount: { type: number }
|
|
15012
|
+
sharePct: { type: number }
|
|
15013
|
+
|
|
15014
|
+
InsightsRecommendationsReviewPipeline:
|
|
15015
|
+
type: object
|
|
15016
|
+
required: [stages, bottleneckStageId, reviewerLoad]
|
|
15017
|
+
properties:
|
|
15018
|
+
stages:
|
|
15019
|
+
type: array
|
|
15020
|
+
items:
|
|
15021
|
+
$ref: "#/components/schemas/InsightsReviewStage"
|
|
15022
|
+
bottleneckStageId:
|
|
15023
|
+
$ref: "#/components/schemas/InsightsReviewStageId"
|
|
15024
|
+
reviewerLoad:
|
|
15025
|
+
type: array
|
|
15026
|
+
items:
|
|
15027
|
+
$ref: "#/components/schemas/InsightsReviewerLoadItem"
|
|
15028
|
+
|
|
15029
|
+
InsightsRecommendationsReviewPipelineResponse:
|
|
15030
|
+
allOf:
|
|
15031
|
+
- $ref: "#/components/schemas/InsightsRecommendationsReviewPipeline"
|
|
15032
|
+
- type: object
|
|
15033
|
+
required: [_meta]
|
|
15034
|
+
properties:
|
|
15035
|
+
_meta:
|
|
15036
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
15037
|
+
|
|
15038
|
+
InsightsCostPerPrTeam:
|
|
15039
|
+
type: object
|
|
15040
|
+
required: [id, name, activeAi, spendUsd, mergedPrs, costPerPrUsd, changePct]
|
|
15041
|
+
properties:
|
|
15042
|
+
id: { type: string }
|
|
15043
|
+
name: { type: string }
|
|
15044
|
+
activeAi: { type: number }
|
|
15045
|
+
spendUsd: { type: number }
|
|
15046
|
+
mergedPrs: { type: number }
|
|
15047
|
+
costPerPrUsd: { type: number }
|
|
15048
|
+
changePct: { type: number }
|
|
15049
|
+
|
|
15050
|
+
InsightsRecommendationsCostPerPr:
|
|
15051
|
+
type: object
|
|
15052
|
+
required: [orgAvgCostUsd, orgAvgPrevUsd, teams]
|
|
15053
|
+
properties:
|
|
15054
|
+
orgAvgCostUsd: { type: number }
|
|
15055
|
+
orgAvgPrevUsd: { type: number }
|
|
15056
|
+
teams:
|
|
15057
|
+
type: array
|
|
15058
|
+
items:
|
|
15059
|
+
$ref: "#/components/schemas/InsightsCostPerPrTeam"
|
|
15060
|
+
|
|
15061
|
+
InsightsRecommendationsCostPerPrResponse:
|
|
15062
|
+
allOf:
|
|
15063
|
+
- $ref: "#/components/schemas/InsightsRecommendationsCostPerPr"
|
|
15064
|
+
- type: object
|
|
15065
|
+
required: [_meta]
|
|
15066
|
+
properties:
|
|
15067
|
+
_meta:
|
|
15068
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
15069
|
+
|
|
15070
|
+
InsightsAdoptionTeam:
|
|
15071
|
+
type: object
|
|
15072
|
+
required: [id, name, activeAi, totalMembers, readinessPct, outputPerEngPerWeek]
|
|
15073
|
+
properties:
|
|
15074
|
+
id: { type: string }
|
|
15075
|
+
name: { type: string }
|
|
15076
|
+
activeAi: { type: number }
|
|
15077
|
+
totalMembers: { type: number }
|
|
15078
|
+
readinessPct: { type: number }
|
|
15079
|
+
outputPerEngPerWeek: { type: number }
|
|
15080
|
+
|
|
15081
|
+
InsightsRecommendationsAdoptionGap:
|
|
15082
|
+
type: object
|
|
15083
|
+
required: [totalContributors, activeContributors, upliftPct, teams]
|
|
15084
|
+
properties:
|
|
15085
|
+
totalContributors: { type: number }
|
|
15086
|
+
activeContributors: { type: number }
|
|
15087
|
+
upliftPct: { type: number }
|
|
15088
|
+
teams:
|
|
15089
|
+
type: array
|
|
15090
|
+
items:
|
|
15091
|
+
$ref: "#/components/schemas/InsightsAdoptionTeam"
|
|
15092
|
+
|
|
15093
|
+
InsightsRecommendationsAdoptionGapResponse:
|
|
15094
|
+
allOf:
|
|
15095
|
+
- $ref: "#/components/schemas/InsightsRecommendationsAdoptionGap"
|
|
15096
|
+
- type: object
|
|
15097
|
+
required: [_meta]
|
|
15098
|
+
properties:
|
|
15099
|
+
_meta:
|
|
15100
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|
|
15101
|
+
|
|
15102
|
+
InsightsRecommendationModuleId:
|
|
15103
|
+
type: string
|
|
15104
|
+
enum:
|
|
15105
|
+
- mod-spend-vs-output
|
|
15106
|
+
- mod-velocity-vs-quality
|
|
15107
|
+
- mod-review-bottleneck
|
|
15108
|
+
- mod-cost-per-pr
|
|
15109
|
+
- mod-adoption-gap
|
|
15110
|
+
|
|
15111
|
+
InsightsRecommendationImpact:
|
|
15112
|
+
type: string
|
|
15113
|
+
enum: [high, medium]
|
|
15114
|
+
|
|
15115
|
+
InsightsRecommendationTone:
|
|
15116
|
+
type: string
|
|
15117
|
+
enum: [action, no-action]
|
|
15118
|
+
|
|
15119
|
+
InsightsEvidenceLinkKind:
|
|
15120
|
+
type: string
|
|
15121
|
+
enum: [user-spend, team, contributor, repo, module]
|
|
15122
|
+
|
|
15123
|
+
InsightsEvidenceChip:
|
|
15124
|
+
type: object
|
|
15125
|
+
required: [label, kind, targetId]
|
|
15126
|
+
properties:
|
|
15127
|
+
label: { type: string }
|
|
15128
|
+
kind:
|
|
15129
|
+
$ref: "#/components/schemas/InsightsEvidenceLinkKind"
|
|
15130
|
+
targetId: { type: string }
|
|
15131
|
+
|
|
15132
|
+
InsightsRecommendationEvidenceGroup:
|
|
15133
|
+
type: object
|
|
15134
|
+
required: [title, chips]
|
|
15135
|
+
properties:
|
|
15136
|
+
title: { type: string }
|
|
15137
|
+
chips:
|
|
15138
|
+
type: array
|
|
15139
|
+
items:
|
|
15140
|
+
$ref: "#/components/schemas/InsightsEvidenceChip"
|
|
15141
|
+
|
|
15142
|
+
InsightsRecommendationDto:
|
|
15143
|
+
type: object
|
|
15144
|
+
required:
|
|
15145
|
+
- moduleId
|
|
15146
|
+
- moduleName
|
|
15147
|
+
- tone
|
|
15148
|
+
- impact
|
|
15149
|
+
- headline
|
|
15150
|
+
- observed
|
|
15151
|
+
- action
|
|
15152
|
+
- benefit
|
|
15153
|
+
- confidencePct
|
|
15154
|
+
- evidence
|
|
15155
|
+
properties:
|
|
15156
|
+
moduleId:
|
|
15157
|
+
$ref: "#/components/schemas/InsightsRecommendationModuleId"
|
|
15158
|
+
moduleName: { type: string }
|
|
15159
|
+
tone:
|
|
15160
|
+
$ref: "#/components/schemas/InsightsRecommendationTone"
|
|
15161
|
+
impact:
|
|
15162
|
+
$ref: "#/components/schemas/InsightsRecommendationImpact"
|
|
15163
|
+
headline: { type: string }
|
|
15164
|
+
observed:
|
|
15165
|
+
type: string
|
|
15166
|
+
description: For tone=action must cite one AI metric and one delivery metric
|
|
15167
|
+
action: { type: string }
|
|
15168
|
+
benefit: { type: string }
|
|
15169
|
+
confidencePct:
|
|
15170
|
+
type: number
|
|
15171
|
+
minimum: 0
|
|
15172
|
+
maximum: 100
|
|
15173
|
+
evidence:
|
|
15174
|
+
type: array
|
|
15175
|
+
items:
|
|
15176
|
+
$ref: "#/components/schemas/InsightsRecommendationEvidenceGroup"
|
|
15177
|
+
|
|
15178
|
+
InsightsRecommendationsListResponse:
|
|
15179
|
+
type: object
|
|
15180
|
+
required: [items, _meta]
|
|
15181
|
+
properties:
|
|
15182
|
+
items:
|
|
15183
|
+
type: array
|
|
15184
|
+
items:
|
|
15185
|
+
$ref: "#/components/schemas/InsightsRecommendationDto"
|
|
15186
|
+
_meta:
|
|
15187
|
+
$ref: "#/components/schemas/InsightsResponseMeta"
|