feat: add account-scoped data synchronization

This commit is contained in:
2026-09-22 09:58:58 +08:00
parent ab9ff389f2
commit 72e040546a
37 changed files with 4252 additions and 159 deletions
@@ -166,6 +166,52 @@ public sealed class RemoteControlClient : IDisposable
return sent;
}
public Task<RemoteDataSyncStatus> GetDataSyncStatusAsync(
string accountId,
CancellationToken cancellationToken = default)
{
RemoteAgentOptions.ValidateIdentifier(accountId, "accountId", 200);
return SendAuthenticatedAsync<RemoteDataSyncStatus>(
HttpMethod.Get,
$"/v1/nodes/{Escape(_options.NodeId!)}/data/accounts/{Escape(accountId)}/sync-status",
null,
cancellationToken);
}
public async Task<RemoteDataBatchAck> SubmitDataBatchAsync(
ReportingConfig reportingConfig,
RemoteSyncBatch batch,
CancellationToken cancellationToken = default)
{
var filtered = RemoteDataBatchAuthorization.Filter(reportingConfig, batch, out var reason);
if (filtered is null)
return new RemoteDataBatchAck(false, false, batch.BatchId, 0, string.Empty, reason);
return await SendAuthenticatedAsync<RemoteDataBatchAck>(HttpMethod.Post, "/v1/data/batches", filtered,
cancellationToken, RemoteDataProtocol.MaxBatchBytes).ConfigureAwait(false);
}
public async Task<IReadOnlyList<RemoteSyncBatch>> FlushDataBatchesAsync(
RemoteDataBatchQueue queue,
ReportingConfig reportingConfig,
CancellationToken cancellationToken = default)
{
EnsureAuthenticated();
var confirmed = new List<RemoteSyncBatch>();
foreach (var batch in queue.Pending())
{
var filtered = RemoteDataBatchAuthorization.Filter(reportingConfig, batch, out _);
if (filtered is null)
{
queue.Drop(batch.BatchId);
continue;
}
var acknowledgement = await SubmitDataBatchAsync(reportingConfig, filtered, cancellationToken).ConfigureAwait(false);
if (acknowledgement.Accepted && queue.MarkConfirmed(acknowledgement))
confirmed.Add(filtered);
}
return confirmed;
}
public Task<RemoteTaskEnvelope> AcknowledgeCancellationAsync(
RemoteTaskEnvelope task,
RemoteTaskStatus status,