@thinkai/tai-api-contract 2.5.1 → 2.5.16
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 +1418 -26
- package/dist/generated/openapi.d.ts.map +1 -1
- package/dist/index.d.ts +317 -0
- package/dist/index.d.ts.map +1 -1
- package/openapi/openapi.yaml +2906 -1200
- package/package.json +1 -1
- package/src/generated/openapi.ts +1418 -26
- package/src/index.ts +353 -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.5.
|
|
4
|
+
version: 2.5.16
|
|
5
5
|
description: >
|
|
6
6
|
Contract surface for the AI Driven SDLC backend used by ThinkAI.
|
|
7
7
|
Workspace-scoped routes use `/workspaces/{workspaceId}/...`.
|
|
@@ -574,587 +574,779 @@ paths:
|
|
|
574
574
|
"401":
|
|
575
575
|
$ref: "#/components/responses/Unauthorized"
|
|
576
576
|
|
|
577
|
-
/workspaces/{workspaceId}/
|
|
577
|
+
/workspaces/{workspaceId}/insights/productivity-insights/aggregated-teams:
|
|
578
578
|
get:
|
|
579
|
-
tags: [
|
|
580
|
-
summary:
|
|
581
|
-
|
|
579
|
+
tags: [Workspace]
|
|
580
|
+
summary: Productivity insights — aggregated team weekly metrics
|
|
581
|
+
description: >
|
|
582
|
+
Team-level rollup for Productivity insights (Aggregated Teams view on /phase-c/c4).
|
|
583
|
+
Returns weekly merged PR counts and fail rates per engineering team, filtered by the
|
|
584
|
+
same department, team, and range controls as the Measure UI.
|
|
585
|
+
operationId: getProductivityInsightsAggregatedTeams
|
|
582
586
|
parameters:
|
|
583
587
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
588
|
+
- name: rangeId
|
|
589
|
+
in: query
|
|
590
|
+
description: Measure time range (maps to weekly bucket count).
|
|
591
|
+
schema:
|
|
592
|
+
type: string
|
|
593
|
+
enum: [4w, 8w, q]
|
|
594
|
+
default: 4w
|
|
595
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
596
|
+
- name: team
|
|
597
|
+
in: query
|
|
598
|
+
description: Team name filter; send `All teams` to include every team.
|
|
599
|
+
schema:
|
|
600
|
+
type: string
|
|
601
|
+
default: All teams
|
|
602
|
+
- name: windowEnd
|
|
603
|
+
in: query
|
|
604
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
605
|
+
schema:
|
|
606
|
+
type: string
|
|
607
|
+
format: date-time
|
|
584
608
|
responses:
|
|
585
609
|
"200":
|
|
586
|
-
description:
|
|
587
|
-
Company profile DTO, or JSON `null` when the workspace exists but no profile
|
|
588
|
-
has been saved yet. Clients should treat `null` as the empty initial state
|
|
589
|
-
(the wizard renders blank inputs); they MUST NOT treat the absence of a
|
|
590
|
-
saved profile as a 404.
|
|
610
|
+
description: Aggregated team productivity series
|
|
591
611
|
content:
|
|
592
612
|
application/json:
|
|
593
613
|
schema:
|
|
594
|
-
$ref: "#/components/schemas/
|
|
595
|
-
examples:
|
|
596
|
-
sample:
|
|
597
|
-
summary: Saved profile
|
|
598
|
-
value:
|
|
599
|
-
companyName: Acme
|
|
600
|
-
industry: software
|
|
601
|
-
companySize: "51-200"
|
|
602
|
-
engineeringHC: "42"
|
|
603
|
-
headquarters: "Austin, TX"
|
|
614
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsDto"
|
|
604
615
|
"400":
|
|
605
|
-
description:
|
|
616
|
+
description: Invalid query parameters
|
|
606
617
|
content:
|
|
607
618
|
application/json:
|
|
608
619
|
schema:
|
|
609
|
-
|
|
620
|
+
type: object
|
|
621
|
+
required: [error]
|
|
622
|
+
properties:
|
|
623
|
+
error: { type: string, example: invalid_query }
|
|
610
624
|
"401":
|
|
611
625
|
$ref: "#/components/responses/Unauthorized"
|
|
612
626
|
"403":
|
|
613
627
|
$ref: "#/components/responses/Forbidden"
|
|
614
628
|
"404":
|
|
615
|
-
description: Workspace does not exist
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
tags: [CompanyProfile]
|
|
622
|
-
summary: Upsert company profile
|
|
623
|
-
operationId: putCompanyProfile
|
|
629
|
+
description: Workspace does not exist or malformed workspaceId
|
|
630
|
+
|
|
631
|
+
/workspaces/{workspaceId}/insights/productivity-insights/merged-pr-trends:
|
|
632
|
+
get:
|
|
633
|
+
tags: [Workspace]
|
|
634
|
+
summary: Productivity insights — merged PR trends (portfolio + contributors)
|
|
624
635
|
description: >
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
636
|
+
Weekly merged PR counts for the Measure "Merged PR Trends" widget on /phase-c/c4
|
|
637
|
+
Individual Contributors. Returns a portfolio aggregate series plus per-contributor weekly
|
|
638
|
+
counts, filtered by the same department, team, and range controls as the Measure UI.
|
|
639
|
+
operationId: getProductivityInsightsMergedPrTrends
|
|
629
640
|
parameters:
|
|
630
641
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
642
|
+
- name: rangeId
|
|
643
|
+
in: query
|
|
644
|
+
description: Measure time range (maps to weekly bucket count).
|
|
645
|
+
schema:
|
|
646
|
+
type: string
|
|
647
|
+
enum: [4w, 8w, q]
|
|
648
|
+
default: 4w
|
|
649
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
650
|
+
- name: team
|
|
651
|
+
in: query
|
|
652
|
+
description: Team name filter; send `All teams` to include every team.
|
|
653
|
+
schema:
|
|
654
|
+
type: string
|
|
655
|
+
default: All teams
|
|
656
|
+
- name: windowEnd
|
|
657
|
+
in: query
|
|
658
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
659
|
+
schema:
|
|
660
|
+
type: string
|
|
661
|
+
format: date-time
|
|
637
662
|
responses:
|
|
638
|
-
"
|
|
639
|
-
description:
|
|
663
|
+
"200":
|
|
664
|
+
description: Portfolio and per-contributor merged PR weekly series
|
|
665
|
+
content:
|
|
666
|
+
application/json:
|
|
667
|
+
schema:
|
|
668
|
+
$ref: "#/components/schemas/ProductivityInsightsMergedPrTrendsDto"
|
|
640
669
|
"400":
|
|
641
|
-
description:
|
|
670
|
+
description: Invalid query parameters
|
|
642
671
|
content:
|
|
643
672
|
application/json:
|
|
644
673
|
schema:
|
|
645
|
-
|
|
674
|
+
type: object
|
|
675
|
+
required: [error]
|
|
676
|
+
properties:
|
|
677
|
+
error: { type: string, example: invalid_query }
|
|
646
678
|
"401":
|
|
647
679
|
$ref: "#/components/responses/Unauthorized"
|
|
648
680
|
"403":
|
|
649
681
|
$ref: "#/components/responses/Forbidden"
|
|
650
682
|
"404":
|
|
651
|
-
description: Workspace does not exist
|
|
652
|
-
content:
|
|
653
|
-
application/json:
|
|
654
|
-
schema:
|
|
655
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
683
|
+
description: Workspace does not exist or malformed workspaceId
|
|
656
684
|
|
|
657
|
-
/workspaces/{workspaceId}/
|
|
685
|
+
/workspaces/{workspaceId}/insights/productivity-insights/teams:
|
|
658
686
|
get:
|
|
659
|
-
tags: [
|
|
660
|
-
summary:
|
|
661
|
-
operationId: getWorkspaceGithubInstallationStatus
|
|
687
|
+
tags: [Workspace]
|
|
688
|
+
summary: Productivity insights — top teams and team drilldown
|
|
662
689
|
description: >
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
690
|
+
Without `teamId`: returns the top-ranked teams by average weekly merged PR count for the
|
|
691
|
+
Measure **Top teams** widget on /phase-c/c4 and /phase-c/c7. With `teamId`: returns weekly
|
|
692
|
+
rollup and summary for a single team (powers `/phase-c/c4/teams/:teamId` drilldown).
|
|
693
|
+
operationId: getProductivityInsightsTeams
|
|
666
694
|
parameters:
|
|
667
695
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
668
|
-
- name:
|
|
696
|
+
- name: teamId
|
|
669
697
|
in: query
|
|
670
|
-
|
|
671
|
-
|
|
698
|
+
description: >
|
|
699
|
+
When set, return drilldown for this org-chart team id instead of the top-team list.
|
|
672
700
|
schema:
|
|
673
|
-
type:
|
|
674
|
-
|
|
701
|
+
type: string
|
|
702
|
+
- name: limit
|
|
703
|
+
in: query
|
|
704
|
+
description: Maximum top-team rows when `teamId` is omitted (UI default 3).
|
|
705
|
+
schema:
|
|
706
|
+
type: integer
|
|
707
|
+
minimum: 1
|
|
708
|
+
maximum: 10
|
|
709
|
+
default: 3
|
|
710
|
+
- name: rangeId
|
|
711
|
+
in: query
|
|
712
|
+
description: Measure time range (maps to weekly bucket count).
|
|
713
|
+
schema:
|
|
714
|
+
type: string
|
|
715
|
+
enum: [4w, 8w, q]
|
|
716
|
+
default: 4w
|
|
717
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
718
|
+
- name: team
|
|
719
|
+
in: query
|
|
720
|
+
description: Team name filter; send `All teams` to include every team.
|
|
721
|
+
schema:
|
|
722
|
+
type: string
|
|
723
|
+
default: All teams
|
|
724
|
+
- name: windowEnd
|
|
725
|
+
in: query
|
|
726
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
727
|
+
schema:
|
|
728
|
+
type: string
|
|
729
|
+
format: date-time
|
|
675
730
|
responses:
|
|
676
731
|
"200":
|
|
677
|
-
description:
|
|
732
|
+
description: Top teams list or single-team drilldown
|
|
678
733
|
content:
|
|
679
734
|
application/json:
|
|
680
735
|
schema:
|
|
681
|
-
$ref: "#/components/schemas/
|
|
736
|
+
$ref: "#/components/schemas/ProductivityInsightsTeamsResponseDto"
|
|
737
|
+
"400":
|
|
738
|
+
description: Invalid query parameters
|
|
739
|
+
content:
|
|
740
|
+
application/json:
|
|
741
|
+
schema:
|
|
742
|
+
type: object
|
|
743
|
+
required: [error]
|
|
744
|
+
properties:
|
|
745
|
+
error: { type: string, example: invalid_query }
|
|
682
746
|
"401":
|
|
683
747
|
$ref: "#/components/responses/Unauthorized"
|
|
684
748
|
"403":
|
|
685
749
|
$ref: "#/components/responses/Forbidden"
|
|
686
750
|
"404":
|
|
687
|
-
description: Workspace
|
|
688
|
-
content:
|
|
689
|
-
application/json:
|
|
690
|
-
schema:
|
|
691
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
751
|
+
description: Workspace or team not found
|
|
692
752
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
753
|
+
/workspaces/{workspaceId}/insights/productivity-insights/contributors/{contributorId}:
|
|
754
|
+
get:
|
|
755
|
+
tags: [Workspace]
|
|
756
|
+
summary: Productivity insights — contributor drilldown
|
|
697
757
|
description: >
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
758
|
+
Weekly and daily activity rollups for a single contributor on
|
|
759
|
+
`/phase-c/c4/contributors/:id`. Distributes weekly merged PR counts from
|
|
760
|
+
precomputed person metrics across weekdays; includes fail-rate signals and
|
|
761
|
+
period-over-period summary deltas. Uses org-chart person ids (typically email).
|
|
762
|
+
operationId: getProductivityInsightsContributor
|
|
703
763
|
parameters:
|
|
704
764
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
705
|
-
- name:
|
|
765
|
+
- name: contributorId
|
|
766
|
+
in: path
|
|
767
|
+
required: true
|
|
768
|
+
description: Org-chart person id (e.g. email from `person_id` external id).
|
|
769
|
+
schema:
|
|
770
|
+
type: string
|
|
771
|
+
- name: rangeId
|
|
706
772
|
in: query
|
|
707
|
-
|
|
708
|
-
description: Optional installation id to disconnect a single linked installation.
|
|
773
|
+
description: Measure time range (maps to weekly bucket count).
|
|
709
774
|
schema:
|
|
710
775
|
type: string
|
|
711
|
-
|
|
776
|
+
enum: [4w, 8w, q]
|
|
777
|
+
default: 4w
|
|
778
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
779
|
+
- name: team
|
|
712
780
|
in: query
|
|
713
|
-
|
|
714
|
-
description: When true, disconnect all linked GitHub installations for this workspace.
|
|
781
|
+
description: Team name filter; send `All teams` to include every team.
|
|
715
782
|
schema:
|
|
716
|
-
type:
|
|
783
|
+
type: string
|
|
784
|
+
default: All teams
|
|
785
|
+
- name: windowEnd
|
|
786
|
+
in: query
|
|
787
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
788
|
+
schema:
|
|
789
|
+
type: string
|
|
790
|
+
format: date-time
|
|
717
791
|
responses:
|
|
718
|
-
"
|
|
719
|
-
description:
|
|
792
|
+
"200":
|
|
793
|
+
description: Contributor activity drilldown
|
|
794
|
+
content:
|
|
795
|
+
application/json:
|
|
796
|
+
schema:
|
|
797
|
+
$ref: "#/components/schemas/ProductivityInsightsContributorDetailDto"
|
|
798
|
+
"400":
|
|
799
|
+
description: Invalid query parameters
|
|
800
|
+
content:
|
|
801
|
+
application/json:
|
|
802
|
+
schema:
|
|
803
|
+
type: object
|
|
804
|
+
required: [error]
|
|
805
|
+
properties:
|
|
806
|
+
error: { type: string, example: invalid_query }
|
|
720
807
|
"401":
|
|
721
808
|
$ref: "#/components/responses/Unauthorized"
|
|
722
809
|
"403":
|
|
723
810
|
$ref: "#/components/responses/Forbidden"
|
|
724
811
|
"404":
|
|
725
|
-
description: Workspace
|
|
726
|
-
content:
|
|
727
|
-
application/json:
|
|
728
|
-
schema:
|
|
729
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
812
|
+
description: Workspace or contributor not found
|
|
730
813
|
|
|
731
|
-
/workspaces/{workspaceId}/
|
|
732
|
-
|
|
733
|
-
tags: [
|
|
734
|
-
summary:
|
|
735
|
-
operationId: postGithubInstallUrl
|
|
814
|
+
/workspaces/{workspaceId}/insights/productivity-insights/needs-attention:
|
|
815
|
+
get:
|
|
816
|
+
tags: [Workspace]
|
|
817
|
+
summary: Productivity insights — needs attention (bottom performers)
|
|
736
818
|
description: >
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
819
|
+
Bottom performers for the Measure "Needs attention" widget on /phase-c/c4
|
|
820
|
+
(LeadersLaggards laggards column). Returns the lowest-ranked teams or contributors
|
|
821
|
+
by average weekly merged PR count for the selected filters and range.
|
|
822
|
+
operationId: getProductivityInsightsNeedsAttention
|
|
741
823
|
parameters:
|
|
742
824
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
825
|
+
- name: entityType
|
|
826
|
+
in: query
|
|
827
|
+
description: Rank teams (Aggregated Teams tab) or contributors (Individual Contributors tab).
|
|
828
|
+
schema:
|
|
829
|
+
type: string
|
|
830
|
+
enum: [teams, contributors]
|
|
831
|
+
default: contributors
|
|
832
|
+
- name: limit
|
|
833
|
+
in: query
|
|
834
|
+
description: Maximum number of laggard rows to return (UI default 3).
|
|
835
|
+
schema:
|
|
836
|
+
type: integer
|
|
837
|
+
minimum: 1
|
|
838
|
+
maximum: 10
|
|
839
|
+
default: 3
|
|
840
|
+
- name: rangeId
|
|
841
|
+
in: query
|
|
842
|
+
description: Measure time range (maps to weekly bucket count).
|
|
843
|
+
schema:
|
|
844
|
+
type: string
|
|
845
|
+
enum: [4w, 8w, q]
|
|
846
|
+
default: 4w
|
|
847
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
848
|
+
- name: team
|
|
849
|
+
in: query
|
|
850
|
+
description: Team name filter; send `All teams` to include every team.
|
|
851
|
+
schema:
|
|
852
|
+
type: string
|
|
853
|
+
default: All teams
|
|
854
|
+
- name: windowEnd
|
|
855
|
+
in: query
|
|
856
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
857
|
+
schema:
|
|
858
|
+
type: string
|
|
859
|
+
format: date-time
|
|
749
860
|
responses:
|
|
750
861
|
"200":
|
|
751
|
-
description:
|
|
862
|
+
description: Bottom performers for the needs-attention widget
|
|
752
863
|
content:
|
|
753
864
|
application/json:
|
|
754
865
|
schema:
|
|
755
|
-
$ref: "#/components/schemas/
|
|
866
|
+
$ref: "#/components/schemas/ProductivityInsightsNeedsAttentionDto"
|
|
756
867
|
"400":
|
|
757
|
-
description:
|
|
868
|
+
description: Invalid query parameters
|
|
758
869
|
content:
|
|
759
870
|
application/json:
|
|
760
871
|
schema:
|
|
761
|
-
|
|
872
|
+
type: object
|
|
873
|
+
required: [error]
|
|
874
|
+
properties:
|
|
875
|
+
error: { type: string, example: invalid_query }
|
|
762
876
|
"401":
|
|
763
877
|
$ref: "#/components/responses/Unauthorized"
|
|
764
878
|
"403":
|
|
765
879
|
$ref: "#/components/responses/Forbidden"
|
|
766
880
|
"404":
|
|
767
881
|
description: Workspace does not exist or malformed workspaceId
|
|
768
|
-
content:
|
|
769
|
-
application/json:
|
|
770
|
-
schema:
|
|
771
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
772
882
|
|
|
773
|
-
/workspaces/{workspaceId}/
|
|
774
|
-
|
|
775
|
-
tags: [
|
|
776
|
-
summary:
|
|
777
|
-
operationId: refreshWorkspaceAiTool
|
|
883
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/aggregated-teams:
|
|
884
|
+
get:
|
|
885
|
+
tags: [Workspace]
|
|
886
|
+
summary: AI usage & spend insights — aggregated team weekly rollups
|
|
778
887
|
description: >
|
|
779
|
-
|
|
780
|
-
|
|
888
|
+
Team-level AI adoption, token volume, and spend for the Measure **Aggregated Teams**
|
|
889
|
+
view on `/phase-c/c7` and the dashboard AI Usage & Spend card. Aggregates stored
|
|
890
|
+
AI-tool integration snapshots (daily usage + billing spend) by org-chart team using
|
|
891
|
+
member email. Same filter params as other Measure insights routes.
|
|
892
|
+
operationId: getAiUsageSpendAggregatedTeams
|
|
781
893
|
parameters:
|
|
782
894
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
783
|
-
- name:
|
|
784
|
-
in:
|
|
785
|
-
|
|
895
|
+
- name: rangeId
|
|
896
|
+
in: query
|
|
897
|
+
description: Measure time range (maps to weekly bucket count).
|
|
786
898
|
schema:
|
|
787
899
|
type: string
|
|
788
|
-
enum: [
|
|
900
|
+
enum: [4w, 8w, q]
|
|
901
|
+
default: 4w
|
|
902
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
903
|
+
- name: team
|
|
904
|
+
in: query
|
|
905
|
+
description: Team name filter; send `All teams` to include every team.
|
|
906
|
+
schema:
|
|
907
|
+
type: string
|
|
908
|
+
default: All teams
|
|
909
|
+
- name: windowEnd
|
|
910
|
+
in: query
|
|
911
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
912
|
+
schema:
|
|
913
|
+
type: string
|
|
914
|
+
format: date-time
|
|
789
915
|
responses:
|
|
790
916
|
"200":
|
|
791
|
-
description:
|
|
917
|
+
description: Aggregated team AI usage and spend series
|
|
792
918
|
content:
|
|
793
919
|
application/json:
|
|
794
920
|
schema:
|
|
795
|
-
$ref: "#/components/schemas/
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
921
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamsDto"
|
|
922
|
+
"400":
|
|
923
|
+
description: Invalid query parameters
|
|
924
|
+
content:
|
|
925
|
+
application/json:
|
|
926
|
+
schema:
|
|
927
|
+
type: object
|
|
928
|
+
required: [error]
|
|
929
|
+
properties:
|
|
930
|
+
error: { type: string, example: invalid_query }
|
|
801
931
|
"401":
|
|
802
932
|
$ref: "#/components/responses/Unauthorized"
|
|
803
933
|
"403":
|
|
804
934
|
$ref: "#/components/responses/Forbidden"
|
|
805
935
|
"404":
|
|
806
|
-
description:
|
|
807
|
-
content:
|
|
808
|
-
application/json:
|
|
809
|
-
schema:
|
|
810
|
-
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
811
|
-
example:
|
|
812
|
-
ok: false
|
|
813
|
-
error: no_source
|
|
814
|
-
"409":
|
|
815
|
-
description: Refresh already in progress
|
|
816
|
-
content:
|
|
817
|
-
application/json:
|
|
818
|
-
schema:
|
|
819
|
-
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
820
|
-
example:
|
|
821
|
-
ok: false
|
|
822
|
-
error: already_in_progress
|
|
936
|
+
description: Workspace does not exist or malformed workspaceId
|
|
823
937
|
|
|
824
|
-
/workspaces/{workspaceId}/
|
|
938
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/aggregated-contributors:
|
|
825
939
|
get:
|
|
826
|
-
tags: [
|
|
827
|
-
summary:
|
|
828
|
-
|
|
940
|
+
tags: [Workspace]
|
|
941
|
+
summary: AI usage & spend insights — aggregated contributor weekly rollups
|
|
942
|
+
description: >
|
|
943
|
+
Per-contributor AI adoption, token volume, and spend for the Measure **Individual
|
|
944
|
+
Contributors** view on `/phase-c/c7`. Aggregates stored AI-tool integration snapshots
|
|
945
|
+
(daily usage + billing spend) by org-chart person id (typically email). Same filter
|
|
946
|
+
params as other Measure insights routes.
|
|
947
|
+
operationId: getAiUsageSpendAggregatedContributors
|
|
829
948
|
parameters:
|
|
830
949
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
831
|
-
- name:
|
|
832
|
-
in:
|
|
833
|
-
|
|
950
|
+
- name: rangeId
|
|
951
|
+
in: query
|
|
952
|
+
description: Measure time range (maps to weekly bucket count).
|
|
834
953
|
schema:
|
|
835
954
|
type: string
|
|
836
|
-
enum: [
|
|
955
|
+
enum: [4w, 8w, q]
|
|
956
|
+
default: 4w
|
|
957
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
958
|
+
- name: team
|
|
959
|
+
in: query
|
|
960
|
+
description: Team name filter; send `All teams` to include every team.
|
|
961
|
+
schema:
|
|
962
|
+
type: string
|
|
963
|
+
default: All teams
|
|
964
|
+
- name: windowEnd
|
|
965
|
+
in: query
|
|
966
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
967
|
+
schema:
|
|
968
|
+
type: string
|
|
969
|
+
format: date-time
|
|
837
970
|
responses:
|
|
838
971
|
"200":
|
|
839
|
-
description:
|
|
972
|
+
description: Aggregated contributor AI usage and spend series
|
|
973
|
+
content:
|
|
974
|
+
application/json:
|
|
975
|
+
schema:
|
|
976
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedContributorsDto"
|
|
977
|
+
"400":
|
|
978
|
+
description: Invalid query parameters
|
|
840
979
|
content:
|
|
841
980
|
application/json:
|
|
842
981
|
schema:
|
|
843
982
|
type: object
|
|
844
|
-
required: [
|
|
983
|
+
required: [error]
|
|
845
984
|
properties:
|
|
846
|
-
|
|
847
|
-
type: array
|
|
848
|
-
items:
|
|
849
|
-
$ref: "#/components/schemas/AiToolSeatDto"
|
|
985
|
+
error: { type: string, example: invalid_query }
|
|
850
986
|
"401":
|
|
851
987
|
$ref: "#/components/responses/Unauthorized"
|
|
852
988
|
"403":
|
|
853
989
|
$ref: "#/components/responses/Forbidden"
|
|
990
|
+
"404":
|
|
991
|
+
description: Workspace does not exist or malformed workspaceId
|
|
854
992
|
|
|
855
|
-
/workspaces/{workspaceId}/
|
|
993
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/contributor-tool-heatmap:
|
|
856
994
|
get:
|
|
857
|
-
tags: [
|
|
858
|
-
summary:
|
|
859
|
-
|
|
995
|
+
tags: [Workspace]
|
|
996
|
+
summary: AI usage & spend insights — contributor × week heatmap rows
|
|
997
|
+
description: >
|
|
998
|
+
Contributor × week heatmap rows for the Measure **Individual Contributors** tool
|
|
999
|
+
heatmap on `/phase-c/c7`. Same aggregation as aggregated-contributors; returns
|
|
1000
|
+
weekly token, spend, and active-user counts per org-chart person.
|
|
1001
|
+
operationId: getAiUsageSpendContributorToolHeatmap
|
|
860
1002
|
parameters:
|
|
861
1003
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
862
|
-
- name:
|
|
863
|
-
in: path
|
|
864
|
-
required: true
|
|
865
|
-
schema:
|
|
866
|
-
type: string
|
|
867
|
-
enum: [cursor]
|
|
868
|
-
- name: from
|
|
1004
|
+
- name: rangeId
|
|
869
1005
|
in: query
|
|
870
|
-
|
|
1006
|
+
description: Measure time range (maps to weekly bucket count).
|
|
871
1007
|
schema:
|
|
872
1008
|
type: string
|
|
873
|
-
|
|
874
|
-
|
|
1009
|
+
enum: [4w, 8w, q]
|
|
1010
|
+
default: 4w
|
|
1011
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1012
|
+
- name: team
|
|
875
1013
|
in: query
|
|
876
|
-
|
|
1014
|
+
description: Team name filter; send `All teams` to include every team.
|
|
877
1015
|
schema:
|
|
878
1016
|
type: string
|
|
879
|
-
|
|
880
|
-
- name:
|
|
1017
|
+
default: All teams
|
|
1018
|
+
- name: windowEnd
|
|
881
1019
|
in: query
|
|
882
|
-
|
|
1020
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
883
1021
|
schema:
|
|
884
1022
|
type: string
|
|
1023
|
+
format: date-time
|
|
885
1024
|
responses:
|
|
886
1025
|
"200":
|
|
887
|
-
description:
|
|
1026
|
+
description: Contributor heatmap rows for AI usage and spend
|
|
1027
|
+
content:
|
|
1028
|
+
application/json:
|
|
1029
|
+
schema:
|
|
1030
|
+
$ref: "#/components/schemas/AiUsageSpendContributorToolHeatmapDto"
|
|
1031
|
+
"400":
|
|
1032
|
+
description: Invalid query parameters
|
|
888
1033
|
content:
|
|
889
1034
|
application/json:
|
|
890
1035
|
schema:
|
|
891
1036
|
type: object
|
|
892
|
-
required: [
|
|
1037
|
+
required: [error]
|
|
893
1038
|
properties:
|
|
894
|
-
|
|
895
|
-
type: array
|
|
896
|
-
items:
|
|
897
|
-
$ref: "#/components/schemas/AiToolDailyUsageRowDto"
|
|
1039
|
+
error: { type: string, example: invalid_query }
|
|
898
1040
|
"401":
|
|
899
1041
|
$ref: "#/components/responses/Unauthorized"
|
|
900
1042
|
"403":
|
|
901
1043
|
$ref: "#/components/responses/Forbidden"
|
|
1044
|
+
"404":
|
|
1045
|
+
description: Workspace does not exist or malformed workspaceId
|
|
902
1046
|
|
|
903
|
-
/workspaces/{workspaceId}/
|
|
1047
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/key-insights:
|
|
904
1048
|
get:
|
|
905
|
-
tags: [
|
|
906
|
-
summary:
|
|
907
|
-
|
|
1049
|
+
tags: [Workspace]
|
|
1050
|
+
summary: AI usage & spend insights — key insights panel
|
|
1051
|
+
description: >
|
|
1052
|
+
Narrative insight cards for the Measure **Key insights** panel on `/phase-c/c7`
|
|
1053
|
+
(AI Usage & Spend). Derived from scoped AI-tool usage/spend snapshots and
|
|
1054
|
+
productivity metrics for the selected filters and range.
|
|
1055
|
+
operationId: getAiUsageSpendKeyInsights
|
|
908
1056
|
parameters:
|
|
909
1057
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
910
|
-
- name:
|
|
911
|
-
in:
|
|
912
|
-
|
|
1058
|
+
- name: rangeId
|
|
1059
|
+
in: query
|
|
1060
|
+
description: Measure time range (maps to weekly bucket count).
|
|
913
1061
|
schema:
|
|
914
1062
|
type: string
|
|
915
|
-
enum: [
|
|
916
|
-
|
|
1063
|
+
enum: [4w, 8w, q]
|
|
1064
|
+
default: 4w
|
|
1065
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1066
|
+
- name: team
|
|
917
1067
|
in: query
|
|
918
|
-
|
|
1068
|
+
description: Team name filter; send `All teams` to include every team.
|
|
919
1069
|
schema:
|
|
920
|
-
type:
|
|
921
|
-
|
|
1070
|
+
type: string
|
|
1071
|
+
default: All teams
|
|
1072
|
+
- name: windowEnd
|
|
1073
|
+
in: query
|
|
1074
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
1075
|
+
schema:
|
|
1076
|
+
type: string
|
|
1077
|
+
format: date-time
|
|
922
1078
|
responses:
|
|
923
1079
|
"200":
|
|
924
|
-
description:
|
|
1080
|
+
description: Key insight cards for the AI usage & spend panel
|
|
1081
|
+
content:
|
|
1082
|
+
application/json:
|
|
1083
|
+
schema:
|
|
1084
|
+
$ref: "#/components/schemas/AiUsageSpendKeyInsightsDto"
|
|
1085
|
+
"400":
|
|
1086
|
+
description: Invalid query parameters
|
|
925
1087
|
content:
|
|
926
1088
|
application/json:
|
|
927
1089
|
schema:
|
|
928
1090
|
type: object
|
|
929
|
-
required: [
|
|
1091
|
+
required: [error]
|
|
930
1092
|
properties:
|
|
931
|
-
|
|
932
|
-
type: array
|
|
933
|
-
items:
|
|
934
|
-
$ref: "#/components/schemas/AiToolSpendRowDto"
|
|
1093
|
+
error: { type: string, example: invalid_query }
|
|
935
1094
|
"401":
|
|
936
1095
|
$ref: "#/components/responses/Unauthorized"
|
|
937
1096
|
"403":
|
|
938
1097
|
$ref: "#/components/responses/Forbidden"
|
|
1098
|
+
"404":
|
|
1099
|
+
description: Workspace does not exist or malformed workspaceId
|
|
939
1100
|
|
|
940
|
-
/workspaces/{workspaceId}/
|
|
1101
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/ai-assisted-code-percentage:
|
|
941
1102
|
get:
|
|
942
|
-
tags: [
|
|
943
|
-
summary:
|
|
944
|
-
|
|
1103
|
+
tags: [Workspace]
|
|
1104
|
+
summary: AI usage & spend insights — AI-assisted code percentage
|
|
1105
|
+
description: >
|
|
1106
|
+
Period and weekly AI-assisted code percentage for the Measure **AI-assisted code**
|
|
1107
|
+
card on `/phase-c/c7` and the **AI impact** curve on `/phase-c/c4`. When scoped
|
|
1108
|
+
productivity metrics include `aiAssistedContributionRatioPercent`, values are
|
|
1109
|
+
**measured** from ingest; otherwise the API falls back to token→LOC heuristics and
|
|
1110
|
+
sets `dataQuality` to **estimated**. Clients should not present estimated series as
|
|
1111
|
+
Cursor-measured signal.
|
|
1112
|
+
operationId: getAiUsageSpendAiAssistedCodePercentage
|
|
945
1113
|
parameters:
|
|
946
1114
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
947
|
-
- name:
|
|
948
|
-
in:
|
|
949
|
-
|
|
1115
|
+
- name: rangeId
|
|
1116
|
+
in: query
|
|
1117
|
+
description: Measure time range (maps to weekly bucket count).
|
|
950
1118
|
schema:
|
|
951
1119
|
type: string
|
|
952
|
-
enum: [
|
|
1120
|
+
enum: [4w, 8w, q]
|
|
1121
|
+
default: 4w
|
|
1122
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1123
|
+
- name: team
|
|
1124
|
+
in: query
|
|
1125
|
+
description: Team name filter; send `All teams` to include every team.
|
|
1126
|
+
schema:
|
|
1127
|
+
type: string
|
|
1128
|
+
default: All teams
|
|
1129
|
+
- name: windowEnd
|
|
1130
|
+
in: query
|
|
1131
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
1132
|
+
schema:
|
|
1133
|
+
type: string
|
|
1134
|
+
format: date-time
|
|
953
1135
|
responses:
|
|
954
1136
|
"200":
|
|
955
|
-
description:
|
|
1137
|
+
description: AI-assisted code percentage series
|
|
1138
|
+
content:
|
|
1139
|
+
application/json:
|
|
1140
|
+
schema:
|
|
1141
|
+
$ref: "#/components/schemas/AiUsageSpendAiAssistedCodePercentageDto"
|
|
1142
|
+
"400":
|
|
1143
|
+
description: Invalid query parameters
|
|
956
1144
|
content:
|
|
957
1145
|
application/json:
|
|
958
1146
|
schema:
|
|
959
1147
|
type: object
|
|
960
|
-
required: [
|
|
1148
|
+
required: [error]
|
|
961
1149
|
properties:
|
|
962
|
-
|
|
963
|
-
$ref: "#/components/schemas/AiToolRefreshStatusDto"
|
|
1150
|
+
error: { type: string, example: invalid_query }
|
|
964
1151
|
"401":
|
|
965
1152
|
$ref: "#/components/responses/Unauthorized"
|
|
966
1153
|
"403":
|
|
967
1154
|
$ref: "#/components/responses/Forbidden"
|
|
968
1155
|
"404":
|
|
969
|
-
description:
|
|
970
|
-
content:
|
|
971
|
-
application/json:
|
|
972
|
-
schema:
|
|
973
|
-
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
974
|
-
example:
|
|
975
|
-
ok: false
|
|
976
|
-
error: no_source
|
|
1156
|
+
description: Workspace does not exist or malformed workspaceId
|
|
977
1157
|
|
|
978
|
-
/
|
|
1158
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/ai-tool-usage-spend:
|
|
979
1159
|
get:
|
|
980
|
-
tags: [
|
|
981
|
-
summary:
|
|
982
|
-
operationId: getGithubInstallCallback
|
|
1160
|
+
tags: [Workspace]
|
|
1161
|
+
summary: AI usage & spend insights — AI tool usage and spend by provider/model
|
|
983
1162
|
description: >
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1163
|
+
Scoped portfolio rollups of AI-tool token usage and spend by registered provider
|
|
1164
|
+
and by model (from daily usage `mostUsedModel`) for the **Provider / Model usage + spend**
|
|
1165
|
+
chart on `/phase-c/c4` and `/phase-c/c7`. Reads stored AI-tool integration snapshots
|
|
1166
|
+
(`tai_workspace_ai_tool_daily_usage`, `tai_workspace_ai_tool_spend`).
|
|
1167
|
+
operationId: getAiUsageSpendAiToolUsageSpend
|
|
987
1168
|
parameters:
|
|
988
|
-
-
|
|
989
|
-
|
|
990
|
-
required: true
|
|
991
|
-
schema:
|
|
992
|
-
type: string
|
|
993
|
-
- name: installation_id
|
|
994
|
-
in: query
|
|
995
|
-
required: false
|
|
996
|
-
schema:
|
|
997
|
-
type: string
|
|
998
|
-
- name: setup_action
|
|
1169
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
1170
|
+
- name: rangeId
|
|
999
1171
|
in: query
|
|
1000
|
-
|
|
1172
|
+
description: Measure time range (maps to weekly bucket count).
|
|
1001
1173
|
schema:
|
|
1002
1174
|
type: string
|
|
1003
|
-
|
|
1175
|
+
enum: [4w, 8w, q]
|
|
1176
|
+
default: 4w
|
|
1177
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1178
|
+
- name: team
|
|
1004
1179
|
in: query
|
|
1005
|
-
|
|
1180
|
+
description: Team name filter; send `All teams` to include every team.
|
|
1006
1181
|
schema:
|
|
1007
1182
|
type: string
|
|
1008
|
-
|
|
1183
|
+
default: All teams
|
|
1184
|
+
- name: windowEnd
|
|
1009
1185
|
in: query
|
|
1010
|
-
|
|
1186
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
1011
1187
|
schema:
|
|
1012
1188
|
type: string
|
|
1189
|
+
format: date-time
|
|
1013
1190
|
responses:
|
|
1014
|
-
"
|
|
1015
|
-
description:
|
|
1016
|
-
"501":
|
|
1017
|
-
description: Workspace store not configured
|
|
1191
|
+
"200":
|
|
1192
|
+
description: Provider and model AI tool usage/spend rollups
|
|
1018
1193
|
content:
|
|
1019
1194
|
application/json:
|
|
1020
1195
|
schema:
|
|
1021
|
-
$ref: "#/components/schemas/
|
|
1022
|
-
"
|
|
1023
|
-
description:
|
|
1196
|
+
$ref: "#/components/schemas/AiUsageSpendAiToolUsageSpendDto"
|
|
1197
|
+
"400":
|
|
1198
|
+
description: Invalid query parameters
|
|
1024
1199
|
content:
|
|
1025
1200
|
application/json:
|
|
1026
1201
|
schema:
|
|
1027
|
-
|
|
1202
|
+
type: object
|
|
1203
|
+
required: [error]
|
|
1204
|
+
properties:
|
|
1205
|
+
error: { type: string, example: invalid_query }
|
|
1206
|
+
"401":
|
|
1207
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1208
|
+
"403":
|
|
1209
|
+
$ref: "#/components/responses/Forbidden"
|
|
1210
|
+
"404":
|
|
1211
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1028
1212
|
|
|
1029
|
-
/
|
|
1030
|
-
|
|
1031
|
-
tags: [
|
|
1032
|
-
summary:
|
|
1033
|
-
operationId: postGithubWebhook
|
|
1213
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/team-tool-heatmap:
|
|
1214
|
+
get:
|
|
1215
|
+
tags: [Workspace]
|
|
1216
|
+
summary: AI usage & spend insights — team weekly heatmap
|
|
1034
1217
|
description: >
|
|
1035
|
-
|
|
1036
|
-
|
|
1218
|
+
Team × week rollups of AI-tool token volume, spend, and active users for the
|
|
1219
|
+
**Team tool heatmap** on `/phase-c/c4` and `/phase-c/c7`. Aggregates stored
|
|
1220
|
+
AI-tool integration snapshots by org-chart team. Same filter params as other
|
|
1221
|
+
Measure insights routes.
|
|
1222
|
+
operationId: getAiUsageSpendTeamToolHeatmap
|
|
1037
1223
|
parameters:
|
|
1038
|
-
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1224
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
1225
|
+
- name: rangeId
|
|
1226
|
+
in: query
|
|
1227
|
+
description: Measure time range (maps to weekly bucket count).
|
|
1041
1228
|
schema:
|
|
1042
1229
|
type: string
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1230
|
+
enum: [4w, 8w, q]
|
|
1231
|
+
default: 4w
|
|
1232
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1233
|
+
- name: team
|
|
1234
|
+
in: query
|
|
1235
|
+
description: Team name filter; send `All teams` to include every team.
|
|
1046
1236
|
schema:
|
|
1047
1237
|
type: string
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1238
|
+
default: All teams
|
|
1239
|
+
- name: windowEnd
|
|
1240
|
+
in: query
|
|
1241
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
1242
|
+
schema:
|
|
1243
|
+
type: string
|
|
1244
|
+
format: date-time
|
|
1055
1245
|
responses:
|
|
1056
1246
|
"200":
|
|
1057
|
-
description:
|
|
1058
|
-
"400":
|
|
1059
|
-
description: Invalid payload
|
|
1247
|
+
description: Team weekly AI usage heatmap rows
|
|
1060
1248
|
content:
|
|
1061
1249
|
application/json:
|
|
1062
1250
|
schema:
|
|
1063
|
-
$ref: "#/components/schemas/
|
|
1064
|
-
"
|
|
1065
|
-
description: Invalid
|
|
1251
|
+
$ref: "#/components/schemas/AiUsageSpendTeamToolHeatmapDto"
|
|
1252
|
+
"400":
|
|
1253
|
+
description: Invalid query parameters
|
|
1066
1254
|
content:
|
|
1067
1255
|
application/json:
|
|
1068
1256
|
schema:
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
application/json:
|
|
1080
|
-
schema:
|
|
1081
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1257
|
+
type: object
|
|
1258
|
+
required: [error]
|
|
1259
|
+
properties:
|
|
1260
|
+
error: { type: string, example: invalid_query }
|
|
1261
|
+
"401":
|
|
1262
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1263
|
+
"403":
|
|
1264
|
+
$ref: "#/components/responses/Forbidden"
|
|
1265
|
+
"404":
|
|
1266
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1082
1267
|
|
|
1083
|
-
/workspaces/{workspaceId}/ai-
|
|
1268
|
+
/workspaces/{workspaceId}/insights/ai-usage-spend/roi-productivity-signal:
|
|
1084
1269
|
get:
|
|
1085
|
-
tags: [
|
|
1086
|
-
summary:
|
|
1087
|
-
|
|
1270
|
+
tags: [Workspace]
|
|
1271
|
+
summary: AI usage & spend insights — ROI and productivity signal
|
|
1272
|
+
description: >
|
|
1273
|
+
Connects scoped AI-tool usage and spend to engineering throughput (merged PRs)
|
|
1274
|
+
for the **ROI & Productivity Signal** panel on `/phase-c/c4` and `/phase-c/c7`.
|
|
1275
|
+
Returns spend efficiency metrics, adoption counts, and weekly usage vs PR series.
|
|
1276
|
+
Same filter params as other Measure insights routes.
|
|
1277
|
+
operationId: getAiUsageSpendRoiProductivitySignal
|
|
1088
1278
|
parameters:
|
|
1089
1279
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1280
|
+
- name: rangeId
|
|
1281
|
+
in: query
|
|
1282
|
+
description: Measure time range (maps to weekly bucket count).
|
|
1283
|
+
schema:
|
|
1284
|
+
type: string
|
|
1285
|
+
enum: [4w, 8w, q]
|
|
1286
|
+
default: 4w
|
|
1287
|
+
- $ref: "#/components/parameters/InsightsDepartmentFilter"
|
|
1288
|
+
- name: team
|
|
1289
|
+
in: query
|
|
1290
|
+
description: Team name filter; send `All teams` to include every team.
|
|
1291
|
+
schema:
|
|
1292
|
+
type: string
|
|
1293
|
+
default: All teams
|
|
1294
|
+
- name: windowEnd
|
|
1295
|
+
in: query
|
|
1296
|
+
description: ISO timestamp for the end of the last weekly bucket; omit for current week.
|
|
1297
|
+
schema:
|
|
1298
|
+
type: string
|
|
1299
|
+
format: date-time
|
|
1090
1300
|
responses:
|
|
1091
1301
|
"200":
|
|
1092
|
-
description:
|
|
1302
|
+
description: ROI and productivity signal rollups
|
|
1093
1303
|
content:
|
|
1094
1304
|
application/json:
|
|
1095
1305
|
schema:
|
|
1096
|
-
$ref: "#/components/schemas/
|
|
1097
|
-
"
|
|
1098
|
-
|
|
1099
|
-
put:
|
|
1100
|
-
tags: [AIReadiness]
|
|
1101
|
-
summary: Upsert AI readiness
|
|
1102
|
-
operationId: putAiReadiness
|
|
1103
|
-
parameters:
|
|
1104
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
1105
|
-
requestBody:
|
|
1106
|
-
required: true
|
|
1107
|
-
content:
|
|
1108
|
-
application/json:
|
|
1109
|
-
schema:
|
|
1110
|
-
$ref: "#/components/schemas/AIReadinessDto"
|
|
1111
|
-
responses:
|
|
1112
|
-
"204":
|
|
1113
|
-
description: Saved
|
|
1114
|
-
"401":
|
|
1115
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1116
|
-
|
|
1117
|
-
/workspaces/{workspaceId}/ai-readiness/maturity:
|
|
1118
|
-
post:
|
|
1119
|
-
tags: [AIReadiness]
|
|
1120
|
-
summary: Compute maturity level
|
|
1121
|
-
operationId: postAiReadinessMaturity
|
|
1122
|
-
parameters:
|
|
1123
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
1124
|
-
requestBody:
|
|
1125
|
-
required: true
|
|
1126
|
-
content:
|
|
1127
|
-
application/json:
|
|
1128
|
-
schema:
|
|
1129
|
-
$ref: "#/components/schemas/AIReadinessDto"
|
|
1130
|
-
responses:
|
|
1131
|
-
"200":
|
|
1132
|
-
description: Derived level
|
|
1306
|
+
$ref: "#/components/schemas/AiUsageSpendRoiProductivitySignalDto"
|
|
1307
|
+
"400":
|
|
1308
|
+
description: Invalid query parameters
|
|
1133
1309
|
content:
|
|
1134
1310
|
application/json:
|
|
1135
1311
|
schema:
|
|
1136
|
-
|
|
1312
|
+
type: object
|
|
1313
|
+
required: [error]
|
|
1314
|
+
properties:
|
|
1315
|
+
error: { type: string, example: invalid_query }
|
|
1137
1316
|
"401":
|
|
1138
1317
|
$ref: "#/components/responses/Unauthorized"
|
|
1318
|
+
"403":
|
|
1319
|
+
$ref: "#/components/responses/Forbidden"
|
|
1320
|
+
"404":
|
|
1321
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1139
1322
|
|
|
1140
|
-
/workspaces/{workspaceId}/
|
|
1323
|
+
/workspaces/{workspaceId}/company-profile:
|
|
1141
1324
|
get:
|
|
1142
|
-
tags: [
|
|
1143
|
-
summary: Get
|
|
1144
|
-
operationId:
|
|
1325
|
+
tags: [CompanyProfile]
|
|
1326
|
+
summary: Get company profile
|
|
1327
|
+
operationId: getCompanyProfile
|
|
1145
1328
|
parameters:
|
|
1146
1329
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1147
1330
|
responses:
|
|
1148
1331
|
"200":
|
|
1149
1332
|
description: >
|
|
1150
|
-
|
|
1151
|
-
has been saved yet. Clients should
|
|
1333
|
+
Company profile DTO, or JSON `null` when the workspace exists but no profile
|
|
1334
|
+
has been saved yet. Clients should treat `null` as the empty initial state
|
|
1335
|
+
(the wizard renders blank inputs); they MUST NOT treat the absence of a
|
|
1336
|
+
saved profile as a 404.
|
|
1152
1337
|
content:
|
|
1153
1338
|
application/json:
|
|
1154
1339
|
schema:
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1340
|
+
$ref: "#/components/schemas/CompanyProfileDto"
|
|
1341
|
+
examples:
|
|
1342
|
+
sample:
|
|
1343
|
+
summary: Saved profile
|
|
1344
|
+
value:
|
|
1345
|
+
companyName: Acme
|
|
1346
|
+
industry: software
|
|
1347
|
+
companySize: "51-200"
|
|
1348
|
+
engineeringHC: "42"
|
|
1349
|
+
headquarters: "Austin, TX"
|
|
1158
1350
|
"400":
|
|
1159
1351
|
description: Malformed workspaceId
|
|
1160
1352
|
content:
|
|
@@ -1172,9 +1364,14 @@ paths:
|
|
|
1172
1364
|
schema:
|
|
1173
1365
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1174
1366
|
put:
|
|
1175
|
-
tags: [
|
|
1176
|
-
summary: Upsert
|
|
1177
|
-
operationId:
|
|
1367
|
+
tags: [CompanyProfile]
|
|
1368
|
+
summary: Upsert company profile
|
|
1369
|
+
operationId: putCompanyProfile
|
|
1370
|
+
description: >
|
|
1371
|
+
Idempotent upsert of the workspace's company profile. On success, also
|
|
1372
|
+
synchronizes `tai_workspaces.name` to the new `companyName` so subsequent
|
|
1373
|
+
calls to `GET /me/workspaces` reflect the updated display name. Repeated
|
|
1374
|
+
PUTs replace the stored payload entirely.
|
|
1178
1375
|
parameters:
|
|
1179
1376
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1180
1377
|
requestBody:
|
|
@@ -1182,12 +1379,12 @@ paths:
|
|
|
1182
1379
|
content:
|
|
1183
1380
|
application/json:
|
|
1184
1381
|
schema:
|
|
1185
|
-
$ref: "#/components/schemas/
|
|
1382
|
+
$ref: "#/components/schemas/CompanyProfileDto"
|
|
1186
1383
|
responses:
|
|
1187
1384
|
"204":
|
|
1188
1385
|
description: Saved
|
|
1189
1386
|
"400":
|
|
1190
|
-
description: Body fails validation (
|
|
1387
|
+
description: Body fails validation (missing/invalid required field, bad enum, conditional rule)
|
|
1191
1388
|
content:
|
|
1192
1389
|
application/json:
|
|
1193
1390
|
schema:
|
|
@@ -1203,406 +1400,522 @@ paths:
|
|
|
1203
1400
|
schema:
|
|
1204
1401
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1205
1402
|
|
|
1206
|
-
/workspaces/{workspaceId}/
|
|
1403
|
+
/workspaces/{workspaceId}/integrations/github:
|
|
1207
1404
|
get:
|
|
1208
|
-
tags: [
|
|
1209
|
-
summary:
|
|
1210
|
-
operationId:
|
|
1405
|
+
tags: [Integrations]
|
|
1406
|
+
summary: GitHub App installation status for workspace
|
|
1407
|
+
operationId: getWorkspaceGithubInstallationStatus
|
|
1408
|
+
description: >
|
|
1409
|
+
Returns whether a GitHub App installation is linked and cached repo metadata.
|
|
1410
|
+
When no installation exists, returns 200 with `installed: false` (never 404 for missing install).
|
|
1411
|
+
Use `refresh=true` to bypass cache and re-list repositories from GitHub.
|
|
1211
1412
|
parameters:
|
|
1212
1413
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1414
|
+
- name: refresh
|
|
1415
|
+
in: query
|
|
1416
|
+
required: false
|
|
1417
|
+
description: When true, bypass `tai_workspace_vcs_repos_cache` and re-fetch from GitHub.
|
|
1418
|
+
schema:
|
|
1419
|
+
type: boolean
|
|
1420
|
+
default: false
|
|
1421
|
+
- name: permissionsRefresh
|
|
1422
|
+
in: query
|
|
1423
|
+
required: false
|
|
1424
|
+
description: >
|
|
1425
|
+
When true, re-fetch GitHub App and installation permission metadata (used by the
|
|
1426
|
+
login permission gate after the user approves on GitHub).
|
|
1427
|
+
schema:
|
|
1428
|
+
type: boolean
|
|
1429
|
+
default: false
|
|
1213
1430
|
responses:
|
|
1214
1431
|
"200":
|
|
1215
|
-
description:
|
|
1432
|
+
description: Installation status
|
|
1216
1433
|
content:
|
|
1217
1434
|
application/json:
|
|
1218
1435
|
schema:
|
|
1219
|
-
$ref: "#/components/schemas/
|
|
1436
|
+
$ref: "#/components/schemas/GithubInstallationStatusDto"
|
|
1220
1437
|
"401":
|
|
1221
1438
|
$ref: "#/components/responses/Unauthorized"
|
|
1439
|
+
"403":
|
|
1440
|
+
$ref: "#/components/responses/Forbidden"
|
|
1441
|
+
"404":
|
|
1442
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1443
|
+
content:
|
|
1444
|
+
application/json:
|
|
1445
|
+
schema:
|
|
1446
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1222
1447
|
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1448
|
+
delete:
|
|
1449
|
+
tags: [Integrations]
|
|
1450
|
+
summary: Disconnect GitHub App installation for workspace
|
|
1451
|
+
operationId: deleteWorkspaceGithubInstallation
|
|
1452
|
+
description: >
|
|
1453
|
+
Removes the workspace GitHub App integration row (and cascaded VCS connection + repos cache).
|
|
1454
|
+
Idempotent: returns 204 when no installation exists. Does not uninstall the app on GitHub;
|
|
1455
|
+
use the manage URL or GitHub settings to revoke the app there if required.
|
|
1456
|
+
security:
|
|
1457
|
+
- bearerAuth: []
|
|
1228
1458
|
parameters:
|
|
1229
1459
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1460
|
+
- name: installationId
|
|
1461
|
+
in: query
|
|
1462
|
+
required: false
|
|
1463
|
+
description: Optional installation id to disconnect a single linked installation.
|
|
1464
|
+
schema:
|
|
1465
|
+
type: string
|
|
1466
|
+
- name: all
|
|
1467
|
+
in: query
|
|
1468
|
+
required: false
|
|
1469
|
+
description: When true, disconnect all linked GitHub installations for this workspace.
|
|
1470
|
+
schema:
|
|
1471
|
+
type: boolean
|
|
1230
1472
|
responses:
|
|
1231
|
-
"
|
|
1232
|
-
description:
|
|
1473
|
+
"204":
|
|
1474
|
+
description: Installation removed or was already absent
|
|
1475
|
+
"401":
|
|
1476
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1477
|
+
"403":
|
|
1478
|
+
$ref: "#/components/responses/Forbidden"
|
|
1479
|
+
"404":
|
|
1480
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1233
1481
|
content:
|
|
1234
1482
|
application/json:
|
|
1235
1483
|
schema:
|
|
1236
|
-
$ref: "#/components/schemas/
|
|
1237
|
-
"401":
|
|
1238
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1484
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1239
1485
|
|
|
1240
|
-
/workspaces/{workspaceId}/
|
|
1486
|
+
/workspaces/{workspaceId}/integrations/github/install-url:
|
|
1241
1487
|
post:
|
|
1242
|
-
tags: [
|
|
1243
|
-
summary:
|
|
1244
|
-
operationId:
|
|
1488
|
+
tags: [Integrations]
|
|
1489
|
+
summary: Create GitHub App installation URL
|
|
1490
|
+
operationId: postGithubInstallUrl
|
|
1491
|
+
description: >
|
|
1492
|
+
Creates a GitHub App installation URL scoped to the workspace and caller.
|
|
1493
|
+
Body is optional; when omitted, defaults to `/phase-a/p3` return path.
|
|
1494
|
+
security:
|
|
1495
|
+
- bearerAuth: []
|
|
1245
1496
|
parameters:
|
|
1246
1497
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1247
1498
|
requestBody:
|
|
1248
|
-
required:
|
|
1499
|
+
required: false
|
|
1249
1500
|
content:
|
|
1250
1501
|
application/json:
|
|
1251
1502
|
schema:
|
|
1252
|
-
$ref: "#/components/schemas/
|
|
1503
|
+
$ref: "#/components/schemas/GithubInstallUrlRequestDto"
|
|
1253
1504
|
responses:
|
|
1254
1505
|
"200":
|
|
1255
|
-
description:
|
|
1506
|
+
description: Installation URL + signed state
|
|
1256
1507
|
content:
|
|
1257
1508
|
application/json:
|
|
1258
1509
|
schema:
|
|
1259
|
-
$ref: "#/components/schemas/
|
|
1510
|
+
$ref: "#/components/schemas/GithubInstallUrlResponseDto"
|
|
1511
|
+
"400":
|
|
1512
|
+
description: Request validation failed
|
|
1513
|
+
content:
|
|
1514
|
+
application/json:
|
|
1515
|
+
schema:
|
|
1516
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1260
1517
|
"401":
|
|
1261
1518
|
$ref: "#/components/responses/Unauthorized"
|
|
1519
|
+
"403":
|
|
1520
|
+
$ref: "#/components/responses/Forbidden"
|
|
1521
|
+
"404":
|
|
1522
|
+
description: Workspace does not exist or malformed workspaceId
|
|
1523
|
+
content:
|
|
1524
|
+
application/json:
|
|
1525
|
+
schema:
|
|
1526
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1262
1527
|
|
|
1263
|
-
/workspaces/{workspaceId}/
|
|
1528
|
+
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/refresh:
|
|
1264
1529
|
post:
|
|
1265
|
-
tags: [
|
|
1266
|
-
summary:
|
|
1530
|
+
tags: [Integrations]
|
|
1531
|
+
summary: Refresh AI tool integration snapshots
|
|
1532
|
+
operationId: refreshWorkspaceAiTool
|
|
1267
1533
|
description: >
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
operationId: postNdaExternal
|
|
1271
|
-
parameters:
|
|
1272
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
1273
|
-
requestBody:
|
|
1274
|
-
required: true
|
|
1275
|
-
content:
|
|
1276
|
-
application/json:
|
|
1277
|
-
schema:
|
|
1278
|
-
$ref: "#/components/schemas/NdaExternalBodyDto"
|
|
1279
|
-
responses:
|
|
1280
|
-
"200":
|
|
1281
|
-
description: Completion record
|
|
1282
|
-
content:
|
|
1283
|
-
application/json:
|
|
1284
|
-
schema:
|
|
1285
|
-
$ref: "#/components/schemas/NdaCompletionDto"
|
|
1286
|
-
"401":
|
|
1287
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1288
|
-
|
|
1289
|
-
/workspaces/{workspaceId}/readiness/repos:
|
|
1290
|
-
get:
|
|
1291
|
-
tags: [RepositoryReadiness]
|
|
1292
|
-
summary: List repo readiness scores
|
|
1293
|
-
operationId: listReadinessRepos
|
|
1534
|
+
Provider-agnostic refresh. Returns 409 when an advisory-lock refresh is already in progress.
|
|
1535
|
+
On upstream auth/rate/network failures, returns `200` with `{ ok:false, error }` so the SPA can render inline error.
|
|
1294
1536
|
parameters:
|
|
1295
1537
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1538
|
+
- name: provider
|
|
1539
|
+
in: path
|
|
1540
|
+
required: true
|
|
1541
|
+
schema:
|
|
1542
|
+
type: string
|
|
1543
|
+
enum: [cursor]
|
|
1296
1544
|
responses:
|
|
1297
1545
|
"200":
|
|
1298
|
-
description:
|
|
1546
|
+
description: Refresh result
|
|
1299
1547
|
content:
|
|
1300
1548
|
application/json:
|
|
1301
1549
|
schema:
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1550
|
+
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
1551
|
+
examples:
|
|
1552
|
+
ok:
|
|
1553
|
+
value: { ok: true }
|
|
1554
|
+
invalid_token:
|
|
1555
|
+
value: { ok: false, error: invalid_token }
|
|
1305
1556
|
"401":
|
|
1306
1557
|
$ref: "#/components/responses/Unauthorized"
|
|
1307
1558
|
"403":
|
|
1308
1559
|
$ref: "#/components/responses/Forbidden"
|
|
1309
1560
|
"404":
|
|
1310
|
-
description:
|
|
1561
|
+
description: Provider source missing for this workspace
|
|
1311
1562
|
content:
|
|
1312
1563
|
application/json:
|
|
1313
1564
|
schema:
|
|
1314
|
-
$ref: "#/components/schemas/
|
|
1565
|
+
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
1566
|
+
example:
|
|
1567
|
+
ok: false
|
|
1568
|
+
error: no_source
|
|
1569
|
+
"409":
|
|
1570
|
+
description: Refresh already in progress
|
|
1571
|
+
content:
|
|
1572
|
+
application/json:
|
|
1573
|
+
schema:
|
|
1574
|
+
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
1575
|
+
example:
|
|
1576
|
+
ok: false
|
|
1577
|
+
error: already_in_progress
|
|
1315
1578
|
|
|
1316
|
-
/workspaces/{workspaceId}/
|
|
1317
|
-
|
|
1318
|
-
tags: [
|
|
1319
|
-
summary:
|
|
1320
|
-
|
|
1321
|
-
User-triggered "Run now" path. Requires workspace editor/admin access and an active GitHub App
|
|
1322
|
-
connection. Prefer `repoId`; `providerSlug` is accepted for compatibility only when it resolves
|
|
1323
|
-
to a repository in the workspace.
|
|
1324
|
-
operationId: postReadinessAnalyze
|
|
1579
|
+
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/seats:
|
|
1580
|
+
get:
|
|
1581
|
+
tags: [Integrations]
|
|
1582
|
+
summary: List latest AI-tool seats
|
|
1583
|
+
operationId: getWorkspaceAiToolSeats
|
|
1325
1584
|
parameters:
|
|
1326
1585
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
examples:
|
|
1334
|
-
byRepoId:
|
|
1335
|
-
value:
|
|
1336
|
-
repoId: "11111111-1111-4111-8111-111111111111"
|
|
1337
|
-
byProviderSlug:
|
|
1338
|
-
value:
|
|
1339
|
-
providerSlug: "thinkai-llc/thinkai-platform-backend"
|
|
1586
|
+
- name: provider
|
|
1587
|
+
in: path
|
|
1588
|
+
required: true
|
|
1589
|
+
schema:
|
|
1590
|
+
type: string
|
|
1591
|
+
enum: [cursor]
|
|
1340
1592
|
responses:
|
|
1341
|
-
"
|
|
1342
|
-
description:
|
|
1343
|
-
content:
|
|
1344
|
-
application/json:
|
|
1345
|
-
schema:
|
|
1346
|
-
$ref: "#/components/schemas/ReadinessAnalyzeResponseDto"
|
|
1347
|
-
"400":
|
|
1348
|
-
description: Invalid body, missing GitHub connection, unsupported provider, or active run conflict inputs
|
|
1593
|
+
"200":
|
|
1594
|
+
description: Seats
|
|
1349
1595
|
content:
|
|
1350
1596
|
application/json:
|
|
1351
1597
|
schema:
|
|
1352
|
-
|
|
1598
|
+
type: object
|
|
1599
|
+
required: [seats]
|
|
1600
|
+
properties:
|
|
1601
|
+
seats:
|
|
1602
|
+
type: array
|
|
1603
|
+
items:
|
|
1604
|
+
$ref: "#/components/schemas/AiToolSeatDto"
|
|
1353
1605
|
"401":
|
|
1354
1606
|
$ref: "#/components/responses/Unauthorized"
|
|
1355
1607
|
"403":
|
|
1356
1608
|
$ref: "#/components/responses/Forbidden"
|
|
1357
|
-
"404":
|
|
1358
|
-
description: Workspace or repository not found
|
|
1359
|
-
content:
|
|
1360
|
-
application/json:
|
|
1361
|
-
schema:
|
|
1362
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1363
|
-
"409":
|
|
1364
|
-
description: A queued/running readiness analysis already exists for this repository slug
|
|
1365
|
-
content:
|
|
1366
|
-
application/json:
|
|
1367
|
-
schema:
|
|
1368
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1369
1609
|
|
|
1370
|
-
/workspaces/{workspaceId}/
|
|
1610
|
+
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/daily-usage:
|
|
1371
1611
|
get:
|
|
1372
|
-
tags: [
|
|
1373
|
-
summary:
|
|
1374
|
-
operationId:
|
|
1612
|
+
tags: [Integrations]
|
|
1613
|
+
summary: List AI-tool daily usage
|
|
1614
|
+
operationId: getWorkspaceAiToolDailyUsage
|
|
1375
1615
|
parameters:
|
|
1376
1616
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1377
|
-
- name:
|
|
1617
|
+
- name: provider
|
|
1378
1618
|
in: path
|
|
1379
1619
|
required: true
|
|
1380
1620
|
schema:
|
|
1381
1621
|
type: string
|
|
1382
|
-
|
|
1622
|
+
enum: [cursor]
|
|
1623
|
+
- name: from
|
|
1624
|
+
in: query
|
|
1625
|
+
required: false
|
|
1626
|
+
schema:
|
|
1627
|
+
type: string
|
|
1628
|
+
format: date
|
|
1629
|
+
- name: to
|
|
1630
|
+
in: query
|
|
1631
|
+
required: false
|
|
1632
|
+
schema:
|
|
1633
|
+
type: string
|
|
1634
|
+
format: date
|
|
1635
|
+
- name: externalId
|
|
1636
|
+
in: query
|
|
1637
|
+
required: false
|
|
1638
|
+
schema:
|
|
1639
|
+
type: string
|
|
1383
1640
|
responses:
|
|
1384
1641
|
"200":
|
|
1385
|
-
description:
|
|
1642
|
+
description: Usage rows
|
|
1386
1643
|
content:
|
|
1387
1644
|
application/json:
|
|
1388
1645
|
schema:
|
|
1389
|
-
|
|
1646
|
+
type: object
|
|
1647
|
+
required: [rows]
|
|
1648
|
+
properties:
|
|
1649
|
+
rows:
|
|
1650
|
+
type: array
|
|
1651
|
+
items:
|
|
1652
|
+
$ref: "#/components/schemas/AiToolDailyUsageRowDto"
|
|
1390
1653
|
"401":
|
|
1391
1654
|
$ref: "#/components/responses/Unauthorized"
|
|
1392
1655
|
"403":
|
|
1393
1656
|
$ref: "#/components/responses/Forbidden"
|
|
1394
|
-
"404":
|
|
1395
|
-
description: Workspace or run not found
|
|
1396
|
-
content:
|
|
1397
|
-
application/json:
|
|
1398
|
-
schema:
|
|
1399
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1400
1657
|
|
|
1401
|
-
/workspaces/{workspaceId}/
|
|
1658
|
+
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/spend:
|
|
1402
1659
|
get:
|
|
1403
|
-
tags: [
|
|
1404
|
-
summary:
|
|
1405
|
-
|
|
1406
|
-
Returns one stored repository scorecard with all eight dimensions and nested issues.
|
|
1407
|
-
Unknown `repoId` or a repo that belongs to another workspace returns `404` (no cross-tenant leakage).
|
|
1408
|
-
operationId: getReadinessRepo
|
|
1660
|
+
tags: [Integrations]
|
|
1661
|
+
summary: List AI-tool spend
|
|
1662
|
+
operationId: getWorkspaceAiToolSpend
|
|
1409
1663
|
parameters:
|
|
1410
1664
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1411
|
-
-
|
|
1665
|
+
- name: provider
|
|
1666
|
+
in: path
|
|
1667
|
+
required: true
|
|
1668
|
+
schema:
|
|
1669
|
+
type: string
|
|
1670
|
+
enum: [cursor]
|
|
1671
|
+
- name: cycleStartMs
|
|
1672
|
+
in: query
|
|
1673
|
+
required: false
|
|
1674
|
+
schema:
|
|
1675
|
+
type: integer
|
|
1676
|
+
format: int64
|
|
1412
1677
|
responses:
|
|
1413
1678
|
"200":
|
|
1414
|
-
description:
|
|
1415
|
-
content:
|
|
1416
|
-
application/json:
|
|
1417
|
-
schema:
|
|
1418
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1419
|
-
"400":
|
|
1420
|
-
description: Malformed `repoId` (not a UUID)
|
|
1679
|
+
description: Spend rows
|
|
1421
1680
|
content:
|
|
1422
1681
|
application/json:
|
|
1423
1682
|
schema:
|
|
1424
|
-
|
|
1683
|
+
type: object
|
|
1684
|
+
required: [rows]
|
|
1685
|
+
properties:
|
|
1686
|
+
rows:
|
|
1687
|
+
type: array
|
|
1688
|
+
items:
|
|
1689
|
+
$ref: "#/components/schemas/AiToolSpendRowDto"
|
|
1425
1690
|
"401":
|
|
1426
1691
|
$ref: "#/components/responses/Unauthorized"
|
|
1427
1692
|
"403":
|
|
1428
1693
|
$ref: "#/components/responses/Forbidden"
|
|
1429
|
-
"404":
|
|
1430
|
-
description: Workspace or repository not found
|
|
1431
|
-
content:
|
|
1432
|
-
application/json:
|
|
1433
|
-
schema:
|
|
1434
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1435
1694
|
|
|
1436
|
-
/workspaces/{workspaceId}/
|
|
1695
|
+
/workspaces/{workspaceId}/integrations/ai-tool/{provider}/status:
|
|
1437
1696
|
get:
|
|
1438
|
-
tags: [
|
|
1439
|
-
summary:
|
|
1440
|
-
|
|
1441
|
-
Returns stored repository readiness scorecards plus a flattened issue queue for the
|
|
1442
|
-
Agentic Foundation dashboard surfaces. This is read-only and does not run scoring on
|
|
1443
|
-
the request path (issue #279). Field `generatedAt` is the server timestamp when this JSON
|
|
1444
|
-
payload was assembled; it is not the same as per-repo `lastAnalyzed` on `RepoReadinessScoreDto`.
|
|
1445
|
-
operationId: getAgenticFoundationDashboard
|
|
1697
|
+
tags: [Integrations]
|
|
1698
|
+
summary: Get last refresh status
|
|
1699
|
+
operationId: getWorkspaceAiToolRefreshStatus
|
|
1446
1700
|
parameters:
|
|
1447
1701
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1702
|
+
- name: provider
|
|
1703
|
+
in: path
|
|
1704
|
+
required: true
|
|
1705
|
+
schema:
|
|
1706
|
+
type: string
|
|
1707
|
+
enum: [cursor]
|
|
1448
1708
|
responses:
|
|
1449
1709
|
"200":
|
|
1450
|
-
description:
|
|
1710
|
+
description: Refresh status
|
|
1451
1711
|
content:
|
|
1452
1712
|
application/json:
|
|
1453
1713
|
schema:
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
workspaceId: 00000000-0000-0000-0000-000000000001
|
|
1460
|
-
generatedAt: "2026-05-12T12:00:00.000Z"
|
|
1461
|
-
summary:
|
|
1462
|
-
repoCount: 0
|
|
1463
|
-
averageOverallScore: 0
|
|
1464
|
-
issueCount: 0
|
|
1465
|
-
criticalIssueCount: 0
|
|
1466
|
-
repos: []
|
|
1467
|
-
issueQueue: []
|
|
1714
|
+
type: object
|
|
1715
|
+
required: [status]
|
|
1716
|
+
properties:
|
|
1717
|
+
status:
|
|
1718
|
+
$ref: "#/components/schemas/AiToolRefreshStatusDto"
|
|
1468
1719
|
"401":
|
|
1469
1720
|
$ref: "#/components/responses/Unauthorized"
|
|
1470
1721
|
"403":
|
|
1471
1722
|
$ref: "#/components/responses/Forbidden"
|
|
1472
1723
|
"404":
|
|
1473
|
-
description:
|
|
1724
|
+
description: No refresh status yet (or provider source missing)
|
|
1474
1725
|
content:
|
|
1475
1726
|
application/json:
|
|
1476
1727
|
schema:
|
|
1477
|
-
$ref: "#/components/schemas/
|
|
1728
|
+
$ref: "#/components/schemas/AiToolRefreshResponseDto"
|
|
1729
|
+
example:
|
|
1730
|
+
ok: false
|
|
1731
|
+
error: no_source
|
|
1478
1732
|
|
|
1479
|
-
/
|
|
1733
|
+
/integrations/github/callback:
|
|
1480
1734
|
get:
|
|
1481
|
-
tags: [
|
|
1482
|
-
summary:
|
|
1735
|
+
tags: [Integrations]
|
|
1736
|
+
summary: GitHub App installation callback
|
|
1737
|
+
operationId: getGithubInstallCallback
|
|
1483
1738
|
description: >
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1739
|
+
Public callback endpoint used by GitHub App installation flow.
|
|
1740
|
+
Resolves and consumes install state, persists workspace installation linkage,
|
|
1741
|
+
then redirects to configured SPA origin with status markers.
|
|
1487
1742
|
parameters:
|
|
1488
|
-
-
|
|
1743
|
+
- name: state
|
|
1744
|
+
in: query
|
|
1745
|
+
required: true
|
|
1746
|
+
schema:
|
|
1747
|
+
type: string
|
|
1748
|
+
- name: installation_id
|
|
1749
|
+
in: query
|
|
1750
|
+
required: false
|
|
1751
|
+
schema:
|
|
1752
|
+
type: string
|
|
1753
|
+
- name: setup_action
|
|
1754
|
+
in: query
|
|
1755
|
+
required: false
|
|
1756
|
+
schema:
|
|
1757
|
+
type: string
|
|
1758
|
+
- name: error
|
|
1759
|
+
in: query
|
|
1760
|
+
required: false
|
|
1761
|
+
schema:
|
|
1762
|
+
type: string
|
|
1763
|
+
- name: error_description
|
|
1764
|
+
in: query
|
|
1765
|
+
required: false
|
|
1766
|
+
schema:
|
|
1767
|
+
type: string
|
|
1489
1768
|
responses:
|
|
1490
|
-
"
|
|
1491
|
-
description:
|
|
1769
|
+
"302":
|
|
1770
|
+
description: Redirect to ThinkAI SPA return path with GitHub connection status
|
|
1771
|
+
"501":
|
|
1772
|
+
description: Workspace store not configured
|
|
1492
1773
|
content:
|
|
1493
1774
|
application/json:
|
|
1494
1775
|
schema:
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
examples:
|
|
1499
|
-
singleRepoSlice:
|
|
1500
|
-
summary: One repo, single pillar dimension
|
|
1501
|
-
value:
|
|
1502
|
-
- repoId: 00000000-0000-0000-0000-000000000002
|
|
1503
|
-
repoName: api-gateway
|
|
1504
|
-
language: typescript
|
|
1505
|
-
overallScore: 67
|
|
1506
|
-
dimensions:
|
|
1507
|
-
- dimensionId: ai-agent-readiness
|
|
1508
|
-
score: 2
|
|
1509
|
-
maxScore: 3
|
|
1510
|
-
issues: []
|
|
1511
|
-
lastAnalyzed: "2026-05-12T12:00:00.000Z"
|
|
1512
|
-
teamId: null
|
|
1513
|
-
provider:
|
|
1514
|
-
kind: github
|
|
1515
|
-
slug: acme/api-gateway
|
|
1516
|
-
webUrl: https://github.com/acme/api-gateway
|
|
1517
|
-
defaultBranch: main
|
|
1518
|
-
externalId: null
|
|
1519
|
-
hostBaseUrl: null
|
|
1520
|
-
analysisStatus: idle
|
|
1521
|
-
activeRunId: null
|
|
1522
|
-
"401":
|
|
1523
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1524
|
-
"403":
|
|
1525
|
-
$ref: "#/components/responses/Forbidden"
|
|
1526
|
-
"404":
|
|
1527
|
-
description: Workspace does not exist
|
|
1776
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1777
|
+
"503":
|
|
1778
|
+
description: SPA origin configuration missing
|
|
1528
1779
|
content:
|
|
1529
1780
|
application/json:
|
|
1530
1781
|
schema:
|
|
1531
1782
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1532
1783
|
|
|
1533
|
-
/
|
|
1534
|
-
|
|
1535
|
-
tags: [
|
|
1536
|
-
summary:
|
|
1537
|
-
|
|
1538
|
-
|
|
1784
|
+
/integrations/github/webhook:
|
|
1785
|
+
post:
|
|
1786
|
+
tags: [Integrations]
|
|
1787
|
+
summary: GitHub App webhook receiver
|
|
1788
|
+
operationId: postGithubWebhook
|
|
1789
|
+
description: >
|
|
1790
|
+
Public webhook endpoint that verifies `X-Hub-Signature-256` and updates or
|
|
1791
|
+
removes workspace GitHub integration/cache state for installation events.
|
|
1539
1792
|
parameters:
|
|
1540
|
-
-
|
|
1793
|
+
- name: X-Hub-Signature-256
|
|
1794
|
+
in: header
|
|
1795
|
+
required: true
|
|
1796
|
+
schema:
|
|
1797
|
+
type: string
|
|
1798
|
+
- name: X-GitHub-Event
|
|
1799
|
+
in: header
|
|
1800
|
+
required: true
|
|
1801
|
+
schema:
|
|
1802
|
+
type: string
|
|
1803
|
+
requestBody:
|
|
1804
|
+
required: true
|
|
1805
|
+
content:
|
|
1806
|
+
application/json:
|
|
1807
|
+
schema:
|
|
1808
|
+
type: object
|
|
1809
|
+
additionalProperties: true
|
|
1541
1810
|
responses:
|
|
1542
1811
|
"200":
|
|
1543
|
-
description:
|
|
1812
|
+
description: Webhook accepted
|
|
1813
|
+
"400":
|
|
1814
|
+
description: Invalid payload
|
|
1544
1815
|
content:
|
|
1545
1816
|
application/json:
|
|
1546
1817
|
schema:
|
|
1547
|
-
|
|
1548
|
-
items:
|
|
1549
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1818
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1550
1819
|
"401":
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1820
|
+
description: Invalid webhook signature
|
|
1821
|
+
content:
|
|
1822
|
+
application/json:
|
|
1823
|
+
schema:
|
|
1824
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1825
|
+
"501":
|
|
1826
|
+
description: Workspace store not configured
|
|
1827
|
+
content:
|
|
1828
|
+
application/json:
|
|
1829
|
+
schema:
|
|
1830
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1831
|
+
"503":
|
|
1832
|
+
description: Missing GitHub webhook secret or GitHub App configuration
|
|
1556
1833
|
content:
|
|
1557
1834
|
application/json:
|
|
1558
1835
|
schema:
|
|
1559
1836
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1560
1837
|
|
|
1561
|
-
/workspaces/{workspaceId}/
|
|
1838
|
+
/workspaces/{workspaceId}/ai-readiness:
|
|
1562
1839
|
get:
|
|
1563
|
-
tags: [
|
|
1564
|
-
summary:
|
|
1565
|
-
|
|
1566
|
-
operationId: getAgenticFoundationCodebaseQuality
|
|
1840
|
+
tags: [AIReadiness]
|
|
1841
|
+
summary: Get AI readiness
|
|
1842
|
+
operationId: getAiReadiness
|
|
1567
1843
|
parameters:
|
|
1568
1844
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1569
1845
|
responses:
|
|
1570
1846
|
"200":
|
|
1571
|
-
description:
|
|
1847
|
+
description: State or JSON null
|
|
1572
1848
|
content:
|
|
1573
1849
|
application/json:
|
|
1574
1850
|
schema:
|
|
1575
|
-
|
|
1576
|
-
items:
|
|
1577
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1851
|
+
$ref: "#/components/schemas/AIReadinessDto"
|
|
1578
1852
|
"401":
|
|
1579
1853
|
$ref: "#/components/responses/Unauthorized"
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1854
|
+
put:
|
|
1855
|
+
tags: [AIReadiness]
|
|
1856
|
+
summary: Upsert AI readiness
|
|
1857
|
+
operationId: putAiReadiness
|
|
1858
|
+
parameters:
|
|
1859
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
1860
|
+
requestBody:
|
|
1861
|
+
required: true
|
|
1862
|
+
content:
|
|
1863
|
+
application/json:
|
|
1864
|
+
schema:
|
|
1865
|
+
$ref: "#/components/schemas/AIReadinessDto"
|
|
1866
|
+
responses:
|
|
1867
|
+
"204":
|
|
1868
|
+
description: Saved
|
|
1869
|
+
"401":
|
|
1870
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1871
|
+
|
|
1872
|
+
/workspaces/{workspaceId}/ai-readiness/maturity:
|
|
1873
|
+
post:
|
|
1874
|
+
tags: [AIReadiness]
|
|
1875
|
+
summary: Compute maturity level
|
|
1876
|
+
operationId: postAiReadinessMaturity
|
|
1877
|
+
parameters:
|
|
1878
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
1879
|
+
requestBody:
|
|
1880
|
+
required: true
|
|
1881
|
+
content:
|
|
1882
|
+
application/json:
|
|
1883
|
+
schema:
|
|
1884
|
+
$ref: "#/components/schemas/AIReadinessDto"
|
|
1885
|
+
responses:
|
|
1886
|
+
"200":
|
|
1887
|
+
description: Derived level
|
|
1584
1888
|
content:
|
|
1585
1889
|
application/json:
|
|
1586
1890
|
schema:
|
|
1587
|
-
$ref: "#/components/schemas/
|
|
1891
|
+
$ref: "#/components/schemas/AiMaturityResultDto"
|
|
1892
|
+
"401":
|
|
1893
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1588
1894
|
|
|
1589
|
-
/workspaces/{workspaceId}/
|
|
1895
|
+
/workspaces/{workspaceId}/tech-stack:
|
|
1590
1896
|
get:
|
|
1591
|
-
tags: [
|
|
1592
|
-
summary:
|
|
1593
|
-
|
|
1594
|
-
operationId: getAgenticFoundationTestQa
|
|
1897
|
+
tags: [TechStack]
|
|
1898
|
+
summary: Get tech stack
|
|
1899
|
+
operationId: getTechStack
|
|
1595
1900
|
parameters:
|
|
1596
1901
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1597
1902
|
responses:
|
|
1598
1903
|
"200":
|
|
1599
|
-
description:
|
|
1904
|
+
description: >
|
|
1905
|
+
Saved tech stack DTO, or JSON `null` when the workspace exists but no stack
|
|
1906
|
+
has been saved yet. Clients should merge `null` with their empty defaults.
|
|
1600
1907
|
content:
|
|
1601
1908
|
application/json:
|
|
1602
1909
|
schema:
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
$ref: "#/components/schemas/
|
|
1910
|
+
nullable: true
|
|
1911
|
+
allOf:
|
|
1912
|
+
- $ref: "#/components/schemas/TechStackDto"
|
|
1913
|
+
"400":
|
|
1914
|
+
description: Malformed workspaceId
|
|
1915
|
+
content:
|
|
1916
|
+
application/json:
|
|
1917
|
+
schema:
|
|
1918
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1606
1919
|
"401":
|
|
1607
1920
|
$ref: "#/components/responses/Unauthorized"
|
|
1608
1921
|
"403":
|
|
@@ -1613,24 +1926,27 @@ paths:
|
|
|
1613
1926
|
application/json:
|
|
1614
1927
|
schema:
|
|
1615
1928
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
summary: Observability pillar (observability slice)
|
|
1621
|
-
description: Returns per-repo `observability` dimension only (issue #284).
|
|
1622
|
-
operationId: getAgenticFoundationObservability
|
|
1929
|
+
put:
|
|
1930
|
+
tags: [TechStack]
|
|
1931
|
+
summary: Upsert tech stack
|
|
1932
|
+
operationId: putTechStack
|
|
1623
1933
|
parameters:
|
|
1624
1934
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1935
|
+
requestBody:
|
|
1936
|
+
required: true
|
|
1937
|
+
content:
|
|
1938
|
+
application/json:
|
|
1939
|
+
schema:
|
|
1940
|
+
$ref: "#/components/schemas/TechStackDto"
|
|
1625
1941
|
responses:
|
|
1626
|
-
"
|
|
1627
|
-
description:
|
|
1942
|
+
"204":
|
|
1943
|
+
description: Saved
|
|
1944
|
+
"400":
|
|
1945
|
+
description: Body fails validation (unknown keys, bounds, missing required fields)
|
|
1628
1946
|
content:
|
|
1629
1947
|
application/json:
|
|
1630
1948
|
schema:
|
|
1631
|
-
|
|
1632
|
-
items:
|
|
1633
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1949
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1634
1950
|
"401":
|
|
1635
1951
|
$ref: "#/components/responses/Unauthorized"
|
|
1636
1952
|
"403":
|
|
@@ -1642,103 +1958,99 @@ paths:
|
|
|
1642
1958
|
schema:
|
|
1643
1959
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1644
1960
|
|
|
1645
|
-
/workspaces/{workspaceId}/
|
|
1961
|
+
/workspaces/{workspaceId}/nda:
|
|
1646
1962
|
get:
|
|
1647
|
-
tags: [
|
|
1648
|
-
summary:
|
|
1649
|
-
|
|
1650
|
-
operationId: getAgenticFoundationApiContract
|
|
1963
|
+
tags: [NDA]
|
|
1964
|
+
summary: Get NDA completion state
|
|
1965
|
+
operationId: getNda
|
|
1651
1966
|
parameters:
|
|
1652
1967
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1653
1968
|
responses:
|
|
1654
1969
|
"200":
|
|
1655
|
-
description:
|
|
1970
|
+
description: Completion or JSON null
|
|
1656
1971
|
content:
|
|
1657
1972
|
application/json:
|
|
1658
1973
|
schema:
|
|
1659
|
-
|
|
1660
|
-
items:
|
|
1661
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1974
|
+
$ref: "#/components/schemas/NdaCompletionDto"
|
|
1662
1975
|
"401":
|
|
1663
1976
|
$ref: "#/components/responses/Unauthorized"
|
|
1664
|
-
"403":
|
|
1665
|
-
$ref: "#/components/responses/Forbidden"
|
|
1666
|
-
"404":
|
|
1667
|
-
description: Workspace does not exist
|
|
1668
|
-
content:
|
|
1669
|
-
application/json:
|
|
1670
|
-
schema:
|
|
1671
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1672
1977
|
|
|
1673
|
-
/workspaces/{workspaceId}/
|
|
1978
|
+
/workspaces/{workspaceId}/nda/template:
|
|
1674
1979
|
get:
|
|
1675
|
-
tags: [
|
|
1676
|
-
summary:
|
|
1677
|
-
|
|
1678
|
-
operationId: getAgenticFoundationPlatformGovernance
|
|
1980
|
+
tags: [NDA]
|
|
1981
|
+
summary: NDA template for display
|
|
1982
|
+
operationId: getNdaTemplate
|
|
1679
1983
|
parameters:
|
|
1680
1984
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1681
1985
|
responses:
|
|
1682
1986
|
"200":
|
|
1683
|
-
description:
|
|
1987
|
+
description: Template
|
|
1684
1988
|
content:
|
|
1685
1989
|
application/json:
|
|
1686
1990
|
schema:
|
|
1687
|
-
|
|
1688
|
-
items:
|
|
1689
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1991
|
+
$ref: "#/components/schemas/NdaTemplateDto"
|
|
1690
1992
|
"401":
|
|
1691
1993
|
$ref: "#/components/responses/Unauthorized"
|
|
1692
|
-
"403":
|
|
1693
|
-
$ref: "#/components/responses/Forbidden"
|
|
1694
|
-
"404":
|
|
1695
|
-
description: Workspace does not exist
|
|
1696
|
-
content:
|
|
1697
|
-
application/json:
|
|
1698
|
-
schema:
|
|
1699
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1700
1994
|
|
|
1701
|
-
/workspaces/{workspaceId}/
|
|
1702
|
-
|
|
1703
|
-
tags: [
|
|
1704
|
-
summary:
|
|
1705
|
-
|
|
1706
|
-
operationId: getAgenticFoundationDeliveryGovernance
|
|
1995
|
+
/workspaces/{workspaceId}/nda/sign:
|
|
1996
|
+
post:
|
|
1997
|
+
tags: [NDA]
|
|
1998
|
+
summary: Electronic NDA signature
|
|
1999
|
+
operationId: postNdaSign
|
|
1707
2000
|
parameters:
|
|
1708
2001
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2002
|
+
requestBody:
|
|
2003
|
+
required: true
|
|
2004
|
+
content:
|
|
2005
|
+
application/json:
|
|
2006
|
+
schema:
|
|
2007
|
+
$ref: "#/components/schemas/NdaSignatureDto"
|
|
1709
2008
|
responses:
|
|
1710
2009
|
"200":
|
|
1711
|
-
description:
|
|
2010
|
+
description: Completion record
|
|
1712
2011
|
content:
|
|
1713
2012
|
application/json:
|
|
1714
2013
|
schema:
|
|
1715
|
-
|
|
1716
|
-
items:
|
|
1717
|
-
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2014
|
+
$ref: "#/components/schemas/NdaCompletionDto"
|
|
1718
2015
|
"401":
|
|
1719
2016
|
$ref: "#/components/responses/Unauthorized"
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
2017
|
+
|
|
2018
|
+
/workspaces/{workspaceId}/nda/external:
|
|
2019
|
+
post:
|
|
2020
|
+
tags: [NDA]
|
|
2021
|
+
summary: External NDA path (after Supabase upload)
|
|
2022
|
+
description: >
|
|
2023
|
+
Preferred body uses `storagePath` after client upload to the `nda-documents` bucket (§14).
|
|
2024
|
+
Multipart variant may be supported by the server as an alternative.
|
|
2025
|
+
operationId: postNdaExternal
|
|
2026
|
+
parameters:
|
|
2027
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2028
|
+
requestBody:
|
|
2029
|
+
required: true
|
|
2030
|
+
content:
|
|
2031
|
+
application/json:
|
|
2032
|
+
schema:
|
|
2033
|
+
$ref: "#/components/schemas/NdaExternalBodyDto"
|
|
2034
|
+
responses:
|
|
2035
|
+
"200":
|
|
2036
|
+
description: Completion record
|
|
1724
2037
|
content:
|
|
1725
2038
|
application/json:
|
|
1726
2039
|
schema:
|
|
1727
|
-
$ref: "#/components/schemas/
|
|
2040
|
+
$ref: "#/components/schemas/NdaCompletionDto"
|
|
2041
|
+
"401":
|
|
2042
|
+
$ref: "#/components/responses/Unauthorized"
|
|
1728
2043
|
|
|
1729
|
-
/workspaces/{workspaceId}/
|
|
2044
|
+
/workspaces/{workspaceId}/readiness/repos:
|
|
1730
2045
|
get:
|
|
1731
|
-
tags: [
|
|
1732
|
-
summary:
|
|
1733
|
-
|
|
1734
|
-
Returns the same payload as `GET .../readiness/repos` (all dimensions per repo) for
|
|
1735
|
-
cross-pillar hub views (issue #288).
|
|
1736
|
-
operationId: getAgenticFoundationAiResolutionHub
|
|
2046
|
+
tags: [RepositoryReadiness]
|
|
2047
|
+
summary: List repo readiness scores
|
|
2048
|
+
operationId: listReadinessRepos
|
|
1737
2049
|
parameters:
|
|
1738
2050
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1739
2051
|
responses:
|
|
1740
2052
|
"200":
|
|
1741
|
-
description:
|
|
2053
|
+
description: Repositories analyzed
|
|
1742
2054
|
content:
|
|
1743
2055
|
application/json:
|
|
1744
2056
|
schema:
|
|
@@ -1756,94 +2068,111 @@ paths:
|
|
|
1756
2068
|
schema:
|
|
1757
2069
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1758
2070
|
|
|
1759
|
-
/workspaces/{workspaceId}/readiness/
|
|
1760
|
-
|
|
2071
|
+
/workspaces/{workspaceId}/readiness/analyze:
|
|
2072
|
+
post:
|
|
1761
2073
|
tags: [RepositoryReadiness]
|
|
1762
|
-
summary:
|
|
2074
|
+
summary: Enqueue AI readiness analysis for one repository
|
|
1763
2075
|
description: >
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
2076
|
+
User-triggered "Run now" path. Requires workspace editor/admin access and an active GitHub App
|
|
2077
|
+
connection. Prefer `repoId`; `providerSlug` is accepted for compatibility only when it resolves
|
|
2078
|
+
to a repository in the workspace.
|
|
2079
|
+
operationId: postReadinessAnalyze
|
|
1767
2080
|
parameters:
|
|
1768
2081
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2082
|
+
requestBody:
|
|
2083
|
+
required: true
|
|
2084
|
+
content:
|
|
2085
|
+
application/json:
|
|
2086
|
+
schema:
|
|
2087
|
+
$ref: "#/components/schemas/ReadinessAnalyzeBodyDto"
|
|
2088
|
+
examples:
|
|
2089
|
+
byRepoId:
|
|
2090
|
+
value:
|
|
2091
|
+
repoId: "11111111-1111-4111-8111-111111111111"
|
|
2092
|
+
byProviderSlug:
|
|
2093
|
+
value:
|
|
2094
|
+
providerSlug: "thinkai-llc/thinkai-platform-backend"
|
|
1769
2095
|
responses:
|
|
1770
|
-
"
|
|
1771
|
-
description:
|
|
2096
|
+
"202":
|
|
2097
|
+
description: Run queued
|
|
1772
2098
|
content:
|
|
1773
2099
|
application/json:
|
|
1774
2100
|
schema:
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
2101
|
+
$ref: "#/components/schemas/ReadinessAnalyzeResponseDto"
|
|
2102
|
+
"400":
|
|
2103
|
+
description: Invalid body, missing GitHub connection, unsupported provider, or active run conflict inputs
|
|
2104
|
+
content:
|
|
2105
|
+
application/json:
|
|
2106
|
+
schema:
|
|
2107
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1778
2108
|
"401":
|
|
1779
2109
|
$ref: "#/components/responses/Unauthorized"
|
|
1780
2110
|
"403":
|
|
1781
2111
|
$ref: "#/components/responses/Forbidden"
|
|
1782
2112
|
"404":
|
|
1783
|
-
description: Workspace
|
|
2113
|
+
description: Workspace or repository not found
|
|
2114
|
+
content:
|
|
2115
|
+
application/json:
|
|
2116
|
+
schema:
|
|
2117
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2118
|
+
"409":
|
|
2119
|
+
description: A queued/running readiness analysis already exists for this repository slug
|
|
1784
2120
|
content:
|
|
1785
2121
|
application/json:
|
|
1786
2122
|
schema:
|
|
1787
2123
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1788
2124
|
|
|
1789
|
-
/workspaces/{workspaceId}/readiness/
|
|
2125
|
+
/workspaces/{workspaceId}/readiness/runs/{runId}:
|
|
1790
2126
|
get:
|
|
1791
2127
|
tags: [RepositoryReadiness]
|
|
1792
|
-
summary:
|
|
1793
|
-
|
|
1794
|
-
Returns persisted fix-queue rows for the workspace (newest first). Empty array when none exist.
|
|
1795
|
-
operationId: listReadinessFixes
|
|
2128
|
+
summary: Get readiness analysis run status
|
|
2129
|
+
operationId: getReadinessRun
|
|
1796
2130
|
parameters:
|
|
1797
2131
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2132
|
+
- name: runId
|
|
2133
|
+
in: path
|
|
2134
|
+
required: true
|
|
2135
|
+
schema:
|
|
2136
|
+
type: string
|
|
2137
|
+
format: uuid
|
|
1798
2138
|
responses:
|
|
1799
2139
|
"200":
|
|
1800
|
-
description:
|
|
2140
|
+
description: Run status
|
|
1801
2141
|
content:
|
|
1802
2142
|
application/json:
|
|
1803
2143
|
schema:
|
|
1804
|
-
|
|
1805
|
-
items:
|
|
1806
|
-
$ref: "#/components/schemas/FixRequestDto"
|
|
2144
|
+
$ref: "#/components/schemas/ReadinessRunSummaryDto"
|
|
1807
2145
|
"401":
|
|
1808
2146
|
$ref: "#/components/responses/Unauthorized"
|
|
1809
2147
|
"403":
|
|
1810
2148
|
$ref: "#/components/responses/Forbidden"
|
|
1811
2149
|
"404":
|
|
1812
|
-
description: Workspace
|
|
2150
|
+
description: Workspace or run not found
|
|
1813
2151
|
content:
|
|
1814
2152
|
application/json:
|
|
1815
2153
|
schema:
|
|
1816
2154
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1817
|
-
|
|
2155
|
+
|
|
2156
|
+
/workspaces/{workspaceId}/readiness/repos/{repoId}:
|
|
2157
|
+
get:
|
|
1818
2158
|
tags: [RepositoryReadiness]
|
|
1819
|
-
summary:
|
|
2159
|
+
summary: Single repo readiness
|
|
1820
2160
|
description: >
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
operationId: postReadinessFix
|
|
2161
|
+
Returns one stored repository scorecard with all eight dimensions and nested issues.
|
|
2162
|
+
Unknown `repoId` or a repo that belongs to another workspace returns `404` (no cross-tenant leakage).
|
|
2163
|
+
operationId: getReadinessRepo
|
|
1825
2164
|
parameters:
|
|
1826
2165
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1827
|
-
|
|
1828
|
-
required: true
|
|
1829
|
-
content:
|
|
1830
|
-
application/json:
|
|
1831
|
-
schema:
|
|
1832
|
-
$ref: "#/components/schemas/CreateFixRequestBodyDto"
|
|
1833
|
-
examples:
|
|
1834
|
-
enqueue:
|
|
1835
|
-
value:
|
|
1836
|
-
issueId: "22222222-2222-2222-2222-222222222222"
|
|
1837
|
-
repoId: "11111111-1111-4111-8111-111111111111"
|
|
2166
|
+
- $ref: "#/components/parameters/RepoId"
|
|
1838
2167
|
responses:
|
|
1839
2168
|
"200":
|
|
1840
|
-
description:
|
|
2169
|
+
description: Repo score
|
|
1841
2170
|
content:
|
|
1842
2171
|
application/json:
|
|
1843
2172
|
schema:
|
|
1844
|
-
$ref: "#/components/schemas/
|
|
2173
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1845
2174
|
"400":
|
|
1846
|
-
description:
|
|
2175
|
+
description: Malformed `repoId` (not a UUID)
|
|
1847
2176
|
content:
|
|
1848
2177
|
application/json:
|
|
1849
2178
|
schema:
|
|
@@ -1853,239 +2182,182 @@ paths:
|
|
|
1853
2182
|
"403":
|
|
1854
2183
|
$ref: "#/components/responses/Forbidden"
|
|
1855
2184
|
"404":
|
|
1856
|
-
description: Workspace
|
|
2185
|
+
description: Workspace or repository not found
|
|
1857
2186
|
content:
|
|
1858
2187
|
application/json:
|
|
1859
2188
|
schema:
|
|
1860
2189
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1861
2190
|
|
|
1862
|
-
/workspaces/{workspaceId}/
|
|
1863
|
-
|
|
1864
|
-
tags: [
|
|
1865
|
-
summary:
|
|
2191
|
+
/workspaces/{workspaceId}/agentic-foundation/dashboard:
|
|
2192
|
+
get:
|
|
2193
|
+
tags: [AgenticFoundation]
|
|
2194
|
+
summary: Agentic Foundation dashboard
|
|
1866
2195
|
description: >
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
2196
|
+
Returns stored repository readiness scorecards plus a flattened issue queue for the
|
|
2197
|
+
Agentic Foundation dashboard surfaces. This is read-only and does not run scoring on
|
|
2198
|
+
the request path (issue #279). Field `generatedAt` is the server timestamp when this JSON
|
|
2199
|
+
payload was assembled; it is not the same as per-repo `lastAnalyzed` on `RepoReadinessScoreDto`.
|
|
2200
|
+
operationId: getAgenticFoundationDashboard
|
|
1871
2201
|
parameters:
|
|
1872
2202
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1873
|
-
- $ref: "#/components/parameters/FixId"
|
|
1874
2203
|
responses:
|
|
1875
2204
|
"200":
|
|
1876
|
-
description:
|
|
2205
|
+
description: Dashboard scorecards and issue queue
|
|
1877
2206
|
content:
|
|
1878
2207
|
application/json:
|
|
1879
2208
|
schema:
|
|
1880
|
-
$ref: "#/components/schemas/
|
|
2209
|
+
$ref: "#/components/schemas/AgenticFoundationDashboardDto"
|
|
2210
|
+
examples:
|
|
2211
|
+
emptyWorkspace:
|
|
2212
|
+
summary: No repos analyzed yet
|
|
2213
|
+
value:
|
|
2214
|
+
workspaceId: 00000000-0000-0000-0000-000000000001
|
|
2215
|
+
generatedAt: "2026-05-12T12:00:00.000Z"
|
|
2216
|
+
summary:
|
|
2217
|
+
repoCount: 0
|
|
2218
|
+
averageOverallScore: 0
|
|
2219
|
+
issueCount: 0
|
|
2220
|
+
criticalIssueCount: 0
|
|
2221
|
+
repos: []
|
|
2222
|
+
issueQueue: []
|
|
1881
2223
|
"401":
|
|
1882
2224
|
$ref: "#/components/responses/Unauthorized"
|
|
1883
2225
|
"403":
|
|
1884
2226
|
$ref: "#/components/responses/Forbidden"
|
|
1885
2227
|
"404":
|
|
1886
|
-
description:
|
|
1887
|
-
content:
|
|
1888
|
-
application/json:
|
|
1889
|
-
schema:
|
|
1890
|
-
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1891
|
-
"409":
|
|
1892
|
-
description: Fix is not in a retryable state
|
|
2228
|
+
description: Workspace does not exist
|
|
1893
2229
|
content:
|
|
1894
2230
|
application/json:
|
|
1895
2231
|
schema:
|
|
1896
2232
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1897
2233
|
|
|
1898
|
-
/workspaces/{workspaceId}/
|
|
2234
|
+
/workspaces/{workspaceId}/agentic-foundation/agentic-readiness:
|
|
1899
2235
|
get:
|
|
1900
|
-
tags: [
|
|
1901
|
-
summary:
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
"200":
|
|
1907
|
-
description: Squad
|
|
1908
|
-
content:
|
|
1909
|
-
application/json:
|
|
1910
|
-
schema:
|
|
1911
|
-
$ref: "#/components/schemas/SquadDto"
|
|
1912
|
-
"401":
|
|
1913
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1914
|
-
put:
|
|
1915
|
-
tags: [SquadProjects]
|
|
1916
|
-
summary: Upsert squad
|
|
1917
|
-
operationId: putSquad
|
|
1918
|
-
parameters:
|
|
1919
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
1920
|
-
requestBody:
|
|
1921
|
-
required: true
|
|
1922
|
-
content:
|
|
1923
|
-
application/json:
|
|
1924
|
-
schema:
|
|
1925
|
-
$ref: "#/components/schemas/SquadDto"
|
|
1926
|
-
responses:
|
|
1927
|
-
"204":
|
|
1928
|
-
description: Saved
|
|
1929
|
-
"401":
|
|
1930
|
-
$ref: "#/components/responses/Unauthorized"
|
|
1931
|
-
|
|
1932
|
-
/workspaces/{workspaceId}/projects:
|
|
1933
|
-
get:
|
|
1934
|
-
tags: [SquadProjects]
|
|
1935
|
-
summary: List projects
|
|
1936
|
-
operationId: listProjects
|
|
2236
|
+
tags: [AgenticFoundation]
|
|
2237
|
+
summary: Agentic readiness pillar (stored dimension slice)
|
|
2238
|
+
description: >
|
|
2239
|
+
Returns `RepoReadinessScoreDto` rows with only the `ai-agent-readiness` dimension populated
|
|
2240
|
+
per repo. Same auth and persistence source as `GET .../readiness/repos` (issue #280).
|
|
2241
|
+
operationId: getAgenticFoundationAgenticReadiness
|
|
1937
2242
|
parameters:
|
|
1938
2243
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1939
2244
|
responses:
|
|
1940
2245
|
"200":
|
|
1941
|
-
description:
|
|
2246
|
+
description: Repositories with ai-agent-readiness slice
|
|
1942
2247
|
content:
|
|
1943
2248
|
application/json:
|
|
1944
2249
|
schema:
|
|
1945
2250
|
type: array
|
|
1946
2251
|
items:
|
|
1947
|
-
$ref: "#/components/schemas/
|
|
2252
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2253
|
+
examples:
|
|
2254
|
+
singleRepoSlice:
|
|
2255
|
+
summary: One repo, single pillar dimension
|
|
2256
|
+
value:
|
|
2257
|
+
- repoId: 00000000-0000-0000-0000-000000000002
|
|
2258
|
+
repoName: api-gateway
|
|
2259
|
+
language: typescript
|
|
2260
|
+
overallScore: 67
|
|
2261
|
+
dimensions:
|
|
2262
|
+
- dimensionId: ai-agent-readiness
|
|
2263
|
+
score: 2
|
|
2264
|
+
maxScore: 3
|
|
2265
|
+
issues: []
|
|
2266
|
+
lastAnalyzed: "2026-05-12T12:00:00.000Z"
|
|
2267
|
+
teamId: null
|
|
2268
|
+
provider:
|
|
2269
|
+
kind: github
|
|
2270
|
+
slug: acme/api-gateway
|
|
2271
|
+
webUrl: https://github.com/acme/api-gateway
|
|
2272
|
+
defaultBranch: main
|
|
2273
|
+
externalId: null
|
|
2274
|
+
hostBaseUrl: null
|
|
2275
|
+
analysisStatus: idle
|
|
2276
|
+
activeRunId: null
|
|
1948
2277
|
"401":
|
|
1949
2278
|
$ref: "#/components/responses/Unauthorized"
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
parameters:
|
|
1955
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
1956
|
-
requestBody:
|
|
1957
|
-
required: true
|
|
1958
|
-
content:
|
|
1959
|
-
application/json:
|
|
1960
|
-
schema:
|
|
1961
|
-
$ref: "#/components/schemas/ProjectDto"
|
|
1962
|
-
responses:
|
|
1963
|
-
"200":
|
|
1964
|
-
description: Created project
|
|
2279
|
+
"403":
|
|
2280
|
+
$ref: "#/components/responses/Forbidden"
|
|
2281
|
+
"404":
|
|
2282
|
+
description: Workspace does not exist
|
|
1965
2283
|
content:
|
|
1966
2284
|
application/json:
|
|
1967
2285
|
schema:
|
|
1968
|
-
$ref: "#/components/schemas/
|
|
1969
|
-
"401":
|
|
1970
|
-
$ref: "#/components/responses/Unauthorized"
|
|
2286
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1971
2287
|
|
|
1972
|
-
/workspaces/{workspaceId}/
|
|
1973
|
-
|
|
1974
|
-
tags: [
|
|
1975
|
-
summary:
|
|
1976
|
-
|
|
2288
|
+
/workspaces/{workspaceId}/agentic-foundation/repository-health:
|
|
2289
|
+
get:
|
|
2290
|
+
tags: [AgenticFoundation]
|
|
2291
|
+
summary: Repository health pillar (repo-hygiene slice)
|
|
2292
|
+
description: Returns per-repo `repo-hygiene` dimension only (issue #281).
|
|
2293
|
+
operationId: getAgenticFoundationRepositoryHealth
|
|
1977
2294
|
parameters:
|
|
1978
2295
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
1979
|
-
- $ref: "#/components/parameters/ProjectId"
|
|
1980
|
-
requestBody:
|
|
1981
|
-
required: true
|
|
1982
|
-
content:
|
|
1983
|
-
application/json:
|
|
1984
|
-
schema:
|
|
1985
|
-
$ref: "#/components/schemas/ProjectPatchDto"
|
|
1986
2296
|
responses:
|
|
1987
2297
|
"200":
|
|
1988
|
-
description:
|
|
2298
|
+
description: Repositories with repo-hygiene slice
|
|
1989
2299
|
content:
|
|
1990
2300
|
application/json:
|
|
1991
2301
|
schema:
|
|
1992
|
-
|
|
2302
|
+
type: array
|
|
2303
|
+
items:
|
|
2304
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
1993
2305
|
"401":
|
|
1994
2306
|
$ref: "#/components/responses/Unauthorized"
|
|
2307
|
+
"403":
|
|
2308
|
+
$ref: "#/components/responses/Forbidden"
|
|
2309
|
+
"404":
|
|
2310
|
+
description: Workspace does not exist
|
|
2311
|
+
content:
|
|
2312
|
+
application/json:
|
|
2313
|
+
schema:
|
|
2314
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
1995
2315
|
|
|
1996
|
-
/workspaces/{workspaceId}/
|
|
2316
|
+
/workspaces/{workspaceId}/agentic-foundation/codebase-quality:
|
|
1997
2317
|
get:
|
|
1998
|
-
tags: [
|
|
1999
|
-
summary:
|
|
2000
|
-
|
|
2318
|
+
tags: [AgenticFoundation]
|
|
2319
|
+
summary: Codebase quality pillar (stack-quality slice)
|
|
2320
|
+
description: Returns per-repo `stack-quality` dimension only (issue #282).
|
|
2321
|
+
operationId: getAgenticFoundationCodebaseQuality
|
|
2001
2322
|
parameters:
|
|
2002
2323
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2003
|
-
- name: limit
|
|
2004
|
-
in: query
|
|
2005
|
-
schema: { type: integer, minimum: 1 }
|
|
2006
|
-
- name: offset
|
|
2007
|
-
in: query
|
|
2008
|
-
schema: { type: integer, minimum: 0 }
|
|
2009
2324
|
responses:
|
|
2010
2325
|
"200":
|
|
2011
|
-
description:
|
|
2326
|
+
description: Repositories with stack-quality slice
|
|
2012
2327
|
content:
|
|
2013
2328
|
application/json:
|
|
2014
2329
|
schema:
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
/workspaces/{workspaceId}/notifications/{id}/read:
|
|
2020
|
-
post:
|
|
2021
|
-
tags: [Notifications]
|
|
2022
|
-
summary: Mark notification read
|
|
2023
|
-
operationId: postNotificationRead
|
|
2024
|
-
parameters:
|
|
2025
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
2026
|
-
- $ref: "#/components/parameters/NotificationId"
|
|
2027
|
-
responses:
|
|
2028
|
-
"204":
|
|
2029
|
-
description: Updated
|
|
2030
|
-
"401":
|
|
2031
|
-
$ref: "#/components/responses/Unauthorized"
|
|
2032
|
-
|
|
2033
|
-
/workspaces/{workspaceId}/notifications/read-all:
|
|
2034
|
-
post:
|
|
2035
|
-
tags: [Notifications]
|
|
2036
|
-
summary: Mark all notifications read
|
|
2037
|
-
operationId: postNotificationsReadAll
|
|
2038
|
-
parameters:
|
|
2039
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
2040
|
-
responses:
|
|
2041
|
-
"204":
|
|
2042
|
-
description: Updated
|
|
2330
|
+
type: array
|
|
2331
|
+
items:
|
|
2332
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2043
2333
|
"401":
|
|
2044
2334
|
$ref: "#/components/responses/Unauthorized"
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
summary: Generate AI strategy recommendations
|
|
2050
|
-
operationId: postAiStrategyRecommend
|
|
2051
|
-
parameters:
|
|
2052
|
-
- $ref: "#/components/parameters/WorkspaceId"
|
|
2053
|
-
requestBody:
|
|
2054
|
-
required: true
|
|
2055
|
-
content:
|
|
2056
|
-
application/json:
|
|
2057
|
-
schema:
|
|
2058
|
-
$ref: "#/components/schemas/AiStrategyRecommendBodyDto"
|
|
2059
|
-
responses:
|
|
2060
|
-
"200":
|
|
2061
|
-
description: Plan
|
|
2335
|
+
"403":
|
|
2336
|
+
$ref: "#/components/responses/Forbidden"
|
|
2337
|
+
"404":
|
|
2338
|
+
description: Workspace does not exist
|
|
2062
2339
|
content:
|
|
2063
2340
|
application/json:
|
|
2064
2341
|
schema:
|
|
2065
|
-
$ref: "#/components/schemas/
|
|
2066
|
-
"401":
|
|
2067
|
-
$ref: "#/components/responses/Unauthorized"
|
|
2342
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2068
2343
|
|
|
2069
|
-
/workspaces/{workspaceId}/
|
|
2344
|
+
/workspaces/{workspaceId}/agentic-foundation/test-qa:
|
|
2070
2345
|
get:
|
|
2071
|
-
tags: [
|
|
2072
|
-
summary:
|
|
2073
|
-
|
|
2346
|
+
tags: [AgenticFoundation]
|
|
2347
|
+
summary: Test and QA pillar (tests-qa slice)
|
|
2348
|
+
description: Returns per-repo `tests-qa` dimension only (issue #283).
|
|
2349
|
+
operationId: getAgenticFoundationTestQa
|
|
2074
2350
|
parameters:
|
|
2075
2351
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2076
2352
|
responses:
|
|
2077
2353
|
"200":
|
|
2078
|
-
description:
|
|
2079
|
-
content:
|
|
2080
|
-
application/json:
|
|
2081
|
-
schema:
|
|
2082
|
-
$ref: "#/components/schemas/JourneyProgressDto"
|
|
2083
|
-
"400":
|
|
2084
|
-
description: Malformed workspaceId
|
|
2354
|
+
description: Repositories with tests-qa slice
|
|
2085
2355
|
content:
|
|
2086
2356
|
application/json:
|
|
2087
2357
|
schema:
|
|
2088
|
-
|
|
2358
|
+
type: array
|
|
2359
|
+
items:
|
|
2360
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2089
2361
|
"401":
|
|
2090
2362
|
$ref: "#/components/responses/Unauthorized"
|
|
2091
2363
|
"403":
|
|
@@ -2096,34 +2368,24 @@ paths:
|
|
|
2096
2368
|
application/json:
|
|
2097
2369
|
schema:
|
|
2098
2370
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2371
|
+
|
|
2372
|
+
/workspaces/{workspaceId}/agentic-foundation/observability:
|
|
2373
|
+
get:
|
|
2374
|
+
tags: [AgenticFoundation]
|
|
2375
|
+
summary: Observability pillar (observability slice)
|
|
2376
|
+
description: Returns per-repo `observability` dimension only (issue #284).
|
|
2377
|
+
operationId: getAgenticFoundationObservability
|
|
2106
2378
|
parameters:
|
|
2107
2379
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2108
|
-
requestBody:
|
|
2109
|
-
required: true
|
|
2110
|
-
content:
|
|
2111
|
-
application/json:
|
|
2112
|
-
schema:
|
|
2113
|
-
$ref: "#/components/schemas/JourneyProgressUpdateDto"
|
|
2114
2380
|
responses:
|
|
2115
2381
|
"200":
|
|
2116
|
-
description:
|
|
2117
|
-
content:
|
|
2118
|
-
application/json:
|
|
2119
|
-
schema:
|
|
2120
|
-
$ref: "#/components/schemas/JourneyProgressDto"
|
|
2121
|
-
"400":
|
|
2122
|
-
description: Body fails validation (non-array, invalid entries, too many steps)
|
|
2382
|
+
description: Repositories with observability slice
|
|
2123
2383
|
content:
|
|
2124
2384
|
application/json:
|
|
2125
2385
|
schema:
|
|
2126
|
-
|
|
2386
|
+
type: array
|
|
2387
|
+
items:
|
|
2388
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2127
2389
|
"401":
|
|
2128
2390
|
$ref: "#/components/responses/Unauthorized"
|
|
2129
2391
|
"403":
|
|
@@ -2135,55 +2397,186 @@ paths:
|
|
|
2135
2397
|
schema:
|
|
2136
2398
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2137
2399
|
|
|
2138
|
-
/
|
|
2400
|
+
/workspaces/{workspaceId}/agentic-foundation/api-contract:
|
|
2139
2401
|
get:
|
|
2140
|
-
tags: [
|
|
2141
|
-
summary:
|
|
2142
|
-
|
|
2402
|
+
tags: [AgenticFoundation]
|
|
2403
|
+
summary: API contract pillar (api-contracts slice)
|
|
2404
|
+
description: Returns per-repo `api-contracts` dimension only (issue #285).
|
|
2405
|
+
operationId: getAgenticFoundationApiContract
|
|
2406
|
+
parameters:
|
|
2407
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2143
2408
|
responses:
|
|
2144
2409
|
"200":
|
|
2145
|
-
description:
|
|
2410
|
+
description: Repositories with api-contracts slice
|
|
2146
2411
|
content:
|
|
2147
2412
|
application/json:
|
|
2148
2413
|
schema:
|
|
2149
|
-
|
|
2414
|
+
type: array
|
|
2415
|
+
items:
|
|
2416
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2150
2417
|
"401":
|
|
2151
2418
|
$ref: "#/components/responses/Unauthorized"
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2419
|
+
"403":
|
|
2420
|
+
$ref: "#/components/responses/Forbidden"
|
|
2421
|
+
"404":
|
|
2422
|
+
description: Workspace does not exist
|
|
2423
|
+
content:
|
|
2424
|
+
application/json:
|
|
2425
|
+
schema:
|
|
2426
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2427
|
+
|
|
2428
|
+
/workspaces/{workspaceId}/agentic-foundation/platform-governance:
|
|
2429
|
+
get:
|
|
2430
|
+
tags: [AgenticFoundation]
|
|
2431
|
+
summary: Platform governance pillar (platform-governance slice)
|
|
2432
|
+
description: Returns per-repo `platform-governance` dimension only (issue #286).
|
|
2433
|
+
operationId: getAgenticFoundationPlatformGovernance
|
|
2434
|
+
parameters:
|
|
2435
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2162
2436
|
responses:
|
|
2163
2437
|
"200":
|
|
2164
|
-
description:
|
|
2438
|
+
description: Repositories with platform-governance slice
|
|
2165
2439
|
content:
|
|
2166
2440
|
application/json:
|
|
2167
2441
|
schema:
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2442
|
+
type: array
|
|
2443
|
+
items:
|
|
2444
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2445
|
+
"401":
|
|
2446
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2447
|
+
"403":
|
|
2448
|
+
$ref: "#/components/responses/Forbidden"
|
|
2449
|
+
"404":
|
|
2450
|
+
description: Workspace does not exist
|
|
2171
2451
|
content:
|
|
2172
2452
|
application/json:
|
|
2173
2453
|
schema:
|
|
2174
|
-
$ref: "#/components/schemas/
|
|
2454
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2455
|
+
|
|
2456
|
+
/workspaces/{workspaceId}/agentic-foundation/delivery-governance:
|
|
2457
|
+
get:
|
|
2458
|
+
tags: [AgenticFoundation]
|
|
2459
|
+
summary: Delivery governance pillar (delivery slice)
|
|
2460
|
+
description: Returns per-repo `delivery` dimension only (issue #287).
|
|
2461
|
+
operationId: getAgenticFoundationDeliveryGovernance
|
|
2462
|
+
parameters:
|
|
2463
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2464
|
+
responses:
|
|
2465
|
+
"200":
|
|
2466
|
+
description: Repositories with delivery slice
|
|
2467
|
+
content:
|
|
2468
|
+
application/json:
|
|
2469
|
+
schema:
|
|
2470
|
+
type: array
|
|
2471
|
+
items:
|
|
2472
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2175
2473
|
"401":
|
|
2176
2474
|
$ref: "#/components/responses/Unauthorized"
|
|
2475
|
+
"403":
|
|
2476
|
+
$ref: "#/components/responses/Forbidden"
|
|
2477
|
+
"404":
|
|
2478
|
+
description: Workspace does not exist
|
|
2479
|
+
content:
|
|
2480
|
+
application/json:
|
|
2481
|
+
schema:
|
|
2482
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2177
2483
|
|
|
2178
|
-
/workspaces/{workspaceId}/
|
|
2484
|
+
/workspaces/{workspaceId}/agentic-foundation/ai-resolution-hub:
|
|
2485
|
+
get:
|
|
2486
|
+
tags: [AgenticFoundation]
|
|
2487
|
+
summary: AI resolution hub (full readiness scorecards)
|
|
2488
|
+
description: >
|
|
2489
|
+
Returns the same payload as `GET .../readiness/repos` (all dimensions per repo) for
|
|
2490
|
+
cross-pillar hub views (issue #288).
|
|
2491
|
+
operationId: getAgenticFoundationAiResolutionHub
|
|
2492
|
+
parameters:
|
|
2493
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2494
|
+
responses:
|
|
2495
|
+
"200":
|
|
2496
|
+
description: Full repository readiness scorecards
|
|
2497
|
+
content:
|
|
2498
|
+
application/json:
|
|
2499
|
+
schema:
|
|
2500
|
+
type: array
|
|
2501
|
+
items:
|
|
2502
|
+
$ref: "#/components/schemas/RepoReadinessScoreDto"
|
|
2503
|
+
"401":
|
|
2504
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2505
|
+
"403":
|
|
2506
|
+
$ref: "#/components/responses/Forbidden"
|
|
2507
|
+
"404":
|
|
2508
|
+
description: Workspace does not exist
|
|
2509
|
+
content:
|
|
2510
|
+
application/json:
|
|
2511
|
+
schema:
|
|
2512
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2513
|
+
|
|
2514
|
+
/workspaces/{workspaceId}/readiness/dimensions:
|
|
2515
|
+
get:
|
|
2516
|
+
tags: [RepositoryReadiness]
|
|
2517
|
+
summary: Readiness dimensions catalog
|
|
2518
|
+
description: >
|
|
2519
|
+
Returns static rubric metadata (id, name, description, maxScore) aligned with the readiness
|
|
2520
|
+
scanner dimensions. Does not run scoring on the request path.
|
|
2521
|
+
operationId: listReadinessDimensions
|
|
2522
|
+
parameters:
|
|
2523
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2524
|
+
responses:
|
|
2525
|
+
"200":
|
|
2526
|
+
description: Dimensions
|
|
2527
|
+
content:
|
|
2528
|
+
application/json:
|
|
2529
|
+
schema:
|
|
2530
|
+
type: array
|
|
2531
|
+
items:
|
|
2532
|
+
$ref: "#/components/schemas/ReadinessDimensionDto"
|
|
2533
|
+
"401":
|
|
2534
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2535
|
+
"403":
|
|
2536
|
+
$ref: "#/components/responses/Forbidden"
|
|
2537
|
+
"404":
|
|
2538
|
+
description: Workspace does not exist
|
|
2539
|
+
content:
|
|
2540
|
+
application/json:
|
|
2541
|
+
schema:
|
|
2542
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2543
|
+
|
|
2544
|
+
/workspaces/{workspaceId}/readiness/fixes:
|
|
2545
|
+
get:
|
|
2546
|
+
tags: [RepositoryReadiness]
|
|
2547
|
+
summary: List fix requests
|
|
2548
|
+
description: >
|
|
2549
|
+
Returns persisted fix-queue rows for the workspace (newest first). Empty array when none exist.
|
|
2550
|
+
operationId: listReadinessFixes
|
|
2551
|
+
parameters:
|
|
2552
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2553
|
+
responses:
|
|
2554
|
+
"200":
|
|
2555
|
+
description: Fix queue
|
|
2556
|
+
content:
|
|
2557
|
+
application/json:
|
|
2558
|
+
schema:
|
|
2559
|
+
type: array
|
|
2560
|
+
items:
|
|
2561
|
+
$ref: "#/components/schemas/FixRequestDto"
|
|
2562
|
+
"401":
|
|
2563
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2564
|
+
"403":
|
|
2565
|
+
$ref: "#/components/responses/Forbidden"
|
|
2566
|
+
"404":
|
|
2567
|
+
description: Workspace does not exist
|
|
2568
|
+
content:
|
|
2569
|
+
application/json:
|
|
2570
|
+
schema:
|
|
2571
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2179
2572
|
post:
|
|
2180
|
-
tags: [
|
|
2181
|
-
summary:
|
|
2573
|
+
tags: [RepositoryReadiness]
|
|
2574
|
+
summary: Enqueue fix for an issue
|
|
2182
2575
|
description: >
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
operationId:
|
|
2576
|
+
Creates a fix request with `status: queued` when `issueId` belongs to `repoId` in this workspace.
|
|
2577
|
+
Requires workspace editor or admin. Re-posting the same `issueId` and `repoId` returns the
|
|
2578
|
+
existing row (idempotent).
|
|
2579
|
+
operationId: postReadinessFix
|
|
2187
2580
|
parameters:
|
|
2188
2581
|
- $ref: "#/components/parameters/WorkspaceId"
|
|
2189
2582
|
requestBody:
|
|
@@ -2191,16 +2584,21 @@ paths:
|
|
|
2191
2584
|
content:
|
|
2192
2585
|
application/json:
|
|
2193
2586
|
schema:
|
|
2194
|
-
$ref: "#/components/schemas/
|
|
2587
|
+
$ref: "#/components/schemas/CreateFixRequestBodyDto"
|
|
2588
|
+
examples:
|
|
2589
|
+
enqueue:
|
|
2590
|
+
value:
|
|
2591
|
+
issueId: "22222222-2222-2222-2222-222222222222"
|
|
2592
|
+
repoId: "11111111-1111-4111-8111-111111111111"
|
|
2195
2593
|
responses:
|
|
2196
2594
|
"200":
|
|
2197
|
-
description:
|
|
2595
|
+
description: Fix request created or existing row returned
|
|
2198
2596
|
content:
|
|
2199
2597
|
application/json:
|
|
2200
2598
|
schema:
|
|
2201
|
-
$ref: "#/components/schemas/
|
|
2599
|
+
$ref: "#/components/schemas/FixRequestDto"
|
|
2202
2600
|
"400":
|
|
2203
|
-
description: Invalid body or
|
|
2601
|
+
description: Invalid body or malformed `repoId` (not a UUID)
|
|
2204
2602
|
content:
|
|
2205
2603
|
application/json:
|
|
2206
2604
|
schema:
|
|
@@ -2210,57 +2608,417 @@ paths:
|
|
|
2210
2608
|
"403":
|
|
2211
2609
|
$ref: "#/components/responses/Forbidden"
|
|
2212
2610
|
"404":
|
|
2213
|
-
description:
|
|
2611
|
+
description: Workspace not found, or issue/repo pair not in workspace
|
|
2214
2612
|
content:
|
|
2215
2613
|
application/json:
|
|
2216
2614
|
schema:
|
|
2217
2615
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2218
|
-
|
|
2219
|
-
|
|
2616
|
+
|
|
2617
|
+
/workspaces/{workspaceId}/readiness/fixes/{fixId}/retry:
|
|
2618
|
+
post:
|
|
2619
|
+
tags: [RepositoryReadiness]
|
|
2620
|
+
summary: Retry a failed fix request
|
|
2621
|
+
description: >
|
|
2622
|
+
Re-queues a fix with `status: failed` when `errorCode` is one of
|
|
2623
|
+
`FixRetryableErrorCode` (`PROVIDER_TIMEOUT`, `RATE_LIMITED`, `TRANSIENT_NETWORK`,
|
|
2624
|
+
`RUNNER_INTERRUPTED`). Idempotent for the same failed row. Requires workspace editor or admin.
|
|
2625
|
+
operationId: postReadinessFixRetry
|
|
2626
|
+
parameters:
|
|
2627
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2628
|
+
- $ref: "#/components/parameters/FixId"
|
|
2629
|
+
responses:
|
|
2630
|
+
"200":
|
|
2631
|
+
description: Fix re-queued
|
|
2632
|
+
content:
|
|
2633
|
+
application/json:
|
|
2634
|
+
schema:
|
|
2635
|
+
$ref: "#/components/schemas/FixRequestDto"
|
|
2636
|
+
"401":
|
|
2637
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2638
|
+
"403":
|
|
2639
|
+
$ref: "#/components/responses/Forbidden"
|
|
2640
|
+
"404":
|
|
2641
|
+
description: Fix not found in workspace
|
|
2220
2642
|
content:
|
|
2221
2643
|
application/json:
|
|
2222
2644
|
schema:
|
|
2223
2645
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2224
|
-
"
|
|
2225
|
-
description:
|
|
2646
|
+
"409":
|
|
2647
|
+
description: Fix is not in a retryable state
|
|
2226
2648
|
content:
|
|
2227
2649
|
application/json:
|
|
2228
2650
|
schema:
|
|
2229
2651
|
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2230
2652
|
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2653
|
+
/workspaces/{workspaceId}/squad:
|
|
2654
|
+
get:
|
|
2655
|
+
tags: [SquadProjects]
|
|
2656
|
+
summary: Get squad configuration
|
|
2657
|
+
operationId: getSquad
|
|
2658
|
+
parameters:
|
|
2659
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2660
|
+
responses:
|
|
2661
|
+
"200":
|
|
2662
|
+
description: Squad
|
|
2663
|
+
content:
|
|
2664
|
+
application/json:
|
|
2665
|
+
schema:
|
|
2666
|
+
$ref: "#/components/schemas/SquadDto"
|
|
2667
|
+
"401":
|
|
2668
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2669
|
+
put:
|
|
2670
|
+
tags: [SquadProjects]
|
|
2671
|
+
summary: Upsert squad
|
|
2672
|
+
operationId: putSquad
|
|
2673
|
+
parameters:
|
|
2674
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2675
|
+
requestBody:
|
|
2676
|
+
required: true
|
|
2677
|
+
content:
|
|
2678
|
+
application/json:
|
|
2679
|
+
schema:
|
|
2680
|
+
$ref: "#/components/schemas/SquadDto"
|
|
2681
|
+
responses:
|
|
2682
|
+
"204":
|
|
2683
|
+
description: Saved
|
|
2684
|
+
"401":
|
|
2685
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2686
|
+
|
|
2687
|
+
/workspaces/{workspaceId}/projects:
|
|
2688
|
+
get:
|
|
2689
|
+
tags: [SquadProjects]
|
|
2690
|
+
summary: List projects
|
|
2691
|
+
operationId: listProjects
|
|
2692
|
+
parameters:
|
|
2693
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2694
|
+
responses:
|
|
2695
|
+
"200":
|
|
2696
|
+
description: Projects
|
|
2697
|
+
content:
|
|
2698
|
+
application/json:
|
|
2699
|
+
schema:
|
|
2700
|
+
type: array
|
|
2701
|
+
items:
|
|
2702
|
+
$ref: "#/components/schemas/ProjectDto"
|
|
2703
|
+
"401":
|
|
2704
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2705
|
+
post:
|
|
2706
|
+
tags: [SquadProjects]
|
|
2707
|
+
summary: Create project
|
|
2708
|
+
operationId: createProject
|
|
2709
|
+
parameters:
|
|
2710
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2711
|
+
requestBody:
|
|
2712
|
+
required: true
|
|
2713
|
+
content:
|
|
2714
|
+
application/json:
|
|
2715
|
+
schema:
|
|
2716
|
+
$ref: "#/components/schemas/ProjectDto"
|
|
2717
|
+
responses:
|
|
2718
|
+
"200":
|
|
2719
|
+
description: Created project
|
|
2720
|
+
content:
|
|
2721
|
+
application/json:
|
|
2722
|
+
schema:
|
|
2723
|
+
$ref: "#/components/schemas/ProjectDto"
|
|
2724
|
+
"401":
|
|
2725
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2726
|
+
|
|
2727
|
+
/workspaces/{workspaceId}/projects/{projectId}:
|
|
2728
|
+
patch:
|
|
2729
|
+
tags: [SquadProjects]
|
|
2730
|
+
summary: Update project
|
|
2731
|
+
operationId: patchProject
|
|
2732
|
+
parameters:
|
|
2733
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2734
|
+
- $ref: "#/components/parameters/ProjectId"
|
|
2735
|
+
requestBody:
|
|
2736
|
+
required: true
|
|
2737
|
+
content:
|
|
2738
|
+
application/json:
|
|
2739
|
+
schema:
|
|
2740
|
+
$ref: "#/components/schemas/ProjectPatchDto"
|
|
2741
|
+
responses:
|
|
2742
|
+
"200":
|
|
2743
|
+
description: Updated project
|
|
2744
|
+
content:
|
|
2745
|
+
application/json:
|
|
2746
|
+
schema:
|
|
2747
|
+
$ref: "#/components/schemas/ProjectDto"
|
|
2748
|
+
"401":
|
|
2749
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2750
|
+
|
|
2751
|
+
/workspaces/{workspaceId}/notifications:
|
|
2752
|
+
get:
|
|
2753
|
+
tags: [Notifications]
|
|
2754
|
+
summary: Paginated notifications
|
|
2755
|
+
operationId: listNotifications
|
|
2756
|
+
parameters:
|
|
2757
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2758
|
+
- name: limit
|
|
2759
|
+
in: query
|
|
2760
|
+
schema: { type: integer, minimum: 1 }
|
|
2761
|
+
- name: offset
|
|
2762
|
+
in: query
|
|
2763
|
+
schema: { type: integer, minimum: 0 }
|
|
2764
|
+
responses:
|
|
2765
|
+
"200":
|
|
2766
|
+
description: Page of notifications
|
|
2767
|
+
content:
|
|
2768
|
+
application/json:
|
|
2769
|
+
schema:
|
|
2770
|
+
$ref: "#/components/schemas/NotificationListDto"
|
|
2771
|
+
"401":
|
|
2772
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2773
|
+
|
|
2774
|
+
/workspaces/{workspaceId}/notifications/{id}/read:
|
|
2775
|
+
post:
|
|
2776
|
+
tags: [Notifications]
|
|
2777
|
+
summary: Mark notification read
|
|
2778
|
+
operationId: postNotificationRead
|
|
2779
|
+
parameters:
|
|
2780
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2781
|
+
- $ref: "#/components/parameters/NotificationId"
|
|
2782
|
+
responses:
|
|
2783
|
+
"204":
|
|
2784
|
+
description: Updated
|
|
2785
|
+
"401":
|
|
2786
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2787
|
+
|
|
2788
|
+
/workspaces/{workspaceId}/notifications/read-all:
|
|
2789
|
+
post:
|
|
2790
|
+
tags: [Notifications]
|
|
2791
|
+
summary: Mark all notifications read
|
|
2792
|
+
operationId: postNotificationsReadAll
|
|
2793
|
+
parameters:
|
|
2794
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2795
|
+
responses:
|
|
2796
|
+
"204":
|
|
2797
|
+
description: Updated
|
|
2798
|
+
"401":
|
|
2799
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2800
|
+
|
|
2801
|
+
/workspaces/{workspaceId}/ai-strategy/recommend:
|
|
2802
|
+
post:
|
|
2803
|
+
tags: [AIStrategy]
|
|
2804
|
+
summary: Generate AI strategy recommendations
|
|
2805
|
+
operationId: postAiStrategyRecommend
|
|
2806
|
+
parameters:
|
|
2807
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2808
|
+
requestBody:
|
|
2809
|
+
required: true
|
|
2810
|
+
content:
|
|
2811
|
+
application/json:
|
|
2812
|
+
schema:
|
|
2813
|
+
$ref: "#/components/schemas/AiStrategyRecommendBodyDto"
|
|
2814
|
+
responses:
|
|
2815
|
+
"200":
|
|
2816
|
+
description: Plan
|
|
2817
|
+
content:
|
|
2818
|
+
application/json:
|
|
2819
|
+
schema:
|
|
2820
|
+
$ref: "#/components/schemas/AiStrategyPlanDto"
|
|
2821
|
+
"401":
|
|
2822
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2823
|
+
|
|
2824
|
+
/workspaces/{workspaceId}/journey/progress:
|
|
2825
|
+
get:
|
|
2826
|
+
tags: [Journey]
|
|
2827
|
+
summary: Journey step completion
|
|
2828
|
+
operationId: getJourneyProgress
|
|
2829
|
+
parameters:
|
|
2830
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2831
|
+
responses:
|
|
2832
|
+
"200":
|
|
2833
|
+
description: Progress (empty completedSteps when no row exists yet; updatedAt is synthetic in that case)
|
|
2834
|
+
content:
|
|
2835
|
+
application/json:
|
|
2836
|
+
schema:
|
|
2837
|
+
$ref: "#/components/schemas/JourneyProgressDto"
|
|
2838
|
+
"400":
|
|
2839
|
+
description: Malformed workspaceId
|
|
2840
|
+
content:
|
|
2841
|
+
application/json:
|
|
2842
|
+
schema:
|
|
2843
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2844
|
+
"401":
|
|
2845
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2846
|
+
"403":
|
|
2847
|
+
$ref: "#/components/responses/Forbidden"
|
|
2848
|
+
"404":
|
|
2849
|
+
description: Workspace does not exist
|
|
2850
|
+
content:
|
|
2851
|
+
application/json:
|
|
2852
|
+
schema:
|
|
2853
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2854
|
+
put:
|
|
2855
|
+
tags: [Journey]
|
|
2856
|
+
summary: Replace completed steps
|
|
2857
|
+
operationId: putJourneyProgress
|
|
2858
|
+
description: >
|
|
2859
|
+
Idempotent replace-all of completed route strings. Returns the persisted
|
|
2860
|
+
JourneyProgressDto including updatedAt.
|
|
2861
|
+
parameters:
|
|
2862
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2863
|
+
requestBody:
|
|
2864
|
+
required: true
|
|
2865
|
+
content:
|
|
2866
|
+
application/json:
|
|
2867
|
+
schema:
|
|
2868
|
+
$ref: "#/components/schemas/JourneyProgressUpdateDto"
|
|
2869
|
+
responses:
|
|
2870
|
+
"200":
|
|
2871
|
+
description: Saved progress
|
|
2872
|
+
content:
|
|
2873
|
+
application/json:
|
|
2874
|
+
schema:
|
|
2875
|
+
$ref: "#/components/schemas/JourneyProgressDto"
|
|
2876
|
+
"400":
|
|
2877
|
+
description: Body fails validation (non-array, invalid entries, too many steps)
|
|
2878
|
+
content:
|
|
2879
|
+
application/json:
|
|
2880
|
+
schema:
|
|
2881
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2882
|
+
"401":
|
|
2883
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2884
|
+
"403":
|
|
2885
|
+
$ref: "#/components/responses/Forbidden"
|
|
2886
|
+
"404":
|
|
2887
|
+
description: Workspace does not exist
|
|
2888
|
+
content:
|
|
2889
|
+
application/json:
|
|
2890
|
+
schema:
|
|
2891
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2892
|
+
|
|
2893
|
+
/me/preferences:
|
|
2894
|
+
get:
|
|
2895
|
+
tags: [Preferences]
|
|
2896
|
+
summary: Get preferences for current user
|
|
2897
|
+
operationId: getMyPreferences
|
|
2898
|
+
responses:
|
|
2899
|
+
"200":
|
|
2900
|
+
description: Preferences
|
|
2901
|
+
content:
|
|
2902
|
+
application/json:
|
|
2903
|
+
schema:
|
|
2904
|
+
$ref: "#/components/schemas/PreferencesDto"
|
|
2905
|
+
"401":
|
|
2906
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2907
|
+
put:
|
|
2908
|
+
tags: [Preferences]
|
|
2909
|
+
summary: Upsert preferences
|
|
2910
|
+
operationId: putMyPreferences
|
|
2911
|
+
requestBody:
|
|
2912
|
+
required: true
|
|
2913
|
+
content:
|
|
2914
|
+
application/json:
|
|
2915
|
+
schema:
|
|
2916
|
+
$ref: "#/components/schemas/PreferencesDto"
|
|
2917
|
+
responses:
|
|
2918
|
+
"200":
|
|
2919
|
+
description: Saved preferences
|
|
2920
|
+
content:
|
|
2921
|
+
application/json:
|
|
2922
|
+
schema:
|
|
2923
|
+
$ref: "#/components/schemas/PreferencesDto"
|
|
2924
|
+
"400":
|
|
2925
|
+
description: Validation failed
|
|
2926
|
+
content:
|
|
2927
|
+
application/json:
|
|
2928
|
+
schema:
|
|
2929
|
+
$ref: "#/components/schemas/PreferencesValidationErrorDto"
|
|
2930
|
+
"401":
|
|
2931
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2932
|
+
|
|
2933
|
+
/workspaces/{workspaceId}/org-chart/import:
|
|
2934
|
+
post:
|
|
2935
|
+
tags: [OrgChartImport]
|
|
2936
|
+
summary: Import org chart from Supabase storage path
|
|
2937
|
+
description: >
|
|
2938
|
+
Parse-only. Downloads the CSV at `storagePath` from the `org-charts` bucket and returns
|
|
2939
|
+
`persons` and `errors`. Does not persist to `spa_org_chart` or `org_chart`. The SPA
|
|
2940
|
+
derives teams client-side and saves the org structure via `POST /workspaces/{workspaceId}/org-chart`.
|
|
2941
|
+
Required columns: employee_id, name, email, title, department, team, manager_id, location.
|
|
2942
|
+
Optional: github_username (GitHub login for productivity ingest). Saving the SPA snapshot
|
|
2943
|
+
also materializes a scoring `org_chart` tree for team/person metrics when import members are present.
|
|
2944
|
+
operationId: postOrgChartImport
|
|
2945
|
+
parameters:
|
|
2946
|
+
- $ref: "#/components/parameters/WorkspaceId"
|
|
2947
|
+
requestBody:
|
|
2948
|
+
required: true
|
|
2949
|
+
content:
|
|
2950
|
+
application/json:
|
|
2951
|
+
schema:
|
|
2952
|
+
$ref: "#/components/schemas/OrgChartImportBodyDto"
|
|
2953
|
+
responses:
|
|
2954
|
+
"200":
|
|
2955
|
+
description: Parsed persons from uploaded CSV (not persisted server-side)
|
|
2956
|
+
content:
|
|
2957
|
+
application/json:
|
|
2958
|
+
schema:
|
|
2959
|
+
$ref: "#/components/schemas/OrgChartImportResultDto"
|
|
2960
|
+
"400":
|
|
2961
|
+
description: Invalid body or storage path
|
|
2962
|
+
content:
|
|
2963
|
+
application/json:
|
|
2964
|
+
schema:
|
|
2965
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2966
|
+
"401":
|
|
2967
|
+
$ref: "#/components/responses/Unauthorized"
|
|
2968
|
+
"403":
|
|
2969
|
+
$ref: "#/components/responses/Forbidden"
|
|
2970
|
+
"404":
|
|
2971
|
+
description: Storage object not found
|
|
2972
|
+
content:
|
|
2973
|
+
application/json:
|
|
2974
|
+
schema:
|
|
2975
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2976
|
+
"502":
|
|
2977
|
+
description: Failed to download file from storage
|
|
2978
|
+
content:
|
|
2979
|
+
application/json:
|
|
2980
|
+
schema:
|
|
2981
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2982
|
+
"503":
|
|
2983
|
+
description: Storage import not configured or service unavailable
|
|
2984
|
+
content:
|
|
2985
|
+
application/json:
|
|
2986
|
+
schema:
|
|
2987
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
2988
|
+
|
|
2989
|
+
components:
|
|
2990
|
+
securitySchemes:
|
|
2991
|
+
bearerAuth:
|
|
2992
|
+
type: http
|
|
2993
|
+
scheme: bearer
|
|
2994
|
+
bearerFormat: JWT
|
|
2995
|
+
description: Supabase access token (`Authorization` header).
|
|
2996
|
+
|
|
2997
|
+
parameters:
|
|
2998
|
+
WorkspaceId:
|
|
2999
|
+
name: workspaceId
|
|
3000
|
+
in: path
|
|
3001
|
+
required: true
|
|
3002
|
+
schema:
|
|
3003
|
+
type: string
|
|
3004
|
+
RepoId:
|
|
3005
|
+
name: repoId
|
|
3006
|
+
in: path
|
|
3007
|
+
required: true
|
|
3008
|
+
schema:
|
|
3009
|
+
type: string
|
|
3010
|
+
format: uuid
|
|
3011
|
+
ProjectId:
|
|
3012
|
+
name: projectId
|
|
3013
|
+
in: path
|
|
3014
|
+
required: true
|
|
3015
|
+
schema:
|
|
3016
|
+
type: string
|
|
3017
|
+
NotificationId:
|
|
3018
|
+
name: id
|
|
3019
|
+
in: path
|
|
3020
|
+
required: true
|
|
3021
|
+
schema:
|
|
2264
3022
|
type: string
|
|
2265
3023
|
FixId:
|
|
2266
3024
|
name: fixId
|
|
@@ -2269,390 +3027,1305 @@ components:
|
|
|
2269
3027
|
schema:
|
|
2270
3028
|
type: string
|
|
2271
3029
|
format: uuid
|
|
3030
|
+
InsightsDepartmentFilter:
|
|
3031
|
+
name: department
|
|
3032
|
+
in: query
|
|
3033
|
+
description: >
|
|
3034
|
+
Department filter; send `All departments` to include every department. Scoped using
|
|
3035
|
+
imported `thinkai_org_structure` members when present, otherwise SPA org chart
|
|
3036
|
+
`department` nodes and their descendant teams. When neither source defines the
|
|
3037
|
+
requested department, insights return no scoped teams or contributors (not org-wide
|
|
3038
|
+
data).
|
|
3039
|
+
schema:
|
|
3040
|
+
type: string
|
|
3041
|
+
default: All departments
|
|
3042
|
+
|
|
3043
|
+
responses:
|
|
3044
|
+
Unauthorized:
|
|
3045
|
+
description: Missing or invalid bearer token
|
|
3046
|
+
content:
|
|
3047
|
+
application/json:
|
|
3048
|
+
schema:
|
|
3049
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
3050
|
+
Forbidden:
|
|
3051
|
+
description: Authenticated but not allowed
|
|
3052
|
+
content:
|
|
3053
|
+
application/json:
|
|
3054
|
+
schema:
|
|
3055
|
+
$ref: "#/components/schemas/ErrorMessageDto"
|
|
3056
|
+
|
|
3057
|
+
schemas:
|
|
3058
|
+
ErrorMessageDto:
|
|
3059
|
+
type: object
|
|
3060
|
+
required: [error]
|
|
3061
|
+
properties:
|
|
3062
|
+
error:
|
|
3063
|
+
type: string
|
|
3064
|
+
|
|
3065
|
+
TeamMemberDto:
|
|
3066
|
+
type: object
|
|
3067
|
+
required: [id, name, email, role]
|
|
3068
|
+
properties:
|
|
3069
|
+
id:
|
|
3070
|
+
type: string
|
|
3071
|
+
name:
|
|
3072
|
+
type: string
|
|
3073
|
+
email:
|
|
3074
|
+
type: string
|
|
3075
|
+
role:
|
|
3076
|
+
type: string
|
|
3077
|
+
enum: [admin, editor, viewer]
|
|
3078
|
+
|
|
3079
|
+
TeamMemberListDto:
|
|
3080
|
+
type: object
|
|
3081
|
+
required: [members]
|
|
3082
|
+
properties:
|
|
3083
|
+
members:
|
|
3084
|
+
type: array
|
|
3085
|
+
items:
|
|
3086
|
+
$ref: "#/components/schemas/TeamMemberDto"
|
|
3087
|
+
|
|
3088
|
+
InviteTeamMemberBodyDto:
|
|
3089
|
+
type: object
|
|
3090
|
+
required: [email, role]
|
|
3091
|
+
properties:
|
|
3092
|
+
email:
|
|
3093
|
+
type: string
|
|
3094
|
+
role:
|
|
3095
|
+
type: string
|
|
3096
|
+
enum: [admin, editor, viewer]
|
|
3097
|
+
|
|
3098
|
+
UpdateTeamMemberRoleBodyDto:
|
|
3099
|
+
type: object
|
|
3100
|
+
required: [role]
|
|
3101
|
+
properties:
|
|
3102
|
+
role:
|
|
3103
|
+
type: string
|
|
3104
|
+
enum: [admin, editor, viewer]
|
|
3105
|
+
|
|
3106
|
+
OrgChartNodeDto:
|
|
3107
|
+
type: object
|
|
3108
|
+
additionalProperties: false
|
|
3109
|
+
required: [id, name, type]
|
|
3110
|
+
properties:
|
|
3111
|
+
id:
|
|
3112
|
+
type: string
|
|
3113
|
+
name:
|
|
3114
|
+
type: string
|
|
3115
|
+
type:
|
|
3116
|
+
type: string
|
|
3117
|
+
enum: [org, department, team, person]
|
|
3118
|
+
external_ids:
|
|
3119
|
+
type: object
|
|
3120
|
+
additionalProperties: { type: string }
|
|
3121
|
+
children:
|
|
3122
|
+
type: array
|
|
3123
|
+
items:
|
|
3124
|
+
$ref: "#/components/schemas/OrgChartNodeDto"
|
|
3125
|
+
|
|
3126
|
+
OrgChartTreeNodeDto:
|
|
3127
|
+
type: object
|
|
3128
|
+
required: [id]
|
|
3129
|
+
properties:
|
|
3130
|
+
id:
|
|
3131
|
+
type: string
|
|
3132
|
+
name:
|
|
3133
|
+
type: string
|
|
3134
|
+
type:
|
|
3135
|
+
type: string
|
|
3136
|
+
person_id:
|
|
3137
|
+
type: string
|
|
3138
|
+
team:
|
|
3139
|
+
type: string
|
|
3140
|
+
role:
|
|
3141
|
+
type: string
|
|
3142
|
+
level:
|
|
3143
|
+
type: string
|
|
3144
|
+
external_ids:
|
|
3145
|
+
type: object
|
|
3146
|
+
additionalProperties: { type: string }
|
|
3147
|
+
children:
|
|
3148
|
+
type: array
|
|
3149
|
+
items:
|
|
3150
|
+
$ref: "#/components/schemas/OrgChartTreeNodeDto"
|
|
3151
|
+
|
|
3152
|
+
ScoringOrgChartDto:
|
|
3153
|
+
type: object
|
|
3154
|
+
additionalProperties: false
|
|
3155
|
+
required: [root]
|
|
3156
|
+
properties:
|
|
3157
|
+
root:
|
|
3158
|
+
$ref: "#/components/schemas/OrgChartTreeNodeDto"
|
|
3159
|
+
|
|
3160
|
+
OrgChartDto:
|
|
3161
|
+
type: object
|
|
3162
|
+
additionalProperties: false
|
|
3163
|
+
required: [root]
|
|
3164
|
+
properties:
|
|
3165
|
+
root:
|
|
3166
|
+
$ref: "#/components/schemas/OrgChartNodeDto"
|
|
3167
|
+
|
|
3168
|
+
OrgChartPersonDto:
|
|
3169
|
+
type: object
|
|
3170
|
+
additionalProperties: false
|
|
3171
|
+
required: [employeeId, name, email, title, department, team, managerId, location]
|
|
3172
|
+
properties:
|
|
3173
|
+
employeeId:
|
|
3174
|
+
type: string
|
|
3175
|
+
description: Stable HR identifier; referenced by manager_id for reporting lines.
|
|
3176
|
+
name:
|
|
3177
|
+
type: string
|
|
3178
|
+
email:
|
|
3179
|
+
type: string
|
|
3180
|
+
description: Work email; used as canonical person_id in productivity ingest when present.
|
|
3181
|
+
title:
|
|
3182
|
+
type: string
|
|
3183
|
+
description: Job title; used for contributor rows and leadership (enabler) hints.
|
|
3184
|
+
department:
|
|
3185
|
+
type: string
|
|
3186
|
+
description: Department filter on Productivity insights.
|
|
3187
|
+
team:
|
|
3188
|
+
type: string
|
|
3189
|
+
description: Engineering team name for Aggregated Teams and team drill-downs.
|
|
3190
|
+
managerId:
|
|
3191
|
+
type: string
|
|
3192
|
+
description: employee_id of the person's manager; leave empty for top-level leaders.
|
|
3193
|
+
location:
|
|
3194
|
+
type: string
|
|
3195
|
+
githubUsername:
|
|
3196
|
+
type: string
|
|
3197
|
+
description: GitHub login (no @) to map merged PRs and reviews to this person in productivity ingest.
|
|
3198
|
+
|
|
3199
|
+
OrgChartImportResultDto:
|
|
3200
|
+
type: object
|
|
3201
|
+
additionalProperties: false
|
|
3202
|
+
required: [persons, errors]
|
|
3203
|
+
properties:
|
|
3204
|
+
persons:
|
|
3205
|
+
type: array
|
|
3206
|
+
items:
|
|
3207
|
+
$ref: "#/components/schemas/OrgChartPersonDto"
|
|
3208
|
+
errors:
|
|
3209
|
+
type: array
|
|
3210
|
+
items:
|
|
3211
|
+
type: string
|
|
3212
|
+
|
|
3213
|
+
OrgChartSaveResultDto:
|
|
3214
|
+
type: object
|
|
3215
|
+
additionalProperties: false
|
|
3216
|
+
required: [ok, tenantId]
|
|
3217
|
+
properties:
|
|
3218
|
+
ok:
|
|
3219
|
+
type: boolean
|
|
3220
|
+
tenantId:
|
|
3221
|
+
type: string
|
|
3222
|
+
format: uuid
|
|
3223
|
+
|
|
3224
|
+
TenantSourceEntryDto:
|
|
3225
|
+
type: object
|
|
3226
|
+
required: [type]
|
|
3227
|
+
properties:
|
|
3228
|
+
type:
|
|
3229
|
+
type: string
|
|
3230
|
+
additionalProperties: true
|
|
3231
|
+
|
|
3232
|
+
CursorSourceDto:
|
|
3233
|
+
type: object
|
|
3234
|
+
description: >
|
|
3235
|
+
Cursor (AI Tools) source entry for `PUT /workspaces/{workspaceId}/sources`
|
|
3236
|
+
and `POST /workspaces/{workspaceId}/sources/test`. The `token` field
|
|
3237
|
+
carries a literal Cursor API key on writes; reads from
|
|
3238
|
+
`GET /workspaces/{workspaceId}/config` redact it to `***`.
|
|
3239
|
+
Runtime calls use the Cursor Admin API at `https://api.cursor.com` (HTTP Basic); do not rely on `baseUrl`.
|
|
3240
|
+
required: [type, token]
|
|
3241
|
+
additionalProperties: false
|
|
3242
|
+
properties:
|
|
3243
|
+
type:
|
|
3244
|
+
type: string
|
|
3245
|
+
enum: [cursor]
|
|
3246
|
+
token:
|
|
3247
|
+
type: string
|
|
3248
|
+
minLength: 1
|
|
3249
|
+
maxLength: 256
|
|
3250
|
+
description: Cursor API key (literal). Whitespace and `env:` prefix are rejected.
|
|
3251
|
+
baseUrl:
|
|
3252
|
+
type: string
|
|
3253
|
+
deprecated: true
|
|
3254
|
+
description: >
|
|
3255
|
+
Deprecated. Historically suggested an API base URL; the server ignores this field
|
|
3256
|
+
and always uses the Cursor Admin API host. Kept so older clients can submit payloads unchanged.
|
|
3257
|
+
default: "https://api.cursor.com"
|
|
3258
|
+
|
|
3259
|
+
WorkspaceConfigDto:
|
|
3260
|
+
type: object
|
|
3261
|
+
required: [sources]
|
|
3262
|
+
properties:
|
|
3263
|
+
sources:
|
|
3264
|
+
type: array
|
|
3265
|
+
items:
|
|
3266
|
+
$ref: "#/components/schemas/TenantSourceEntryDto"
|
|
3267
|
+
orgChart:
|
|
3268
|
+
nullable: true
|
|
3269
|
+
allOf:
|
|
3270
|
+
- $ref: "#/components/schemas/ScoringOrgChartDto"
|
|
3271
|
+
region:
|
|
3272
|
+
type: string
|
|
3273
|
+
nullable: true
|
|
3274
|
+
enum: [us, eu, me]
|
|
3275
|
+
|
|
3276
|
+
TestConnectionResponseDto:
|
|
3277
|
+
type: object
|
|
3278
|
+
required: [success]
|
|
3279
|
+
properties:
|
|
3280
|
+
success:
|
|
3281
|
+
type: boolean
|
|
3282
|
+
error:
|
|
3283
|
+
type: string
|
|
3284
|
+
|
|
3285
|
+
AiToolSeatDto:
|
|
3286
|
+
type: object
|
|
3287
|
+
required: [externalId, email, isRemoved]
|
|
3288
|
+
properties:
|
|
3289
|
+
externalId:
|
|
3290
|
+
type: string
|
|
3291
|
+
email:
|
|
3292
|
+
type: string
|
|
3293
|
+
displayName:
|
|
3294
|
+
type: string
|
|
3295
|
+
nullable: true
|
|
3296
|
+
role:
|
|
3297
|
+
type: string
|
|
3298
|
+
nullable: true
|
|
3299
|
+
isRemoved:
|
|
3300
|
+
type: boolean
|
|
3301
|
+
payload:
|
|
3302
|
+
type: object
|
|
3303
|
+
additionalProperties: true
|
|
2272
3304
|
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
3305
|
+
AiToolDailyUsageRowDto:
|
|
3306
|
+
type: object
|
|
3307
|
+
required: [day, externalId, isActive]
|
|
3308
|
+
properties:
|
|
3309
|
+
day:
|
|
3310
|
+
type: string
|
|
3311
|
+
format: date
|
|
3312
|
+
externalId:
|
|
3313
|
+
type: string
|
|
3314
|
+
email:
|
|
3315
|
+
type: string
|
|
3316
|
+
nullable: true
|
|
3317
|
+
isActive:
|
|
3318
|
+
type: boolean
|
|
3319
|
+
mostUsedModel:
|
|
3320
|
+
type: string
|
|
3321
|
+
nullable: true
|
|
3322
|
+
payload:
|
|
3323
|
+
type: object
|
|
3324
|
+
additionalProperties: true
|
|
3325
|
+
|
|
3326
|
+
AiToolSpendRowDto:
|
|
3327
|
+
type: object
|
|
3328
|
+
required: [billingCycleStartMs, externalId, spendCents]
|
|
3329
|
+
properties:
|
|
3330
|
+
billingCycleStartMs:
|
|
3331
|
+
type: integer
|
|
3332
|
+
format: int64
|
|
3333
|
+
externalId:
|
|
3334
|
+
type: string
|
|
3335
|
+
email:
|
|
3336
|
+
type: string
|
|
3337
|
+
nullable: true
|
|
3338
|
+
spendCents:
|
|
3339
|
+
type: integer
|
|
3340
|
+
format: int64
|
|
3341
|
+
payload:
|
|
3342
|
+
type: object
|
|
3343
|
+
additionalProperties: true
|
|
3344
|
+
|
|
3345
|
+
AiToolRefreshStatusDto:
|
|
3346
|
+
type: object
|
|
3347
|
+
required: [lastAttemptAt, counts]
|
|
3348
|
+
properties:
|
|
3349
|
+
lastAttemptAt:
|
|
3350
|
+
type: string
|
|
3351
|
+
format: date-time
|
|
3352
|
+
lastSuccessAt:
|
|
3353
|
+
type: string
|
|
3354
|
+
format: date-time
|
|
3355
|
+
nullable: true
|
|
3356
|
+
lastErrorKind:
|
|
3357
|
+
type: string
|
|
3358
|
+
nullable: true
|
|
3359
|
+
lastErrorMessage:
|
|
3360
|
+
type: string
|
|
3361
|
+
nullable: true
|
|
3362
|
+
durationMs:
|
|
3363
|
+
type: integer
|
|
3364
|
+
format: int64
|
|
3365
|
+
nullable: true
|
|
3366
|
+
counts:
|
|
3367
|
+
type: object
|
|
3368
|
+
additionalProperties: true
|
|
3369
|
+
|
|
3370
|
+
AiToolRefreshResponseDto:
|
|
3371
|
+
type: object
|
|
3372
|
+
required: [ok]
|
|
3373
|
+
properties:
|
|
3374
|
+
ok:
|
|
3375
|
+
type: boolean
|
|
3376
|
+
error:
|
|
3377
|
+
type: string
|
|
3378
|
+
nullable: true
|
|
3379
|
+
|
|
3380
|
+
DashboardProductivityMetricsDto:
|
|
3381
|
+
type: object
|
|
3382
|
+
description: Nested metric groups; see TypeScript `DashboardProductivityMetricsDto` in @thinkai/tai-api-contract.
|
|
3383
|
+
additionalProperties: true
|
|
3384
|
+
|
|
3385
|
+
DashboardProductivityDto:
|
|
3386
|
+
type: object
|
|
3387
|
+
required: [workspaceId, windowStart, windowEnd, scope, metrics]
|
|
3388
|
+
properties:
|
|
3389
|
+
workspaceId:
|
|
3390
|
+
type: string
|
|
3391
|
+
format: uuid
|
|
3392
|
+
generatedAt:
|
|
3393
|
+
type: string
|
|
3394
|
+
format: date-time
|
|
3395
|
+
description: Response generation time (RFC 3339).
|
|
3396
|
+
windowStart:
|
|
3397
|
+
type: string
|
|
3398
|
+
format: date-time
|
|
3399
|
+
windowEnd:
|
|
3400
|
+
type: string
|
|
3401
|
+
format: date-time
|
|
3402
|
+
scope:
|
|
3403
|
+
type: string
|
|
3404
|
+
enum: [org, team, person]
|
|
3405
|
+
metrics:
|
|
3406
|
+
$ref: "#/components/schemas/DashboardProductivityMetricsDto"
|
|
3407
|
+
meta:
|
|
3408
|
+
type: object
|
|
3409
|
+
additionalProperties: true
|
|
3410
|
+
|
|
3411
|
+
DashboardProductivityHistoryDto:
|
|
3412
|
+
type: object
|
|
3413
|
+
required: [workspaceId, bucket, buckets]
|
|
3414
|
+
properties:
|
|
3415
|
+
workspaceId:
|
|
3416
|
+
type: string
|
|
3417
|
+
format: uuid
|
|
3418
|
+
bucket:
|
|
3419
|
+
type: string
|
|
3420
|
+
enum: [day, week, month]
|
|
3421
|
+
buckets:
|
|
3422
|
+
type: array
|
|
3423
|
+
items:
|
|
3424
|
+
type: object
|
|
3425
|
+
required: [bucketStart, bucketEnd, metrics]
|
|
3426
|
+
properties:
|
|
3427
|
+
bucketStart:
|
|
3428
|
+
type: string
|
|
3429
|
+
format: date-time
|
|
3430
|
+
bucketEnd:
|
|
3431
|
+
type: string
|
|
3432
|
+
format: date-time
|
|
3433
|
+
metrics:
|
|
3434
|
+
$ref: "#/components/schemas/DashboardProductivityMetricsDto"
|
|
3435
|
+
|
|
3436
|
+
ProductivityInsightsAggregatedTeamsScopeDto:
|
|
3437
|
+
type: object
|
|
3438
|
+
additionalProperties: false
|
|
3439
|
+
required: [department, team]
|
|
3440
|
+
properties:
|
|
3441
|
+
department:
|
|
3442
|
+
type: string
|
|
3443
|
+
description: >
|
|
3444
|
+
Applied department filter from the Measure UI. Backend scopes via CSV import
|
|
3445
|
+
(`thinkai_org_structure`) or SPA `department` nodes; unknown departments yield
|
|
3446
|
+
empty scoped results rather than org-wide rollups.
|
|
3447
|
+
team:
|
|
3448
|
+
type: string
|
|
3449
|
+
description: Applied team name filter from the Measure UI.
|
|
3450
|
+
|
|
3451
|
+
ProductivityInsightsAggregatedTeamWeekDto:
|
|
3452
|
+
type: object
|
|
3453
|
+
additionalProperties: false
|
|
3454
|
+
required: [bucketStart, bucketEnd, mergedPrCount, failRatePercent]
|
|
3455
|
+
properties:
|
|
3456
|
+
bucketStart:
|
|
3457
|
+
type: string
|
|
3458
|
+
format: date-time
|
|
3459
|
+
bucketEnd:
|
|
3460
|
+
type: string
|
|
3461
|
+
format: date-time
|
|
3462
|
+
weekLabel:
|
|
3463
|
+
type: string
|
|
3464
|
+
description: Short label for the week column (MM/DD), aligned with Measure charts.
|
|
3465
|
+
mergedPrCount:
|
|
3466
|
+
type: number
|
|
3467
|
+
failRatePercent:
|
|
3468
|
+
type: number
|
|
3469
|
+
|
|
3470
|
+
ProductivityInsightsAggregatedTeamRowDto:
|
|
3471
|
+
type: object
|
|
3472
|
+
additionalProperties: false
|
|
3473
|
+
required: [teamId, teamName, headcount, weeks]
|
|
3474
|
+
properties:
|
|
3475
|
+
teamId:
|
|
3476
|
+
type: string
|
|
3477
|
+
teamName:
|
|
3478
|
+
type: string
|
|
3479
|
+
headcount:
|
|
3480
|
+
type: integer
|
|
3481
|
+
minimum: 0
|
|
3482
|
+
managerLabel:
|
|
3483
|
+
type: string
|
|
3484
|
+
weeks:
|
|
3485
|
+
type: array
|
|
3486
|
+
items:
|
|
3487
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamWeekDto"
|
|
3488
|
+
|
|
3489
|
+
ProductivityInsightsAggregatedTeamsDto:
|
|
3490
|
+
type: object
|
|
3491
|
+
additionalProperties: false
|
|
3492
|
+
required: [workspaceId, range, scope, generatedAt, teams]
|
|
3493
|
+
properties:
|
|
3494
|
+
workspaceId:
|
|
3495
|
+
type: string
|
|
3496
|
+
format: uuid
|
|
3497
|
+
range:
|
|
3498
|
+
type: string
|
|
3499
|
+
enum: [4w, 8w, q]
|
|
3500
|
+
scope:
|
|
3501
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3502
|
+
generatedAt:
|
|
3503
|
+
type: string
|
|
3504
|
+
format: date-time
|
|
3505
|
+
teams:
|
|
3506
|
+
type: array
|
|
3507
|
+
items:
|
|
3508
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamRowDto"
|
|
3509
|
+
|
|
3510
|
+
ProductivityInsightsMergedPrTrendWeekDto:
|
|
3511
|
+
type: object
|
|
3512
|
+
additionalProperties: false
|
|
3513
|
+
required: [bucketStart, bucketEnd, mergedPrCount]
|
|
3514
|
+
properties:
|
|
3515
|
+
bucketStart:
|
|
3516
|
+
type: string
|
|
3517
|
+
format: date-time
|
|
3518
|
+
bucketEnd:
|
|
3519
|
+
type: string
|
|
3520
|
+
format: date-time
|
|
3521
|
+
weekLabel:
|
|
3522
|
+
type: string
|
|
3523
|
+
description: Short label for the week column (MM/DD), aligned with Measure charts.
|
|
3524
|
+
mergedPrCount:
|
|
3525
|
+
type: number
|
|
3526
|
+
|
|
3527
|
+
ProductivityInsightsMergedPrContributorRowDto:
|
|
3528
|
+
type: object
|
|
3529
|
+
additionalProperties: false
|
|
3530
|
+
required: [personId, personName, weeks]
|
|
3531
|
+
properties:
|
|
3532
|
+
personId:
|
|
3533
|
+
type: string
|
|
3534
|
+
description: Canonical person identifier (matches org chart person_id / employeeId).
|
|
3535
|
+
personName:
|
|
3536
|
+
type: string
|
|
3537
|
+
teamName:
|
|
3538
|
+
type: string
|
|
3539
|
+
weeks:
|
|
3540
|
+
type: array
|
|
3541
|
+
items:
|
|
3542
|
+
$ref: "#/components/schemas/ProductivityInsightsMergedPrTrendWeekDto"
|
|
3543
|
+
|
|
3544
|
+
ProductivityInsightsMergedPrTrendsDto:
|
|
3545
|
+
type: object
|
|
3546
|
+
additionalProperties: false
|
|
3547
|
+
required: [workspaceId, range, scope, generatedAt, weeks, contributors]
|
|
3548
|
+
properties:
|
|
3549
|
+
workspaceId:
|
|
3550
|
+
type: string
|
|
3551
|
+
format: uuid
|
|
3552
|
+
range:
|
|
3553
|
+
type: string
|
|
3554
|
+
enum: [4w, 8w, q]
|
|
3555
|
+
scope:
|
|
3556
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3557
|
+
generatedAt:
|
|
3558
|
+
type: string
|
|
3559
|
+
format: date-time
|
|
3560
|
+
weeks:
|
|
3561
|
+
type: array
|
|
3562
|
+
description: Portfolio aggregate merged PR counts (sum of filtered contributors per week).
|
|
3563
|
+
items:
|
|
3564
|
+
$ref: "#/components/schemas/ProductivityInsightsMergedPrTrendWeekDto"
|
|
3565
|
+
contributors:
|
|
3566
|
+
type: array
|
|
3567
|
+
items:
|
|
3568
|
+
$ref: "#/components/schemas/ProductivityInsightsMergedPrContributorRowDto"
|
|
3569
|
+
|
|
3570
|
+
ProductivityInsightsTeamLeaderItemDto:
|
|
3571
|
+
type: object
|
|
3572
|
+
additionalProperties: false
|
|
3573
|
+
required:
|
|
3574
|
+
[rank, teamId, teamName, periodAvgMergedPrs, deltaVsPeriodAvgPercent]
|
|
3575
|
+
properties:
|
|
3576
|
+
rank:
|
|
3577
|
+
type: integer
|
|
3578
|
+
minimum: 1
|
|
3579
|
+
description: 1-based rank within the top-teams list (1 = highest performer).
|
|
3580
|
+
teamId:
|
|
3581
|
+
type: string
|
|
3582
|
+
teamName:
|
|
3583
|
+
type: string
|
|
3584
|
+
subtitle:
|
|
3585
|
+
type: string
|
|
3586
|
+
description: Optional context line (e.g. headcount or manager).
|
|
3587
|
+
periodAvgMergedPrs:
|
|
3588
|
+
type: number
|
|
3589
|
+
description: Average weekly merged PR count over the selected range.
|
|
3590
|
+
deltaVsPeriodAvgPercent:
|
|
3591
|
+
type: number
|
|
3592
|
+
description: Percent change of the latest week vs the period average.
|
|
3593
|
+
avgFailRatePercent:
|
|
3594
|
+
type: number
|
|
3595
|
+
description: Average change failure rate over the range when available.
|
|
3596
|
+
|
|
3597
|
+
ProductivityInsightsTeamSummaryDto:
|
|
3598
|
+
type: object
|
|
3599
|
+
additionalProperties: false
|
|
3600
|
+
required: [totalMergedPrs, avgMergedPrsPerWeek, avgFailRatePercent, headcount]
|
|
3601
|
+
properties:
|
|
3602
|
+
totalMergedPrs:
|
|
3603
|
+
type: number
|
|
3604
|
+
avgMergedPrsPerWeek:
|
|
3605
|
+
type: number
|
|
3606
|
+
avgFailRatePercent:
|
|
3607
|
+
type: number
|
|
3608
|
+
headcount:
|
|
3609
|
+
type: integer
|
|
3610
|
+
minimum: 0
|
|
2286
3611
|
|
|
2287
|
-
|
|
2288
|
-
ErrorMessageDto:
|
|
3612
|
+
ProductivityInsightsTeamDetailDto:
|
|
2289
3613
|
type: object
|
|
2290
|
-
|
|
3614
|
+
additionalProperties: false
|
|
3615
|
+
required: [teamId, teamName, headcount, weeks, summary]
|
|
2291
3616
|
properties:
|
|
2292
|
-
|
|
3617
|
+
teamId:
|
|
3618
|
+
type: string
|
|
3619
|
+
teamName:
|
|
3620
|
+
type: string
|
|
3621
|
+
headcount:
|
|
3622
|
+
type: integer
|
|
3623
|
+
minimum: 0
|
|
3624
|
+
managerLabel:
|
|
2293
3625
|
type: string
|
|
3626
|
+
weeks:
|
|
3627
|
+
type: array
|
|
3628
|
+
items:
|
|
3629
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamWeekDto"
|
|
3630
|
+
summary:
|
|
3631
|
+
$ref: "#/components/schemas/ProductivityInsightsTeamSummaryDto"
|
|
2294
3632
|
|
|
2295
|
-
|
|
3633
|
+
ProductivityInsightsTeamsResponseDto:
|
|
2296
3634
|
type: object
|
|
2297
|
-
|
|
3635
|
+
additionalProperties: false
|
|
3636
|
+
required: [workspaceId, range, scope, generatedAt]
|
|
3637
|
+
properties:
|
|
3638
|
+
workspaceId:
|
|
3639
|
+
type: string
|
|
3640
|
+
format: uuid
|
|
3641
|
+
range:
|
|
3642
|
+
type: string
|
|
3643
|
+
enum: [4w, 8w, q]
|
|
3644
|
+
scope:
|
|
3645
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3646
|
+
generatedAt:
|
|
3647
|
+
type: string
|
|
3648
|
+
format: date-time
|
|
3649
|
+
items:
|
|
3650
|
+
type: array
|
|
3651
|
+
description: Present when `teamId` query is omitted — top-ranked teams.
|
|
3652
|
+
items:
|
|
3653
|
+
$ref: "#/components/schemas/ProductivityInsightsTeamLeaderItemDto"
|
|
3654
|
+
team:
|
|
3655
|
+
description: Present when `teamId` query is set — single-team drilldown.
|
|
3656
|
+
allOf:
|
|
3657
|
+
- $ref: "#/components/schemas/ProductivityInsightsTeamDetailDto"
|
|
3658
|
+
|
|
3659
|
+
ProductivityInsightsContributorProfileDto:
|
|
3660
|
+
type: object
|
|
3661
|
+
additionalProperties: false
|
|
3662
|
+
required: [id, name]
|
|
2298
3663
|
properties:
|
|
2299
3664
|
id:
|
|
2300
3665
|
type: string
|
|
3666
|
+
description: Org-chart person id (typically email).
|
|
2301
3667
|
name:
|
|
2302
3668
|
type: string
|
|
2303
|
-
|
|
3669
|
+
title:
|
|
2304
3670
|
type: string
|
|
2305
|
-
|
|
3671
|
+
team:
|
|
3672
|
+
type: string
|
|
3673
|
+
department:
|
|
2306
3674
|
type: string
|
|
2307
|
-
enum: [admin, editor, viewer]
|
|
2308
3675
|
|
|
2309
|
-
|
|
3676
|
+
ProductivityInsightsContributorActivityDayDto:
|
|
2310
3677
|
type: object
|
|
2311
|
-
|
|
3678
|
+
additionalProperties: false
|
|
3679
|
+
required:
|
|
3680
|
+
[date, dayIndex, mergedPrCount, mergedPrs, absent, failureSignal, failures]
|
|
2312
3681
|
properties:
|
|
2313
|
-
|
|
3682
|
+
date:
|
|
3683
|
+
type: string
|
|
3684
|
+
format: date
|
|
3685
|
+
dayIndex:
|
|
3686
|
+
type: integer
|
|
3687
|
+
minimum: 0
|
|
3688
|
+
maximum: 6
|
|
3689
|
+
mergedPrCount:
|
|
3690
|
+
type: integer
|
|
3691
|
+
minimum: 0
|
|
3692
|
+
mergedPrs:
|
|
2314
3693
|
type: array
|
|
2315
3694
|
items:
|
|
2316
|
-
|
|
3695
|
+
type: string
|
|
3696
|
+
absent:
|
|
3697
|
+
type: boolean
|
|
3698
|
+
absenceType:
|
|
3699
|
+
type: string
|
|
3700
|
+
failureSignal:
|
|
3701
|
+
type: boolean
|
|
3702
|
+
failures:
|
|
3703
|
+
type: array
|
|
3704
|
+
items:
|
|
3705
|
+
type: string
|
|
2317
3706
|
|
|
2318
|
-
|
|
3707
|
+
ProductivityInsightsContributorActivityWeekDto:
|
|
2319
3708
|
type: object
|
|
2320
|
-
|
|
3709
|
+
additionalProperties: false
|
|
3710
|
+
required: [label, bucketStart, bucketEnd, days]
|
|
2321
3711
|
properties:
|
|
2322
|
-
|
|
3712
|
+
label:
|
|
2323
3713
|
type: string
|
|
2324
|
-
|
|
3714
|
+
bucketStart:
|
|
2325
3715
|
type: string
|
|
2326
|
-
|
|
3716
|
+
format: date-time
|
|
3717
|
+
bucketEnd:
|
|
3718
|
+
type: string
|
|
3719
|
+
format: date-time
|
|
3720
|
+
days:
|
|
3721
|
+
type: array
|
|
3722
|
+
items:
|
|
3723
|
+
$ref: "#/components/schemas/ProductivityInsightsContributorActivityDayDto"
|
|
2327
3724
|
|
|
2328
|
-
|
|
3725
|
+
ProductivityInsightsContributorActivitySummaryDto:
|
|
2329
3726
|
type: object
|
|
2330
|
-
|
|
3727
|
+
additionalProperties: false
|
|
3728
|
+
required:
|
|
3729
|
+
- totalMergedPrs
|
|
3730
|
+
- avgMergedPrsPerWeek
|
|
3731
|
+
- totalAbsenceDays
|
|
3732
|
+
- avgFailRate
|
|
3733
|
+
- mergedPrDelta
|
|
3734
|
+
- avgMergedPrsPerWeekDelta
|
|
3735
|
+
- totalAbsenceDaysDelta
|
|
3736
|
+
- avgFailRateDelta
|
|
2331
3737
|
properties:
|
|
2332
|
-
|
|
2333
|
-
type:
|
|
2334
|
-
|
|
3738
|
+
totalMergedPrs:
|
|
3739
|
+
type: integer
|
|
3740
|
+
minimum: 0
|
|
3741
|
+
avgMergedPrsPerWeek:
|
|
3742
|
+
type: number
|
|
3743
|
+
totalAbsenceDays:
|
|
3744
|
+
type: integer
|
|
3745
|
+
minimum: 0
|
|
3746
|
+
avgFailRate:
|
|
3747
|
+
type: number
|
|
3748
|
+
mergedPrDelta:
|
|
3749
|
+
type: number
|
|
3750
|
+
avgMergedPrsPerWeekDelta:
|
|
3751
|
+
type: number
|
|
3752
|
+
totalAbsenceDaysDelta:
|
|
3753
|
+
type: number
|
|
3754
|
+
avgFailRateDelta:
|
|
3755
|
+
type: number
|
|
2335
3756
|
|
|
2336
|
-
|
|
3757
|
+
ProductivityInsightsContributorDetailDto:
|
|
2337
3758
|
type: object
|
|
2338
3759
|
additionalProperties: false
|
|
2339
|
-
required:
|
|
3760
|
+
required:
|
|
3761
|
+
- workspaceId
|
|
3762
|
+
- contributorId
|
|
3763
|
+
- range
|
|
3764
|
+
- scope
|
|
3765
|
+
- generatedAt
|
|
3766
|
+
- contributor
|
|
3767
|
+
- weeks
|
|
3768
|
+
- summary
|
|
2340
3769
|
properties:
|
|
2341
|
-
|
|
3770
|
+
workspaceId:
|
|
2342
3771
|
type: string
|
|
2343
|
-
|
|
3772
|
+
format: uuid
|
|
3773
|
+
contributorId:
|
|
2344
3774
|
type: string
|
|
2345
|
-
|
|
3775
|
+
range:
|
|
2346
3776
|
type: string
|
|
2347
|
-
enum: [
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
3777
|
+
enum: [4w, 8w, q]
|
|
3778
|
+
scope:
|
|
3779
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3780
|
+
generatedAt:
|
|
3781
|
+
type: string
|
|
3782
|
+
format: date-time
|
|
3783
|
+
contributor:
|
|
3784
|
+
$ref: "#/components/schemas/ProductivityInsightsContributorProfileDto"
|
|
3785
|
+
weeks:
|
|
2352
3786
|
type: array
|
|
2353
3787
|
items:
|
|
2354
|
-
$ref: "#/components/schemas/
|
|
3788
|
+
$ref: "#/components/schemas/ProductivityInsightsContributorActivityWeekDto"
|
|
3789
|
+
summary:
|
|
3790
|
+
$ref: "#/components/schemas/ProductivityInsightsContributorActivitySummaryDto"
|
|
2355
3791
|
|
|
2356
|
-
|
|
3792
|
+
ProductivityInsightsNeedsAttentionItemDto:
|
|
2357
3793
|
type: object
|
|
2358
|
-
|
|
3794
|
+
additionalProperties: false
|
|
3795
|
+
required:
|
|
3796
|
+
[rank, entityId, entityType, name, periodAvgMergedPrs, deltaVsPeriodAvgPercent]
|
|
2359
3797
|
properties:
|
|
2360
|
-
|
|
3798
|
+
rank:
|
|
3799
|
+
type: integer
|
|
3800
|
+
minimum: 1
|
|
3801
|
+
description: 1-based rank within the laggards list (1 = lowest performer).
|
|
3802
|
+
entityId:
|
|
3803
|
+
type: string
|
|
3804
|
+
description: Org chart team id or canonical person id.
|
|
3805
|
+
entityType:
|
|
2361
3806
|
type: string
|
|
3807
|
+
enum: [team, contributor]
|
|
2362
3808
|
name:
|
|
2363
3809
|
type: string
|
|
2364
|
-
|
|
3810
|
+
subtitle:
|
|
2365
3811
|
type: string
|
|
2366
|
-
|
|
3812
|
+
description: Optional context line (e.g. headcount or job title).
|
|
3813
|
+
periodAvgMergedPrs:
|
|
3814
|
+
type: number
|
|
3815
|
+
description: Mean weekly merged PR count across the selected range.
|
|
3816
|
+
deltaVsPeriodAvgPercent:
|
|
3817
|
+
type: number
|
|
3818
|
+
description: Percent change of the latest week vs the period mean.
|
|
3819
|
+
avgFailRatePercent:
|
|
3820
|
+
type: number
|
|
3821
|
+
description: Mean weekly change-failure rate when available.
|
|
3822
|
+
|
|
3823
|
+
ProductivityInsightsNeedsAttentionDto:
|
|
3824
|
+
type: object
|
|
3825
|
+
additionalProperties: false
|
|
3826
|
+
required: [workspaceId, range, scope, entityType, generatedAt, items]
|
|
3827
|
+
properties:
|
|
3828
|
+
workspaceId:
|
|
2367
3829
|
type: string
|
|
2368
|
-
|
|
3830
|
+
format: uuid
|
|
3831
|
+
range:
|
|
2369
3832
|
type: string
|
|
2370
|
-
|
|
3833
|
+
enum: [4w, 8w, q]
|
|
3834
|
+
scope:
|
|
3835
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3836
|
+
entityType:
|
|
2371
3837
|
type: string
|
|
2372
|
-
|
|
3838
|
+
enum: [teams, contributors]
|
|
3839
|
+
generatedAt:
|
|
2373
3840
|
type: string
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
additionalProperties: { type: string }
|
|
2377
|
-
children:
|
|
3841
|
+
format: date-time
|
|
3842
|
+
items:
|
|
2378
3843
|
type: array
|
|
2379
3844
|
items:
|
|
2380
|
-
$ref: "#/components/schemas/
|
|
3845
|
+
$ref: "#/components/schemas/ProductivityInsightsNeedsAttentionItemDto"
|
|
2381
3846
|
|
|
2382
|
-
|
|
3847
|
+
AiUsageSpendAggregatedTeamWeekDto:
|
|
2383
3848
|
type: object
|
|
2384
3849
|
additionalProperties: false
|
|
2385
|
-
required: [
|
|
3850
|
+
required: [bucketStart, bucketEnd, tokenCount, spendCents, activeUsers]
|
|
2386
3851
|
properties:
|
|
2387
|
-
|
|
2388
|
-
|
|
3852
|
+
bucketStart:
|
|
3853
|
+
type: string
|
|
3854
|
+
format: date-time
|
|
3855
|
+
bucketEnd:
|
|
3856
|
+
type: string
|
|
3857
|
+
format: date-time
|
|
3858
|
+
weekLabel:
|
|
3859
|
+
type: string
|
|
3860
|
+
description: Short label for table headers (e.g. MM/DD).
|
|
3861
|
+
tokenCount:
|
|
3862
|
+
type: integer
|
|
3863
|
+
minimum: 0
|
|
3864
|
+
description: Total tokens consumed in the bucket (from AI-tool daily usage payloads when available).
|
|
3865
|
+
spendCents:
|
|
3866
|
+
type: integer
|
|
3867
|
+
minimum: 0
|
|
3868
|
+
description: Estimated spend in USD cents attributed to the bucket.
|
|
3869
|
+
activeUsers:
|
|
3870
|
+
type: integer
|
|
3871
|
+
minimum: 0
|
|
3872
|
+
description: Distinct engineers with active AI-tool usage in the bucket.
|
|
2389
3873
|
|
|
2390
|
-
|
|
3874
|
+
AiUsageSpendAggregatedTeamRowDto:
|
|
2391
3875
|
type: object
|
|
2392
3876
|
additionalProperties: false
|
|
2393
|
-
required: [
|
|
3877
|
+
required: [teamId, teamName, headcount, weeks]
|
|
2394
3878
|
properties:
|
|
2395
|
-
|
|
2396
|
-
|
|
3879
|
+
teamId:
|
|
3880
|
+
type: string
|
|
3881
|
+
teamName:
|
|
3882
|
+
type: string
|
|
3883
|
+
headcount:
|
|
3884
|
+
type: integer
|
|
3885
|
+
minimum: 0
|
|
3886
|
+
managerLabel:
|
|
3887
|
+
type: string
|
|
3888
|
+
weeks:
|
|
3889
|
+
type: array
|
|
3890
|
+
items:
|
|
3891
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamWeekDto"
|
|
2397
3892
|
|
|
2398
|
-
|
|
3893
|
+
AiUsageSpendAggregatedTeamsSummaryDto:
|
|
2399
3894
|
type: object
|
|
2400
3895
|
additionalProperties: false
|
|
2401
|
-
required:
|
|
3896
|
+
required:
|
|
3897
|
+
[totalTokenCount, totalSpendCents, activeUsers, activeTools, totalEngineers]
|
|
2402
3898
|
properties:
|
|
2403
|
-
|
|
3899
|
+
totalTokenCount:
|
|
3900
|
+
type: integer
|
|
3901
|
+
minimum: 0
|
|
3902
|
+
totalSpendCents:
|
|
3903
|
+
type: integer
|
|
3904
|
+
minimum: 0
|
|
3905
|
+
activeUsers:
|
|
3906
|
+
type: integer
|
|
3907
|
+
minimum: 0
|
|
3908
|
+
description: Distinct engineers with any active usage in the selected range.
|
|
3909
|
+
activeTools:
|
|
3910
|
+
type: integer
|
|
3911
|
+
minimum: 0
|
|
3912
|
+
description: Count of connected AI-tool providers with usage or spend in range.
|
|
3913
|
+
totalEngineers:
|
|
3914
|
+
type: integer
|
|
3915
|
+
minimum: 0
|
|
3916
|
+
description: Sum of org-chart headcount across returned teams.
|
|
3917
|
+
|
|
3918
|
+
AiUsageSpendAggregatedTeamsDto:
|
|
3919
|
+
type: object
|
|
3920
|
+
additionalProperties: false
|
|
3921
|
+
required: [workspaceId, range, scope, generatedAt, teams, summary]
|
|
3922
|
+
properties:
|
|
3923
|
+
workspaceId:
|
|
2404
3924
|
type: string
|
|
2405
|
-
|
|
3925
|
+
format: uuid
|
|
3926
|
+
range:
|
|
2406
3927
|
type: string
|
|
2407
|
-
|
|
3928
|
+
enum: [4w, 8w, q]
|
|
3929
|
+
scope:
|
|
3930
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3931
|
+
generatedAt:
|
|
2408
3932
|
type: string
|
|
2409
|
-
|
|
3933
|
+
format: date-time
|
|
3934
|
+
teams:
|
|
3935
|
+
type: array
|
|
3936
|
+
items:
|
|
3937
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamRowDto"
|
|
3938
|
+
summary:
|
|
3939
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamsSummaryDto"
|
|
3940
|
+
|
|
3941
|
+
AiUsageSpendAggregatedContributorRowDto:
|
|
3942
|
+
type: object
|
|
3943
|
+
additionalProperties: false
|
|
3944
|
+
required: [contributorId, contributorName, weeks]
|
|
3945
|
+
properties:
|
|
3946
|
+
contributorId:
|
|
2410
3947
|
type: string
|
|
2411
|
-
|
|
3948
|
+
description: Org-chart person id (typically email).
|
|
3949
|
+
contributorName:
|
|
2412
3950
|
type: string
|
|
2413
|
-
|
|
3951
|
+
title:
|
|
2414
3952
|
type: string
|
|
2415
|
-
|
|
3953
|
+
team:
|
|
2416
3954
|
type: string
|
|
2417
|
-
|
|
3955
|
+
department:
|
|
2418
3956
|
type: string
|
|
3957
|
+
weeks:
|
|
3958
|
+
type: array
|
|
3959
|
+
items:
|
|
3960
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamWeekDto"
|
|
2419
3961
|
|
|
2420
|
-
|
|
3962
|
+
AiUsageSpendAggregatedContributorsDto:
|
|
2421
3963
|
type: object
|
|
2422
3964
|
additionalProperties: false
|
|
2423
|
-
required: [
|
|
3965
|
+
required: [workspaceId, range, scope, generatedAt, contributors, summary]
|
|
2424
3966
|
properties:
|
|
2425
|
-
|
|
2426
|
-
type:
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
3967
|
+
workspaceId:
|
|
3968
|
+
type: string
|
|
3969
|
+
format: uuid
|
|
3970
|
+
range:
|
|
3971
|
+
type: string
|
|
3972
|
+
enum: [4w, 8w, q]
|
|
3973
|
+
scope:
|
|
3974
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
3975
|
+
generatedAt:
|
|
3976
|
+
type: string
|
|
3977
|
+
format: date-time
|
|
3978
|
+
contributors:
|
|
2430
3979
|
type: array
|
|
2431
3980
|
items:
|
|
2432
|
-
|
|
3981
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedContributorRowDto"
|
|
3982
|
+
summary:
|
|
3983
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamsSummaryDto"
|
|
2433
3984
|
|
|
2434
|
-
|
|
3985
|
+
AiUsageSpendContributorToolHeatmapDto:
|
|
2435
3986
|
type: object
|
|
2436
3987
|
additionalProperties: false
|
|
2437
|
-
required:
|
|
3988
|
+
required:
|
|
3989
|
+
- workspaceId
|
|
3990
|
+
- range
|
|
3991
|
+
- scope
|
|
3992
|
+
- generatedAt
|
|
3993
|
+
- contributors
|
|
2438
3994
|
properties:
|
|
2439
|
-
|
|
2440
|
-
type: boolean
|
|
2441
|
-
tenantId:
|
|
3995
|
+
workspaceId:
|
|
2442
3996
|
type: string
|
|
2443
3997
|
format: uuid
|
|
2444
|
-
|
|
2445
|
-
TenantSourceEntryDto:
|
|
2446
|
-
type: object
|
|
2447
|
-
required: [type]
|
|
2448
|
-
properties:
|
|
2449
|
-
type:
|
|
3998
|
+
range:
|
|
2450
3999
|
type: string
|
|
2451
|
-
|
|
4000
|
+
enum: [4w, 8w, q]
|
|
4001
|
+
scope:
|
|
4002
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
4003
|
+
generatedAt:
|
|
4004
|
+
type: string
|
|
4005
|
+
format: date-time
|
|
4006
|
+
contributors:
|
|
4007
|
+
type: array
|
|
4008
|
+
items:
|
|
4009
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedContributorRowDto"
|
|
2452
4010
|
|
|
2453
|
-
|
|
4011
|
+
AiUsageSpendKeyInsightItemDto:
|
|
2454
4012
|
type: object
|
|
2455
|
-
description: >
|
|
2456
|
-
Cursor (AI Tools) source entry for `PUT /workspaces/{workspaceId}/sources`
|
|
2457
|
-
and `POST /workspaces/{workspaceId}/sources/test`. The `token` field
|
|
2458
|
-
carries a literal Cursor API key on writes; reads from
|
|
2459
|
-
`GET /workspaces/{workspaceId}/config` redact it to `***`.
|
|
2460
|
-
Runtime calls use the Cursor Admin API at `https://api.cursor.com` (HTTP Basic); do not rely on `baseUrl`.
|
|
2461
|
-
required: [type, token]
|
|
2462
4013
|
additionalProperties: false
|
|
4014
|
+
required: [id, tone, text]
|
|
2463
4015
|
properties:
|
|
2464
|
-
|
|
4016
|
+
id:
|
|
2465
4017
|
type: string
|
|
2466
|
-
|
|
2467
|
-
|
|
4018
|
+
description: Stable insight key (e.g. spend-leader, spend-vs-output).
|
|
4019
|
+
tone:
|
|
2468
4020
|
type: string
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
description: Cursor API key (literal). Whitespace and `env:` prefix are rejected.
|
|
2472
|
-
baseUrl:
|
|
4021
|
+
enum: [positive, warning, neutral]
|
|
4022
|
+
text:
|
|
2473
4023
|
type: string
|
|
2474
|
-
|
|
2475
|
-
description: >
|
|
2476
|
-
Deprecated. Historically suggested an API base URL; the server ignores this field
|
|
2477
|
-
and always uses the Cursor Admin API host. Kept so older clients can submit payloads unchanged.
|
|
2478
|
-
default: "https://api.cursor.com"
|
|
4024
|
+
description: Human-readable insight sentence for the UI panel.
|
|
2479
4025
|
|
|
2480
|
-
|
|
4026
|
+
AiUsageSpendKeyInsightsDto:
|
|
2481
4027
|
type: object
|
|
2482
|
-
|
|
4028
|
+
additionalProperties: false
|
|
4029
|
+
required: [workspaceId, range, scope, generatedAt, items]
|
|
2483
4030
|
properties:
|
|
2484
|
-
|
|
4031
|
+
workspaceId:
|
|
4032
|
+
type: string
|
|
4033
|
+
format: uuid
|
|
4034
|
+
range:
|
|
4035
|
+
type: string
|
|
4036
|
+
enum: [4w, 8w, q]
|
|
4037
|
+
scope:
|
|
4038
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
4039
|
+
generatedAt:
|
|
4040
|
+
type: string
|
|
4041
|
+
format: date-time
|
|
4042
|
+
items:
|
|
2485
4043
|
type: array
|
|
2486
4044
|
items:
|
|
2487
|
-
$ref: "#/components/schemas/
|
|
2488
|
-
orgChart:
|
|
2489
|
-
nullable: true
|
|
2490
|
-
allOf:
|
|
2491
|
-
- $ref: "#/components/schemas/ScoringOrgChartDto"
|
|
2492
|
-
region:
|
|
2493
|
-
type: string
|
|
2494
|
-
nullable: true
|
|
2495
|
-
enum: [us, eu, me]
|
|
4045
|
+
$ref: "#/components/schemas/AiUsageSpendKeyInsightItemDto"
|
|
2496
4046
|
|
|
2497
|
-
|
|
2498
|
-
type:
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
type: string
|
|
4047
|
+
AiAssistedCodeDataQuality:
|
|
4048
|
+
type: string
|
|
4049
|
+
enum: [estimated, measured]
|
|
4050
|
+
description: >
|
|
4051
|
+
**measured** — derived from scoped productivity ingest
|
|
4052
|
+
(`aiAdoption.aiAssistedContributionRatioPercent`). **estimated** — derived from
|
|
4053
|
+
AI-tool token volume heuristics when ingest ratios are absent for that bucket.
|
|
2505
4054
|
|
|
2506
|
-
|
|
4055
|
+
AiUsageSpendAiAssistedCodeWeekDto:
|
|
2507
4056
|
type: object
|
|
2508
|
-
|
|
4057
|
+
additionalProperties: false
|
|
4058
|
+
required:
|
|
4059
|
+
[
|
|
4060
|
+
bucketStart,
|
|
4061
|
+
bucketEnd,
|
|
4062
|
+
aiAssistedCodePercent,
|
|
4063
|
+
totalLoc,
|
|
4064
|
+
aiLoc,
|
|
4065
|
+
humanLoc,
|
|
4066
|
+
dataQuality,
|
|
4067
|
+
]
|
|
2509
4068
|
properties:
|
|
2510
|
-
|
|
4069
|
+
bucketStart:
|
|
2511
4070
|
type: string
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
displayName:
|
|
4071
|
+
format: date-time
|
|
4072
|
+
bucketEnd:
|
|
2515
4073
|
type: string
|
|
2516
|
-
|
|
2517
|
-
|
|
4074
|
+
format: date-time
|
|
4075
|
+
weekLabel:
|
|
2518
4076
|
type: string
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
4077
|
+
aiAssistedCodePercent:
|
|
4078
|
+
type: number
|
|
4079
|
+
minimum: 0
|
|
4080
|
+
maximum: 100
|
|
4081
|
+
totalLoc:
|
|
4082
|
+
type: integer
|
|
4083
|
+
minimum: 0
|
|
4084
|
+
aiLoc:
|
|
4085
|
+
type: integer
|
|
4086
|
+
minimum: 0
|
|
4087
|
+
humanLoc:
|
|
4088
|
+
type: integer
|
|
4089
|
+
minimum: 0
|
|
4090
|
+
dataQuality:
|
|
4091
|
+
$ref: "#/components/schemas/AiAssistedCodeDataQuality"
|
|
2525
4092
|
|
|
2526
|
-
|
|
4093
|
+
AiUsageSpendAiAssistedCodePercentageDto:
|
|
2527
4094
|
type: object
|
|
2528
|
-
|
|
4095
|
+
additionalProperties: false
|
|
4096
|
+
required:
|
|
4097
|
+
- workspaceId
|
|
4098
|
+
- range
|
|
4099
|
+
- scope
|
|
4100
|
+
- generatedAt
|
|
4101
|
+
- aiAssistedCodePercent
|
|
4102
|
+
- deltaVsPriorPeriodPercent
|
|
4103
|
+
- totalLoc
|
|
4104
|
+
- aiLoc
|
|
4105
|
+
- humanLoc
|
|
4106
|
+
- dataQuality
|
|
4107
|
+
- weeks
|
|
2529
4108
|
properties:
|
|
2530
|
-
|
|
2531
|
-
type: string
|
|
2532
|
-
format: date
|
|
2533
|
-
externalId:
|
|
4109
|
+
workspaceId:
|
|
2534
4110
|
type: string
|
|
2535
|
-
|
|
4111
|
+
format: uuid
|
|
4112
|
+
range:
|
|
2536
4113
|
type: string
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
4114
|
+
enum: [4w, 8w, q]
|
|
4115
|
+
scope:
|
|
4116
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
4117
|
+
generatedAt:
|
|
2541
4118
|
type: string
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
type:
|
|
2545
|
-
|
|
4119
|
+
format: date-time
|
|
4120
|
+
aiAssistedCodePercent:
|
|
4121
|
+
type: number
|
|
4122
|
+
minimum: 0
|
|
4123
|
+
maximum: 100
|
|
4124
|
+
description: Portfolio AI-assisted code share for the selected period (0–100).
|
|
4125
|
+
dataQuality:
|
|
4126
|
+
description: >
|
|
4127
|
+
Period rollup quality. **measured** only when every weekly bucket in `weeks`
|
|
4128
|
+
used ingest ratios; otherwise **estimated** (including mixed ingest/heuristic weeks).
|
|
4129
|
+
allOf:
|
|
4130
|
+
- $ref: "#/components/schemas/AiAssistedCodeDataQuality"
|
|
4131
|
+
deltaVsPriorPeriodPercent:
|
|
4132
|
+
type: number
|
|
4133
|
+
description: Change in AI-assisted code share vs the prior half of the range (percentage points).
|
|
4134
|
+
totalLoc:
|
|
4135
|
+
type: integer
|
|
4136
|
+
minimum: 0
|
|
4137
|
+
aiLoc:
|
|
4138
|
+
type: integer
|
|
4139
|
+
minimum: 0
|
|
4140
|
+
humanLoc:
|
|
4141
|
+
type: integer
|
|
4142
|
+
minimum: 0
|
|
4143
|
+
targetMinPercent:
|
|
4144
|
+
type: number
|
|
4145
|
+
default: 50
|
|
4146
|
+
targetMaxPercent:
|
|
4147
|
+
type: number
|
|
4148
|
+
default: 75
|
|
4149
|
+
weeks:
|
|
4150
|
+
type: array
|
|
4151
|
+
items:
|
|
4152
|
+
$ref: "#/components/schemas/AiUsageSpendAiAssistedCodeWeekDto"
|
|
2546
4153
|
|
|
2547
|
-
|
|
4154
|
+
AiUsageSpendAiToolUsageSpendProviderItemDto:
|
|
2548
4155
|
type: object
|
|
2549
|
-
|
|
4156
|
+
additionalProperties: false
|
|
4157
|
+
required: [providerId, providerName, tokenCount, spendCents, activeUsers]
|
|
2550
4158
|
properties:
|
|
2551
|
-
|
|
2552
|
-
type: integer
|
|
2553
|
-
format: int64
|
|
2554
|
-
externalId:
|
|
4159
|
+
providerId:
|
|
2555
4160
|
type: string
|
|
2556
|
-
|
|
4161
|
+
providerName:
|
|
2557
4162
|
type: string
|
|
2558
|
-
|
|
4163
|
+
tokenCount:
|
|
4164
|
+
type: integer
|
|
4165
|
+
minimum: 0
|
|
2559
4166
|
spendCents:
|
|
2560
4167
|
type: integer
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
type:
|
|
2564
|
-
|
|
4168
|
+
minimum: 0
|
|
4169
|
+
activeUsers:
|
|
4170
|
+
type: integer
|
|
4171
|
+
minimum: 0
|
|
2565
4172
|
|
|
2566
|
-
|
|
4173
|
+
AiUsageSpendAiToolUsageSpendModelItemDto:
|
|
2567
4174
|
type: object
|
|
2568
|
-
|
|
4175
|
+
additionalProperties: false
|
|
4176
|
+
required: [providerId, providerName, modelName, tokenCount, spendCents]
|
|
2569
4177
|
properties:
|
|
2570
|
-
|
|
2571
|
-
type: string
|
|
2572
|
-
format: date-time
|
|
2573
|
-
lastSuccessAt:
|
|
4178
|
+
providerId:
|
|
2574
4179
|
type: string
|
|
2575
|
-
|
|
2576
|
-
nullable: true
|
|
2577
|
-
lastErrorKind:
|
|
4180
|
+
providerName:
|
|
2578
4181
|
type: string
|
|
2579
|
-
|
|
2580
|
-
lastErrorMessage:
|
|
4182
|
+
modelName:
|
|
2581
4183
|
type: string
|
|
2582
|
-
|
|
2583
|
-
durationMs:
|
|
4184
|
+
tokenCount:
|
|
2584
4185
|
type: integer
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
additionalProperties: true
|
|
4186
|
+
minimum: 0
|
|
4187
|
+
spendCents:
|
|
4188
|
+
type: integer
|
|
4189
|
+
minimum: 0
|
|
2590
4190
|
|
|
2591
|
-
|
|
4191
|
+
AiUsageSpendAiToolUsageSpendDto:
|
|
2592
4192
|
type: object
|
|
2593
|
-
|
|
4193
|
+
additionalProperties: false
|
|
4194
|
+
required:
|
|
4195
|
+
- workspaceId
|
|
4196
|
+
- range
|
|
4197
|
+
- scope
|
|
4198
|
+
- generatedAt
|
|
4199
|
+
- totalEngineers
|
|
4200
|
+
- providers
|
|
4201
|
+
- models
|
|
2594
4202
|
properties:
|
|
2595
|
-
|
|
2596
|
-
type: boolean
|
|
2597
|
-
error:
|
|
4203
|
+
workspaceId:
|
|
2598
4204
|
type: string
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
4205
|
+
format: uuid
|
|
4206
|
+
range:
|
|
4207
|
+
type: string
|
|
4208
|
+
enum: [4w, 8w, q]
|
|
4209
|
+
scope:
|
|
4210
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
4211
|
+
generatedAt:
|
|
4212
|
+
type: string
|
|
4213
|
+
format: date-time
|
|
4214
|
+
totalEngineers:
|
|
4215
|
+
type: integer
|
|
4216
|
+
minimum: 0
|
|
4217
|
+
providers:
|
|
4218
|
+
type: array
|
|
4219
|
+
items:
|
|
4220
|
+
$ref: "#/components/schemas/AiUsageSpendAiToolUsageSpendProviderItemDto"
|
|
4221
|
+
models:
|
|
4222
|
+
type: array
|
|
4223
|
+
items:
|
|
4224
|
+
$ref: "#/components/schemas/AiUsageSpendAiToolUsageSpendModelItemDto"
|
|
2605
4225
|
|
|
2606
|
-
|
|
4226
|
+
AiUsageSpendTeamToolHeatmapDto:
|
|
2607
4227
|
type: object
|
|
2608
|
-
|
|
4228
|
+
additionalProperties: false
|
|
4229
|
+
required:
|
|
4230
|
+
- workspaceId
|
|
4231
|
+
- range
|
|
4232
|
+
- scope
|
|
4233
|
+
- generatedAt
|
|
4234
|
+
- teams
|
|
2609
4235
|
properties:
|
|
2610
4236
|
workspaceId:
|
|
2611
4237
|
type: string
|
|
2612
4238
|
format: uuid
|
|
4239
|
+
range:
|
|
4240
|
+
type: string
|
|
4241
|
+
enum: [4w, 8w, q]
|
|
4242
|
+
scope:
|
|
4243
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
2613
4244
|
generatedAt:
|
|
2614
4245
|
type: string
|
|
2615
4246
|
format: date-time
|
|
2616
|
-
|
|
2617
|
-
|
|
4247
|
+
teams:
|
|
4248
|
+
type: array
|
|
4249
|
+
items:
|
|
4250
|
+
$ref: "#/components/schemas/AiUsageSpendAggregatedTeamRowDto"
|
|
4251
|
+
|
|
4252
|
+
AiUsageSpendRoiProductivitySignalWeekDto:
|
|
4253
|
+
type: object
|
|
4254
|
+
additionalProperties: false
|
|
4255
|
+
required: [bucketStart, bucketEnd, mergedPrCount, tokenCount]
|
|
4256
|
+
properties:
|
|
4257
|
+
bucketStart:
|
|
2618
4258
|
type: string
|
|
2619
4259
|
format: date-time
|
|
2620
|
-
|
|
4260
|
+
bucketEnd:
|
|
2621
4261
|
type: string
|
|
2622
4262
|
format: date-time
|
|
2623
|
-
|
|
4263
|
+
weekLabel:
|
|
2624
4264
|
type: string
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
4265
|
+
mergedPrCount:
|
|
4266
|
+
type: integer
|
|
4267
|
+
minimum: 0
|
|
4268
|
+
description: Estimated merged PR count in the bucket from dashboard velocity metrics.
|
|
4269
|
+
tokenCount:
|
|
4270
|
+
type: integer
|
|
4271
|
+
minimum: 0
|
|
4272
|
+
description: Total AI-tool tokens consumed in the bucket.
|
|
2631
4273
|
|
|
2632
|
-
|
|
4274
|
+
AiUsageSpendRoiProductivitySignalDto:
|
|
2633
4275
|
type: object
|
|
2634
|
-
|
|
4276
|
+
additionalProperties: false
|
|
4277
|
+
required:
|
|
4278
|
+
- workspaceId
|
|
4279
|
+
- range
|
|
4280
|
+
- scope
|
|
4281
|
+
- generatedAt
|
|
4282
|
+
- totalMergedPrs
|
|
4283
|
+
- totalSpendCents
|
|
4284
|
+
- activeUsers
|
|
4285
|
+
- totalEngineers
|
|
4286
|
+
- aiAssistedPrRatio
|
|
4287
|
+
- prThroughputDeltaPercent
|
|
4288
|
+
- usageDeltaPercent
|
|
4289
|
+
- weeks
|
|
2635
4290
|
properties:
|
|
2636
4291
|
workspaceId:
|
|
2637
4292
|
type: string
|
|
2638
4293
|
format: uuid
|
|
2639
|
-
|
|
4294
|
+
range:
|
|
2640
4295
|
type: string
|
|
2641
|
-
enum: [
|
|
2642
|
-
|
|
4296
|
+
enum: [4w, 8w, q]
|
|
4297
|
+
scope:
|
|
4298
|
+
$ref: "#/components/schemas/ProductivityInsightsAggregatedTeamsScopeDto"
|
|
4299
|
+
generatedAt:
|
|
4300
|
+
type: string
|
|
4301
|
+
format: date-time
|
|
4302
|
+
totalMergedPrs:
|
|
4303
|
+
type: integer
|
|
4304
|
+
minimum: 0
|
|
4305
|
+
totalSpendCents:
|
|
4306
|
+
type: integer
|
|
4307
|
+
minimum: 0
|
|
4308
|
+
activeUsers:
|
|
4309
|
+
type: integer
|
|
4310
|
+
minimum: 0
|
|
4311
|
+
totalEngineers:
|
|
4312
|
+
type: integer
|
|
4313
|
+
minimum: 0
|
|
4314
|
+
aiAssistedPrRatio:
|
|
4315
|
+
type: number
|
|
4316
|
+
minimum: 0
|
|
4317
|
+
maximum: 1
|
|
4318
|
+
description: Share of merged PRs estimated to be AI-assisted (0–1).
|
|
4319
|
+
prThroughputDeltaPercent:
|
|
4320
|
+
type: number
|
|
4321
|
+
description: Percent change in merged PR throughput (recent half vs prior half of range).
|
|
4322
|
+
usageDeltaPercent:
|
|
4323
|
+
type: number
|
|
4324
|
+
description: Percent change in token usage (recent half vs prior half of range).
|
|
4325
|
+
weeks:
|
|
2643
4326
|
type: array
|
|
2644
4327
|
items:
|
|
2645
|
-
|
|
2646
|
-
required: [bucketStart, bucketEnd, metrics]
|
|
2647
|
-
properties:
|
|
2648
|
-
bucketStart:
|
|
2649
|
-
type: string
|
|
2650
|
-
format: date-time
|
|
2651
|
-
bucketEnd:
|
|
2652
|
-
type: string
|
|
2653
|
-
format: date-time
|
|
2654
|
-
metrics:
|
|
2655
|
-
$ref: "#/components/schemas/DashboardProductivityMetricsDto"
|
|
4328
|
+
$ref: "#/components/schemas/AiUsageSpendRoiProductivitySignalWeekDto"
|
|
2656
4329
|
|
|
2657
4330
|
MeProfileDto:
|
|
2658
4331
|
type: object
|
|
@@ -2772,9 +4445,26 @@ components:
|
|
|
2772
4445
|
type: boolean
|
|
2773
4446
|
nullable: true
|
|
2774
4447
|
|
|
4448
|
+
GithubMissingPermissionDto:
|
|
4449
|
+
type: object
|
|
4450
|
+
additionalProperties: false
|
|
4451
|
+
required: [name, required]
|
|
4452
|
+
properties:
|
|
4453
|
+
name:
|
|
4454
|
+
type: string
|
|
4455
|
+
description: GitHub App permission key (e.g. contents, pull_requests).
|
|
4456
|
+
required:
|
|
4457
|
+
type: string
|
|
4458
|
+
enum: [read, write, admin]
|
|
4459
|
+
granted:
|
|
4460
|
+
type: string
|
|
4461
|
+
enum: [read, write, admin]
|
|
4462
|
+
nullable: true
|
|
4463
|
+
description: Null when the installation has not granted this permission.
|
|
4464
|
+
|
|
2775
4465
|
GithubInstallationSummaryDto:
|
|
2776
4466
|
type: object
|
|
2777
|
-
required: [installationId, account, repos]
|
|
4467
|
+
required: [installationId, account, repos, permissionsUpgradeRequired]
|
|
2778
4468
|
properties:
|
|
2779
4469
|
installationId:
|
|
2780
4470
|
type: string
|
|
@@ -2793,10 +4483,23 @@ components:
|
|
|
2793
4483
|
type: string
|
|
2794
4484
|
format: date-time
|
|
2795
4485
|
nullable: true
|
|
4486
|
+
permissionsUpgradeRequired:
|
|
4487
|
+
type: boolean
|
|
4488
|
+
description: >
|
|
4489
|
+
True when this installation's granted permissions are below what the ThinkAI GitHub App
|
|
4490
|
+
currently requests.
|
|
4491
|
+
missingPermissions:
|
|
4492
|
+
type: array
|
|
4493
|
+
items:
|
|
4494
|
+
$ref: "#/components/schemas/GithubMissingPermissionDto"
|
|
4495
|
+
upgradeMessage:
|
|
4496
|
+
type: string
|
|
4497
|
+
nullable: true
|
|
4498
|
+
description: Human-readable summary for UI when permissionsUpgradeRequired is true.
|
|
2796
4499
|
|
|
2797
4500
|
GithubInstallationStatusDto:
|
|
2798
4501
|
type: object
|
|
2799
|
-
required: [installed, installations]
|
|
4502
|
+
required: [installed, installations, permissionsUpgradeRequired]
|
|
2800
4503
|
properties:
|
|
2801
4504
|
installed:
|
|
2802
4505
|
type: boolean
|
|
@@ -2804,6 +4507,9 @@ components:
|
|
|
2804
4507
|
type: array
|
|
2805
4508
|
items:
|
|
2806
4509
|
$ref: "#/components/schemas/GithubInstallationSummaryDto"
|
|
4510
|
+
permissionsUpgradeRequired:
|
|
4511
|
+
type: boolean
|
|
4512
|
+
description: True if any connected installation is under-permissioned.
|
|
2807
4513
|
installationId:
|
|
2808
4514
|
type: string
|
|
2809
4515
|
nullable: true
|