| 1 | using System.Net.Http.Json; |
| 2 | using System.Text.Json.Serialization; |
| 3 | |
| 4 | namespace CascadeIDE.Features.Intercom.Transport; |
| 5 | |
| 6 | public sealed partial class IntercomTransportApiClient |
| 7 | { |
| 8 | public async Task<bool> PingHealthAsync(CancellationToken ct = default) |
| 9 | { |
| 10 | using var res = await _http.GetAsync("/health", ct).ConfigureAwait(false); |
| 11 | return res.IsSuccessStatusCode; |
| 12 | } |
| 13 | |
| 14 | public async Task<IntercomAdminHealthDto?> GetTeamAdminHealthAsync( |
| 15 | string teamId, |
| 16 | string bearerToken, |
| 17 | CancellationToken ct) |
| 18 | { |
| 19 | using var req = Authorized(HttpMethod.Get, $"/api/v1/teams/{Uri.EscapeDataString(teamId)}/admin/health", bearerToken); |
| 20 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 21 | if (!res.IsSuccessStatusCode) |
| 22 | return null; |
| 23 | return await res.Content.ReadFromJsonAsync<IntercomAdminHealthDto>(IntercomTransportJson.Web, ct) |
| 24 | .ConfigureAwait(false); |
| 25 | } |
| 26 | |
| 27 | public async Task<IReadOnlyList<IntercomTeamMemberDto>> ListTeamMembersAsync( |
| 28 | string teamId, |
| 29 | string bearerToken, |
| 30 | CancellationToken ct) |
| 31 | { |
| 32 | using var req = Authorized(HttpMethod.Get, $"/api/v1/teams/{Uri.EscapeDataString(teamId)}/members", bearerToken); |
| 33 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 34 | if (!res.IsSuccessStatusCode) |
| 35 | return []; |
| 36 | var list = await res.Content.ReadFromJsonAsync<List<IntercomTeamMemberDto>>(IntercomTransportJson.Web, ct) |
| 37 | .ConfigureAwait(false); |
| 38 | return list ?? []; |
| 39 | } |
| 40 | |
| 41 | public async Task<IntercomAgentProvisionDto?> ProvisionAgentAsync( |
| 42 | string teamId, |
| 43 | string displayName, |
| 44 | string? avatarGlyph, |
| 45 | string bearerToken, |
| 46 | CancellationToken ct) |
| 47 | { |
| 48 | var body = new { display_name = displayName, avatar_glyph = avatarGlyph }; |
| 49 | using var req = Authorized(HttpMethod.Post, $"/api/v1/teams/{Uri.EscapeDataString(teamId)}/agents", bearerToken); |
| 50 | req.Content = JsonContent.Create(body, options: IntercomTransportJson.Web); |
| 51 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 52 | if (!res.IsSuccessStatusCode) |
| 53 | return null; |
| 54 | return await res.Content.ReadFromJsonAsync<IntercomAgentProvisionDto>(IntercomTransportJson.Web, ct) |
| 55 | .ConfigureAwait(false); |
| 56 | } |
| 57 | |
| 58 | public async Task<IntercomInviteDto?> CreateInviteAsync( |
| 59 | string teamId, |
| 60 | string teamRole, |
| 61 | string bearerToken, |
| 62 | CancellationToken ct) |
| 63 | { |
| 64 | var body = new { team_role = teamRole, ttl_hours = 168, max_uses = 1 }; |
| 65 | using var req = Authorized(HttpMethod.Post, $"/api/v1/teams/{Uri.EscapeDataString(teamId)}/invites", bearerToken); |
| 66 | req.Content = JsonContent.Create(body, options: IntercomTransportJson.Web); |
| 67 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 68 | if (!res.IsSuccessStatusCode) |
| 69 | return null; |
| 70 | return await res.Content.ReadFromJsonAsync<IntercomInviteDto>(IntercomTransportJson.Web, ct) |
| 71 | .ConfigureAwait(false); |
| 72 | } |
| 73 | |
| 74 | public async Task<IntercomProjectDto?> CreateProjectAsync( |
| 75 | string projectId, |
| 76 | string? displayName, |
| 77 | string bearerToken, |
| 78 | CancellationToken ct) |
| 79 | { |
| 80 | var body = new { project_id = projectId, display_name = displayName }; |
| 81 | using var req = Authorized(HttpMethod.Post, "/api/v1/projects", bearerToken); |
| 82 | req.Content = JsonContent.Create(body, options: IntercomTransportJson.Web); |
| 83 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 84 | if (!res.IsSuccessStatusCode) |
| 85 | return null; |
| 86 | return await res.Content.ReadFromJsonAsync<IntercomProjectDto>(IntercomTransportJson.Web, ct) |
| 87 | .ConfigureAwait(false); |
| 88 | } |
| 89 | |
| 90 | public async Task<bool> PutProjectReposAsync( |
| 91 | string projectId, |
| 92 | IReadOnlyList<string> repoUrls, |
| 93 | string bearerToken, |
| 94 | CancellationToken ct) |
| 95 | { |
| 96 | var body = new { repo_urls = repoUrls }; |
| 97 | using var req = Authorized(HttpMethod.Put, $"/api/v1/projects/{Uri.EscapeDataString(projectId)}/repos", bearerToken); |
| 98 | req.Content = JsonContent.Create(body, options: IntercomTransportJson.Web); |
| 99 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 100 | return res.IsSuccessStatusCode; |
| 101 | } |
| 102 | |
| 103 | public async Task<bool> PutTeamProjectsAsync( |
| 104 | string teamId, |
| 105 | IReadOnlyList<string> projectIds, |
| 106 | string bearerToken, |
| 107 | CancellationToken ct) |
| 108 | { |
| 109 | var body = new { project_ids = projectIds }; |
| 110 | using var req = Authorized(HttpMethod.Put, $"/api/v1/teams/{Uri.EscapeDataString(teamId)}/projects", bearerToken); |
| 111 | req.Content = JsonContent.Create(body, options: IntercomTransportJson.Web); |
| 112 | using var res = await _http.SendAsync(req, ct).ConfigureAwait(false); |
| 113 | return res.IsSuccessStatusCode; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | public sealed record IntercomAdminHealthDto( |
| 118 | [property: JsonPropertyName("status")] string Status, |
| 119 | [property: JsonPropertyName("team_id")] string TeamId, |
| 120 | [property: JsonPropertyName("sse_subscribers")] int SseSubscribers); |
| 121 | |
| 122 | public sealed record IntercomTeamMemberDto( |
| 123 | [property: JsonPropertyName("member_id")] string MemberId, |
| 124 | [property: JsonPropertyName("member_kind")] string MemberKind, |
| 125 | [property: JsonPropertyName("team_role")] string TeamRole, |
| 126 | [property: JsonPropertyName("display_name")] string DisplayName, |
| 127 | [property: JsonPropertyName("team_display_name")] string? TeamDisplayName, |
| 128 | [property: JsonPropertyName("joined_at_utc")] string JoinedAtUtc); |
| 129 | |
| 130 | public sealed record IntercomAgentProvisionDto( |
| 131 | [property: JsonPropertyName("member_id")] string MemberId, |
| 132 | [property: JsonPropertyName("display_name")] string DisplayName, |
| 133 | [property: JsonPropertyName("avatar_glyph")] string? AvatarGlyph, |
| 134 | [property: JsonPropertyName("credential_token")] string CredentialToken); |
| 135 | |
| 136 | public sealed record IntercomInviteDto( |
| 137 | [property: JsonPropertyName("invite_id")] string InviteId, |
| 138 | [property: JsonPropertyName("token")] string Token, |
| 139 | [property: JsonPropertyName("team_role")] string TeamRole, |
| 140 | [property: JsonPropertyName("expires_at_utc")] string ExpiresAtUtc, |
| 141 | [property: JsonPropertyName("max_uses")] int MaxUses); |
| 142 | |
| 143 | public sealed record IntercomProjectDto( |
| 144 | [property: JsonPropertyName("project_id")] string ProjectId, |
| 145 | [property: JsonPropertyName("display_name")] string DisplayName); |
| 146 | |