45 lines
2.8 KiB
C#
45 lines
2.8 KiB
C#
using Dapper;
|
|
using FastEndpoints;
|
|
using Npgsql;
|
|
using Kbx.Shared.ExternalData.Generated;
|
|
using Kbx.Shared.Runtime;
|
|
|
|
namespace Kbx.Modules.Common.ExternalData.Status;
|
|
|
|
public sealed record Row(string DatasetId,string ProviderId,string SourceLabel,string State,long CacheEntries,DateTimeOffset? LastReceivedAt,DateTimeOffset? OldestFreshUntil,long StaleEntries,long UnavailableEntries);
|
|
public sealed record Response(IReadOnlyList<Row> Items);
|
|
file sealed record DbRow(string DatasetId,string ProviderId,string State,long CacheEntries,DateTimeOffset? LastReceivedAt,DateTimeOffset? OldestFreshUntil,long StaleEntries,long UnavailableEntries);
|
|
|
|
public sealed class Endpoint(NpgsqlDataSource dataSource):EndpointWithoutRequest<Response>
|
|
{
|
|
public override void Configure(){Get("/api/kbx/external-data/status");Permissions("common.external-data.read");}
|
|
public override async Task HandleAsync(CancellationToken ct)
|
|
{
|
|
const string sql="""
|
|
select dataset_id as DatasetId, provider_id as ProviderId,
|
|
case
|
|
when bool_or(fresh_until is not null and now() <= fresh_until) then 'fresh'
|
|
when bool_or(usable_until is not null and now() <= usable_until) then 'stale'
|
|
when bool_or(state='unavailable') then 'unavailable'
|
|
else 'expired'
|
|
end as State,
|
|
count(*) as CacheEntries,
|
|
max(received_at) as LastReceivedAt,
|
|
min(fresh_until) as OldestFreshUntil,
|
|
count(*) filter(where fresh_until is not null and now()>fresh_until and usable_until is not null and now()<=usable_until) as StaleEntries,
|
|
count(*) filter(where state='unavailable') as UnavailableEntries
|
|
from kbx.external_data_cache
|
|
where tenant_id=@TenantId
|
|
group by dataset_id,provider_id
|
|
""";
|
|
await using var connection=await dataSource.OpenConnectionAsync(ct);
|
|
var db=(await connection.QueryAsync<DbRow>(new CommandDefinition(sql,new{TenantId=RuntimeIdentity.TenantId(User)},cancellationToken:ct))).ToDictionary(x=>x.DatasetId,StringComparer.Ordinal);
|
|
var rows=KbxExternalDataCatalog.All.Values.OrderBy(x=>x.Id,StringComparer.Ordinal).Select(dataset=>{
|
|
if(db.TryGetValue(dataset.Id,out var current))return new Row(dataset.Id,dataset.ProviderId,dataset.SourceLabel,current.State,current.CacheEntries,current.LastReceivedAt,current.OldestFreshUntil,current.StaleEntries,current.UnavailableEntries);
|
|
var state=dataset.FreshnessMode=="provider-defined" && dataset.FreshForSeconds is null ? "unavailable" : "expired";
|
|
return new Row(dataset.Id,dataset.ProviderId,dataset.SourceLabel,state,0,null,null,0,state=="unavailable"?1:0);
|
|
}).ToArray();
|
|
await Send.OkAsync(new Response(rows),ct);
|
|
}
|
|
}
|