From eac70e1c609a584c8d75b10ea393c60afe48a77b Mon Sep 17 00:00:00 2001 From: Ryan Quinn Date: Thu, 6 Feb 2025 10:35:10 -0600 Subject: [PATCH] feat: support start time in read changes request --- README.md | 3 ++- docs/OpenFgaApi.md | 6 ++++-- src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs | 3 ++- src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs | 3 ++- src/OpenFga.Sdk/Api/OpenFgaApi.cs | 6 +++++- src/OpenFga.Sdk/Client/Client.cs | 4 ++-- src/OpenFga.Sdk/Client/Model/ClientReadChangesRequest.cs | 2 ++ src/OpenFga.Sdk/Model/ErrorCode.cs | 8 +++++++- 8 files changed, 26 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9c1199f..4412209 100644 --- a/README.md +++ b/README.md @@ -379,7 +379,8 @@ Reads the list of historical relationship tuple writes and deletes. [API Documentation](https://openfga.dev/api/service#/Relationship%20Tuples/ReadChanges) ```csharp -var body = new ClientReadChangesRequest { Type = "document" }; +var startTime = DateTime.Parse("2022-01-01T00:00:00Z"); +var body = new ClientReadChangesRequest { Type = "document", StartTime = startTime }; var options = new ClientReadChangesOptions { PageSize = 10, ContinuationToken = "...", diff --git a/docs/OpenFgaApi.md b/docs/OpenFgaApi.md index c935b38..938f67d 100644 --- a/docs/OpenFgaApi.md +++ b/docs/OpenFgaApi.md @@ -991,7 +991,7 @@ Name | Type | Description | Notes # **ReadChanges** -> ReadChangesResponse ReadChanges (string? type = null, int? pageSize = null, string? continuationToken = null) +> ReadChangesResponse ReadChanges (string? type = null, int? pageSize = null, string? continuationToken = null, DateTime? startTime = null) Return a list of all the tuple changes @@ -1023,11 +1023,12 @@ namespace Example var type = "type_example"; // string? | (optional) var pageSize = 56; // int? | (optional) var continuationToken = "continuationToken_example"; // string? | (optional) + var startTime = DateTime.Parse("2013-10-20T19:20:30+01:00"); // DateTime? | Start date and time of changes to read. Format: ISO 8601 timestamp (e.g., 2022-01-01T00:00:00Z) If a continuation_token is provided along side start_time, the continuation_token will take precedence over start_time. (optional) try { // Return a list of all the tuple changes - ReadChangesResponse response = await openFgaApi.ReadChanges(type, pageSize, continuationToken); + ReadChangesResponse response = await openFgaApi.ReadChanges(type, pageSize, continuationToken, startTime); Debug.WriteLine(response); } catch (ApiException e) @@ -1049,6 +1050,7 @@ Name | Type | Description | Notes **type** | **string?**| | [optional] **pageSize** | **int?**| | [optional] **continuationToken** | **string?**| | [optional] + **startTime** | **DateTime?**| Start date and time of changes to read. Format: ISO 8601 timestamp (e.g., 2022-01-01T00:00:00Z) If a continuation_token is provided along side start_time, the continuation_token will take precedence over start_time. | [optional] ### Return type diff --git a/src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs b/src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs index b825fed..5e8876c 100644 --- a/src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs +++ b/src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs @@ -1702,8 +1702,9 @@ public async Task ReadChangesTest() { var type = "repo"; var pageSize = 25; + var startTime = DateTime.Parse("2022-01-01T00:00:00Z"); var continuationToken = "eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="; - var response = await openFgaApi.ReadChanges(_storeId, type, pageSize, continuationToken); + var response = await openFgaApi.ReadChanges(_storeId, type, pageSize, continuationToken, startTime); mockHandler.Protected().Verify( "SendAsync", diff --git a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs index 3d732c1..c24a23a 100644 --- a/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs +++ b/src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs @@ -645,9 +645,10 @@ public async Task ReadChangesTest() { var type = "repo"; var pageSize = 25; + var startTime = DateTime.Parse("2022-01-01T00:00:00Z"); var continuationToken = "eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ=="; - var response = await fgaClient.ReadChanges(new ClientReadChangesRequest { Type = type }, new ClientReadChangesOptions { + var response = await fgaClient.ReadChanges(new ClientReadChangesRequest { Type = type, StartTime = startTime }, new ClientReadChangesOptions { PageSize = pageSize, ContinuationToken = continuationToken, }); diff --git a/src/OpenFga.Sdk/Api/OpenFgaApi.cs b/src/OpenFga.Sdk/Api/OpenFgaApi.cs index 4d66dbb..6875b5a 100644 --- a/src/OpenFga.Sdk/Api/OpenFgaApi.cs +++ b/src/OpenFga.Sdk/Api/OpenFgaApi.cs @@ -425,9 +425,10 @@ public async Task ReadAuthorizationModel(string /// (optional) /// (optional) /// (optional) + /// Start date and time of changes to read. Format: ISO 8601 timestamp (e.g., 2022-01-01T00:00:00Z) If a continuation_token is provided along side start_time, the continuation_token will take precedence over start_time. (optional) /// Cancellation Token to cancel the request. /// Task of ReadChangesResponse - public async Task ReadChanges(string storeId, string? type = default(string?), int? pageSize = default(int?), string? continuationToken = default(string?), CancellationToken cancellationToken = default) { + public async Task ReadChanges(string storeId, string? type = default(string?), int? pageSize = default(int?), string? continuationToken = default(string?), DateTime? startTime = default(DateTime?), CancellationToken cancellationToken = default) { var pathParams = new Dictionary { }; if (string.IsNullOrWhiteSpace(storeId)) { throw new FgaRequiredParamError("ReadChanges", "StoreId"); @@ -446,6 +447,9 @@ public async Task ReadAuthorizationModel(string if (continuationToken != null) { queryParams.Add("continuation_token", continuationToken.ToString()); } + if (startTime != null) { + queryParams.Add("start_time", startTime.ToString()); + } var requestBuilder = new RequestBuilder { Method = new HttpMethod("GET"), diff --git a/src/OpenFga.Sdk/Client/Client.cs b/src/OpenFga.Sdk/Client/Client.cs index 3e71470..6f7b3f2 100644 --- a/src/OpenFga.Sdk/Client/Client.cs +++ b/src/OpenFga.Sdk/Client/Client.cs @@ -164,9 +164,9 @@ public async Task ReadAuthorizationModel( * Read Changes - Read the list of historical relationship tuple writes and deletes */ public async Task ReadChanges(ClientReadChangesRequest? body = default, - IClientReadChangesOptions? options = default, + ClientReadChangesOptions? options = default, CancellationToken cancellationToken = default) => - await api.ReadChanges(GetStoreId(options), body?.Type, options?.PageSize, options?.ContinuationToken, cancellationToken); + await api.ReadChanges(GetStoreId(options), body?.Type, options?.PageSize, options?.ContinuationToken, body?.StartTime, cancellationToken); /** * Read - Read tuples previously written to the store (does not evaluate) diff --git a/src/OpenFga.Sdk/Client/Model/ClientReadChangesRequest.cs b/src/OpenFga.Sdk/Client/Model/ClientReadChangesRequest.cs index a154158..4ce84cf 100644 --- a/src/OpenFga.Sdk/Client/Model/ClientReadChangesRequest.cs +++ b/src/OpenFga.Sdk/Client/Model/ClientReadChangesRequest.cs @@ -18,11 +18,13 @@ namespace OpenFga.Sdk.Client.Model; public interface IClientReadChangesRequest { string Type { get; set; } + DateTime? StartTime { get; set; } } public class ClientReadChangesRequest : IClientReadChangesRequest, IEquatable, IValidatableObject { public string Type { get; set; } + public DateTime? StartTime { get; set; } public bool Equals(ClientReadChangesRequest input) { if (input == null) { diff --git a/src/OpenFga.Sdk/Model/ErrorCode.cs b/src/OpenFga.Sdk/Model/ErrorCode.cs index b5b6b3a..0d2318a 100644 --- a/src/OpenFga.Sdk/Model/ErrorCode.cs +++ b/src/OpenFga.Sdk/Model/ErrorCode.cs @@ -312,7 +312,13 @@ public enum ErrorCode { /// Enum Cancelled for value: cancelled /// [EnumMember(Value = "cancelled")] - Cancelled = 49 + Cancelled = 49, + + /// + /// Enum InvalidStartTime for value: invalid_start_time + /// + [EnumMember(Value = "invalid_start_time")] + InvalidStartTime = 50 }