@thinkai/tai-api-contract 2.11.1 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.0.3
2
2
  info:
3
3
  title: ThinkAI API
4
- version: 2.11.1
4
+ version: 2.13.0
5
5
  description: >
6
6
  Contract surface for the AI Driven SDLC backend used by ThinkAI.
7
7
  Workspace-scoped routes use `/workspaces/{workspaceId}/...`.
@@ -52,6 +52,8 @@ tags:
52
52
  description: Agentic Foundation pillars (epic #278); reads stored repository readiness snapshots
53
53
  - name: YourAiJourney
54
54
  description: Your AI Journey dashboard aggregators (epic #267); composes readiness, metrics, and AI-spend data for the /dashboard page
55
+ - name: WorkspaceActivity
56
+ description: Workspace-wide lifecycle activity log — repo add/remove/re-add and integration lifecycle events (issue #515).
55
57
  - name: PlatformAdmin
56
58
  description: Platform-admin operations restricted to PLATFORM_ADMIN_EMAILS. Callers must present a valid JWT from an email on that allowlist; all other callers receive 403.
57
59
 
@@ -2282,6 +2284,12 @@ paths:
2282
2284
  - $ref: "#/components/parameters/PaginationOrder"
2283
2285
  - $ref: "#/components/parameters/ReadinessRepoSearch"
2284
2286
  - $ref: "#/components/parameters/ReadinessRepoLanguage"
2287
+ - name: includeArchived
2288
+ in: query
2289
+ description: When `true`, includes Inactive (user-removed) repos alongside Active ones. Default is `false` (active only).
2290
+ schema:
2291
+ type: boolean
2292
+ default: false
2285
2293
  responses:
2286
2294
  "200":
2287
2295
  description: Paginated repositories analyzed
@@ -2462,6 +2470,62 @@ paths:
2462
2470
  application/json:
2463
2471
  schema:
2464
2472
  $ref: "#/components/schemas/ErrorMessageDto"
2473
+ patch:
2474
+ tags: [RepositoryReadiness]
2475
+ summary: Archive (remove) or restore (re-add) a repository
2476
+ description: >
2477
+ Set `archived: true` to soft-remove the repo (Inactive). Set `archived: false` to re-add a
2478
+ previously Inactive repo (Active). Re-add reuses the same `repo_id` row so historical scan
2479
+ foreign keys remain intact, and automatically enqueues a fresh readiness scan.
2480
+
2481
+ Returns `409` with `code: repo_scan_in_progress` if a scan is queued or running when archiving.
2482
+ Returns `409` with `code: repo_already_active` if re-adding a repo that is already Active.
2483
+ operationId: patchReadinessRepo
2484
+ parameters:
2485
+ - $ref: "#/components/parameters/WorkspaceId"
2486
+ - $ref: "#/components/parameters/RepoId"
2487
+ requestBody:
2488
+ required: true
2489
+ content:
2490
+ application/json:
2491
+ schema:
2492
+ $ref: "#/components/schemas/PatchRepoArchiveBodyDto"
2493
+ examples:
2494
+ archive:
2495
+ value:
2496
+ archived: true
2497
+ restore:
2498
+ value:
2499
+ archived: false
2500
+ responses:
2501
+ "200":
2502
+ description: Repo status updated
2503
+ content:
2504
+ application/json:
2505
+ schema:
2506
+ $ref: "#/components/schemas/PatchRepoArchiveResponseDto"
2507
+ "400":
2508
+ description: Malformed request body or repoId
2509
+ content:
2510
+ application/json:
2511
+ schema:
2512
+ $ref: "#/components/schemas/ErrorMessageDto"
2513
+ "401":
2514
+ $ref: "#/components/responses/Unauthorized"
2515
+ "403":
2516
+ $ref: "#/components/responses/Forbidden"
2517
+ "404":
2518
+ description: Workspace or repository not found
2519
+ content:
2520
+ application/json:
2521
+ schema:
2522
+ $ref: "#/components/schemas/ErrorMessageDto"
2523
+ "409":
2524
+ description: Conflict — scan in progress or repo already in the requested state
2525
+ content:
2526
+ application/json:
2527
+ schema:
2528
+ $ref: "#/components/schemas/ErrorMessageDto"
2465
2529
 
2466
2530
  /workspaces/{workspaceId}/readiness/repos/{repoId}/runs:
2467
2531
  get:
@@ -2603,6 +2667,83 @@ paths:
2603
2667
  schema:
2604
2668
  $ref: "#/components/schemas/ErrorMessageDto"
2605
2669
 
2670
+ /workspaces/{workspaceId}/activity:
2671
+ get:
2672
+ tags: [WorkspaceActivity]
2673
+ summary: Workspace activity log (paginated)
2674
+ operationId: listWorkspaceActivity
2675
+ description: >
2676
+ Paginated, chronological feed of workspace-scoped lifecycle events: repository add/remove/re-add
2677
+ and GitHub integration add/remove. Inactive repos remain visible in this log.
2678
+ Filter by `eventType`, `actorUserId`, or date range (`since`/`until`).
2679
+ parameters:
2680
+ - $ref: "#/components/parameters/WorkspaceId"
2681
+ - $ref: "#/components/parameters/PaginationLimit"
2682
+ - $ref: "#/components/parameters/PaginationOffset"
2683
+ - $ref: "#/components/parameters/PaginationOrder"
2684
+ - name: eventType
2685
+ in: query
2686
+ description: Filter to a specific event type.
2687
+ schema:
2688
+ $ref: "#/components/schemas/ActivityLogEventTypeDto"
2689
+ - name: actorUserId
2690
+ in: query
2691
+ description: Filter to events performed by a specific user (UUID).
2692
+ schema:
2693
+ type: string
2694
+ format: uuid
2695
+ - name: since
2696
+ in: query
2697
+ description: ISO-8601 lower bound on `occurredAt` (inclusive).
2698
+ schema:
2699
+ type: string
2700
+ format: date-time
2701
+ - name: until
2702
+ in: query
2703
+ description: ISO-8601 upper bound on `occurredAt` (inclusive).
2704
+ schema:
2705
+ type: string
2706
+ format: date-time
2707
+ - name: eventCategory
2708
+ in: query
2709
+ required: false
2710
+ description: >
2711
+ Filter by event namespace prefix (e.g. "fix", "repo", "integration", "readiness", "config", "member").
2712
+ schema:
2713
+ type: string
2714
+ - name: search
2715
+ in: query
2716
+ required: false
2717
+ description: >
2718
+ Case-insensitive substring filter applied across repo name,
2719
+ integration type, actor email, and actor display name.
2720
+ schema:
2721
+ type: string
2722
+ maxLength: 200
2723
+ responses:
2724
+ "200":
2725
+ description: Paginated activity log entries
2726
+ content:
2727
+ application/json:
2728
+ schema:
2729
+ $ref: "#/components/schemas/ActivityLogPageDto"
2730
+ "400":
2731
+ description: Invalid query parameters
2732
+ content:
2733
+ application/json:
2734
+ schema:
2735
+ $ref: "#/components/schemas/ErrorMessageDto"
2736
+ "401":
2737
+ $ref: "#/components/responses/Unauthorized"
2738
+ "403":
2739
+ $ref: "#/components/responses/Forbidden"
2740
+ "404":
2741
+ description: Workspace does not exist
2742
+ content:
2743
+ application/json:
2744
+ schema:
2745
+ $ref: "#/components/schemas/ErrorMessageDto"
2746
+
2606
2747
  /workspaces/{workspaceId}/readiness/score-history:
2607
2748
  get:
2608
2749
  tags: [RepositoryReadiness]
@@ -3897,6 +4038,123 @@ paths:
3897
4038
  schema:
3898
4039
  $ref: "#/components/schemas/ErrorMessageDto"
3899
4040
 
4041
+ /workspaces/{workspaceId}/absences:
4042
+ get:
4043
+ tags: [HRIS]
4044
+ summary: List absence records
4045
+ operationId: listWorkspaceAbsences
4046
+ description: >
4047
+ Returns time-off/absence records sourced from connected HRIS providers (e.g. Personio)
4048
+ for the given date window. Requires workspace membership.
4049
+ parameters:
4050
+ - $ref: "#/components/parameters/WorkspaceId"
4051
+ - name: from
4052
+ in: query
4053
+ description: Start of date window (ISO YYYY-MM-DD). Defaults to today.
4054
+ schema: { type: string, format: date }
4055
+ - name: to
4056
+ in: query
4057
+ description: End of date window (ISO YYYY-MM-DD). Defaults to 90 days from today.
4058
+ schema: { type: string, format: date }
4059
+ responses:
4060
+ "200":
4061
+ description: Absence list with last sync timestamp
4062
+ content:
4063
+ application/json:
4064
+ schema:
4065
+ $ref: "#/components/schemas/WorkspaceAbsenceListDto"
4066
+ example:
4067
+ absences:
4068
+ - source: personio
4069
+ employeeEmail: alice@example.com
4070
+ absenceType: Vacation
4071
+ startDate: "2025-07-01"
4072
+ endDate: "2025-07-05"
4073
+ halfDayStart: false
4074
+ halfDayEnd: false
4075
+ status: approved
4076
+ syncedAt: "2025-06-30T08:00:00.000Z"
4077
+ "401":
4078
+ $ref: "#/components/responses/Unauthorized"
4079
+ "403":
4080
+ $ref: "#/components/responses/Forbidden"
4081
+
4082
+ /workspaces/{workspaceId}/hris/status:
4083
+ get:
4084
+ tags: [HRIS]
4085
+ summary: HRIS sync status
4086
+ operationId: getHrisSyncStatus
4087
+ description: >
4088
+ Returns the last sync status for every HRIS provider connected to the workspace.
4089
+ Returns an empty `statuses` array when no HRIS source has been synced yet.
4090
+ Requires workspace membership.
4091
+ parameters:
4092
+ - $ref: "#/components/parameters/WorkspaceId"
4093
+ responses:
4094
+ "200":
4095
+ description: Sync status list
4096
+ content:
4097
+ application/json:
4098
+ schema:
4099
+ $ref: "#/components/schemas/HrisSyncStatusListDto"
4100
+ example:
4101
+ statuses:
4102
+ - provider: personio
4103
+ lastSyncAt: "2025-06-30T08:00:00.000Z"
4104
+ status: ok
4105
+ "401":
4106
+ $ref: "#/components/responses/Unauthorized"
4107
+ "403":
4108
+ $ref: "#/components/responses/Forbidden"
4109
+
4110
+ /workspaces/{workspaceId}/hris/sync:
4111
+ post:
4112
+ tags: [HRIS]
4113
+ summary: Trigger manual HRIS sync
4114
+ operationId: triggerHrisSync
4115
+ description: >
4116
+ Manually triggers an HRIS sync for the workspace. Runs synchronously and returns
4117
+ the result. Requires editor role (same permission level as org-chart writes).
4118
+ Returns 422 when no HRIS source is configured.
4119
+ parameters:
4120
+ - $ref: "#/components/parameters/WorkspaceId"
4121
+ responses:
4122
+ "200":
4123
+ description: Sync completed successfully
4124
+ content:
4125
+ application/json:
4126
+ schema:
4127
+ $ref: "#/components/schemas/HrisTriggerSyncResultDto"
4128
+ example:
4129
+ status: ok
4130
+ employeeCount: 42
4131
+ absenceCount: 7
4132
+ durationMs: 1234
4133
+ "422":
4134
+ description: No HRIS source configured for this workspace
4135
+ content:
4136
+ application/json:
4137
+ schema:
4138
+ $ref: "#/components/schemas/HrisTriggerSyncResultDto"
4139
+ example:
4140
+ status: skipped
4141
+ code: no_personio_source
4142
+ reason: no_personio_source
4143
+ "500":
4144
+ description: Sync failed (Personio API error, decryption failure, etc.)
4145
+ content:
4146
+ application/json:
4147
+ schema:
4148
+ $ref: "#/components/schemas/HrisTriggerSyncResultDto"
4149
+ example:
4150
+ status: error
4151
+ code: hris_sync_failed
4152
+ error: "Personio employees API 401"
4153
+ "401":
4154
+ $ref: "#/components/responses/Unauthorized"
4155
+ "403":
4156
+ $ref: "#/components/responses/Forbidden"
4157
+
3900
4158
  components:
3901
4159
  securitySchemes:
3902
4160
  bearerAuth:
@@ -7363,3 +7621,241 @@ components:
7363
7621
  type: integer
7364
7622
  activeUsers:
7365
7623
  type: integer
7624
+
7625
+ PatchRepoArchiveBodyDto:
7626
+ type: object
7627
+ required: [archived]
7628
+ properties:
7629
+ archived:
7630
+ type: boolean
7631
+ description: >
7632
+ `true` to soft-remove (Inactive). `false` to restore a previously Inactive repo (Active),
7633
+ which also enqueues a fresh readiness scan.
7634
+
7635
+ PatchRepoArchiveResponseDto:
7636
+ type: object
7637
+ required: [repoId, status]
7638
+ properties:
7639
+ repoId:
7640
+ type: string
7641
+ format: uuid
7642
+ status:
7643
+ type: string
7644
+ enum: [Active, Inactive]
7645
+ description: Current lifecycle status of the repository after the operation.
7646
+ runId:
7647
+ type: string
7648
+ format: uuid
7649
+ nullable: true
7650
+ description: ID of the freshly enqueued readiness scan run (only present on re-add).
7651
+
7652
+ ActivityLogEventTypeDto:
7653
+ type: string
7654
+ description: Type of workspace lifecycle event.
7655
+ enum:
7656
+ - repo.added
7657
+ - repo.removed
7658
+ - repo.readded
7659
+ - integration.github.added
7660
+ - integration.github.updated
7661
+ - integration.github.removed
7662
+ - integration.github.permissions_changed
7663
+ - integration.github.repo_added
7664
+ - integration.github.repo_removed
7665
+ - fix.requested
7666
+ - fix.generating
7667
+ - fix.pr_created
7668
+ - fix.merged
7669
+ - fix.failed
7670
+ - readiness.scan_started
7671
+ - readiness.scan_completed
7672
+ - readiness.scan_failed
7673
+ - readiness.scan_partial
7674
+ - config.cursor.added
7675
+ - config.cursor.updated
7676
+ - config.cursor.removed
7677
+ - config.cursor.platform_key_enabled
7678
+ - config.cursor.platform_key_disabled
7679
+ - config.claude.added
7680
+ - config.claude.updated
7681
+ - config.claude.removed
7682
+ - member.invited
7683
+ - member.role_changed
7684
+ - member.removed
7685
+
7686
+ ActivityLogActorDto:
7687
+ type: object
7688
+ required: [userId]
7689
+ properties:
7690
+ userId:
7691
+ type: string
7692
+ format: uuid
7693
+ email:
7694
+ type: string
7695
+ format: email
7696
+ nullable: true
7697
+ name:
7698
+ type: string
7699
+ nullable: true
7700
+
7701
+ ActivityLogEntryDto:
7702
+ type: object
7703
+ required: [id, eventType, eventCategory, occurredAt, actorType]
7704
+ properties:
7705
+ id:
7706
+ type: string
7707
+ format: uuid
7708
+ eventType:
7709
+ $ref: "#/components/schemas/ActivityLogEventTypeDto"
7710
+ eventCategory:
7711
+ type: string
7712
+ description: Namespace prefix derived from event_type (e.g. "fix", "repo", "config").
7713
+ occurredAt:
7714
+ type: string
7715
+ format: date-time
7716
+ actorType:
7717
+ type: string
7718
+ enum: [user, system, webhook]
7719
+ description: Whether the event was triggered by a human user, a batch/system process, or a webhook.
7720
+ actor:
7721
+ nullable: true
7722
+ allOf:
7723
+ - $ref: "#/components/schemas/ActivityLogActorDto"
7724
+ repoId:
7725
+ type: string
7726
+ format: uuid
7727
+ nullable: true
7728
+ repoName:
7729
+ type: string
7730
+ nullable: true
7731
+ integrationId:
7732
+ type: string
7733
+ format: uuid
7734
+ nullable: true
7735
+ integrationType:
7736
+ type: string
7737
+ nullable: true
7738
+ fixRequestId:
7739
+ type: string
7740
+ format: uuid
7741
+ nullable: true
7742
+ description: ID of the related fix request (fix.* events).
7743
+ issueId:
7744
+ type: string
7745
+ format: uuid
7746
+ nullable: true
7747
+ description: ID of the related readiness issue (fix.* events).
7748
+ readinessRunId:
7749
+ type: string
7750
+ format: uuid
7751
+ nullable: true
7752
+ description: ID of the related readiness run (readiness.* events).
7753
+ metadata:
7754
+ type: object
7755
+ additionalProperties: true
7756
+ nullable: true
7757
+ description: Event-specific supplementary data (before/after state, installation IDs, etc.).
7758
+
7759
+ WorkspaceAbsenceDto:
7760
+ type: object
7761
+ required: [source, employeeEmail, absenceType, startDate, endDate, halfDayStart, halfDayEnd, status]
7762
+ properties:
7763
+ source:
7764
+ type: string
7765
+ description: HRIS provider that sourced this record (e.g. 'personio', 'zenhr').
7766
+ employeeEmail:
7767
+ type: string
7768
+ format: email
7769
+ absenceType:
7770
+ type: string
7771
+ startDate:
7772
+ type: string
7773
+ format: date
7774
+ endDate:
7775
+ type: string
7776
+ format: date
7777
+ halfDayStart:
7778
+ type: boolean
7779
+ halfDayEnd:
7780
+ type: boolean
7781
+ status:
7782
+ type: string
7783
+ enum: [approved, pending, rejected]
7784
+
7785
+ WorkspaceAbsenceListDto:
7786
+ type: object
7787
+ required: [absences, syncedAt]
7788
+ properties:
7789
+ absences:
7790
+ type: array
7791
+ items:
7792
+ $ref: "#/components/schemas/WorkspaceAbsenceDto"
7793
+ syncedAt:
7794
+ type: string
7795
+ format: date-time
7796
+ nullable: true
7797
+ description: ISO timestamp of the most recent successful HRIS sync, or null if never synced.
7798
+
7799
+ HrisSyncStatusDto:
7800
+ type: object
7801
+ required: [provider, lastSyncAt, status]
7802
+ properties:
7803
+ provider:
7804
+ type: string
7805
+ description: Provider identifier (e.g. 'personio', 'zenhr').
7806
+ lastSyncAt:
7807
+ type: string
7808
+ format: date-time
7809
+ nullable: true
7810
+ status:
7811
+ type: string
7812
+ enum: [ok, error, never]
7813
+ lastError:
7814
+ type: string
7815
+ nullable: true
7816
+
7817
+ HrisSyncStatusListDto:
7818
+ type: object
7819
+ required: [statuses]
7820
+ properties:
7821
+ statuses:
7822
+ type: array
7823
+ items:
7824
+ $ref: "#/components/schemas/HrisSyncStatusDto"
7825
+
7826
+ HrisTriggerSyncResultDto:
7827
+ type: object
7828
+ required: [status]
7829
+ properties:
7830
+ status:
7831
+ type: string
7832
+ enum: [ok, skipped, error]
7833
+ code:
7834
+ type: string
7835
+ description: Stable machine-readable code (e.g. 'no_personio_source', 'hris_sync_failed').
7836
+ employeeCount:
7837
+ type: integer
7838
+ description: Number of employees synced (present when status = 'ok').
7839
+ absenceCount:
7840
+ type: integer
7841
+ description: Number of absence records synced (present when status = 'ok').
7842
+ durationMs:
7843
+ type: integer
7844
+ description: Wall-clock duration of the sync in milliseconds (present when status = 'ok').
7845
+ reason:
7846
+ type: string
7847
+ description: Machine-readable reason for a skipped sync (e.g. 'no_personio_source').
7848
+ error:
7849
+ type: string
7850
+ description: Error message when status = 'error'.
7851
+
7852
+ ActivityLogPageDto:
7853
+ allOf:
7854
+ - $ref: "#/components/schemas/PageMetaDto"
7855
+ - type: object
7856
+ required: [items]
7857
+ properties:
7858
+ items:
7859
+ type: array
7860
+ items:
7861
+ $ref: "#/components/schemas/ActivityLogEntryDto"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkai/tai-api-contract",
3
- "version": "2.11.1",
3
+ "version": "2.13.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,6 +21,7 @@
21
21
  "dependencies": {},
22
22
  "devDependencies": {
23
23
  "@stoplight/spectral-cli": "^6.15.1",
24
+ "jsonpath-plus": "^10.3.0",
24
25
  "openapi-typescript": "^7.13.0",
25
26
  "typescript": "~5.3.0"
26
27
  },