Lyo.Reporting.Postgres
1.0.1
dotnet add package Lyo.Reporting.Postgres --version 1.0.1
NuGet\Install-Package Lyo.Reporting.Postgres -Version 1.0.1
<PackageReference Include="Lyo.Reporting.Postgres" Version="1.0.1" />
<PackageVersion Include="Lyo.Reporting.Postgres" Version="1.0.1" />
<PackageReference Include="Lyo.Reporting.Postgres" />
paket add Lyo.Reporting.Postgres --version 1.0.1
#r "nuget: Lyo.Reporting.Postgres, 1.0.1"
#:package Lyo.Reporting.Postgres@1.0.1
#addin nuget:?package=Lyo.Reporting.Postgres&version=1.0.1
#tool nuget:?package=Lyo.Reporting.Postgres&version=1.0.1
Lyo.Reporting.Postgres
PostgreSQL schema (reporting), EF migrations, CSV/XLSX/JSON renderers, ReportService generation pipeline, and ReportRetentionService cleanup.
HTTP endpoints live in Lyo.Api.Reporting (BuildReportingGroup). This package is service + EF only.
Examples
Register with DI
services.AddLyoQueryServices();
services.AddLocalCache();
services.AddIOTempService();
services.AddPostgresReportingManagement(o => {
o.ConnectionString = cs;
o.EnableAutoMigrations = true;
o.MaxReportDataJsonBytes = 5_000_000;
o.MaxOutputFileBytes = 50_000_000;
o.AllowAdHocGeneration = true; // false = saved definitions only, no JSON overrides
o.MaxConcurrentGenerations = 4; // 0 = unlimited; saturation throws ReportBusyException (HTTP 503)
o.GenerationRetention = TimeSpan.FromDays(90); // null = retention cleanup disabled
});
services.AddReportingWebRenderer(); // optional HTML/PDF
services.AddReportDataProvider<MyProvider>();
services.AddReportingGenerationProfile("my-profile", p => p.DefaultFormat(ReportFormat.Csv));
services.AddReportingGenerationHooks(new ReportGenerationHooks {
AfterRenderAsync = async (ctx, ct) => {
var storage = ctx.Services.GetRequiredService<IFileStorageService>();
var saved = await storage.SaveFileAsync(
ctx.StagedFilePath!,
ctx.FileName,
pathPrefix: ctx.PathPrefix ?? ctx.Request.PathPrefix,
contentType: ctx.ContentType,
ct: ct);
ctx.OutputFileId = saved.Id;
},
// Called before a generation row is removed (retention cleanup or definition delete):
OnCleanupAsync = async (ctx, ct) => {
if (ctx.OutputFileId is Guid fileId) {
var storage = ctx.Services.GetRequiredService<IFileStorageService>();
await storage.DeleteFileAsync(fileId, ct: ct);
}
}
});
services.AddLyoApiReporting();
app.BuildReportingGroup(new ReportingApiOptions {
DefinitionAuth = EndpointAuth.RequireAuthenticatedUser(),
GenerationAuth = EndpointAuth.RequireAuthenticatedUser(),
GenerateAuth = EndpointAuth.RequireAuthorization("ReportingGenerate")
});
Run retention cleanup
// e.g. inside a scheduled job handler
var retention = scope.ServiceProvider.GetRequiredService<ReportRetentionService>();
var deleted = await retention.CleanupAsync(ct);
Design-time migrations
export REPORTING_CONNECTION_STRING="Host=localhost;Database=postgres;..."
dotnet ef migrations add YourMigration --project Integration/Reporting/Lyo.Reporting.Postgres
Rendering
ReportService resolves IEnumerable<IReportRenderer> from DI — it does not project-reference Lyo.Reporting.Web.
| Format | Package | Registration |
|---|---|---|
| CSV | this package | AddPostgresReportingManagement → CsvReportRenderer (first grid) |
| XLSX | this package | AddPostgresReportingManagement → XlsxReportRenderer (one worksheet per grid) |
| JSON | this package | AddPostgresReportingManagement → JsonReportRenderer (composition JSON verbatim) |
| HTML / PDF | Lyo.Reporting.Web |
host calls AddReportingWebRenderer() (+ AddWebRenderer) |
Optional host IReportDataProvider / ReportingGenerationProfile (keyed by definition GenerationProfileKey) supply domain data or pre-rendered files before render.
Hardening options
AllowAdHocGeneration(defaulttrue): whenfalse,GenerateAsyncrequires a savedReportDefinitionIdand rejectsReportDataJson/OverrideReportDataJsonpayloads. Reruns of stored snapshots remain allowed.MaxConcurrentGenerations(default0= unlimited): gates the provider + render section via a process-wideReportGenerationThrottle. When saturated, generate waits briefly then throwsReportBusyException(mapped to HTTP 503 by the API).GenerationRetention(defaultnull= disabled): age after which terminal generations are eligible forReportRetentionServicecleanup.- Input hygiene: request file names are sanitized (directory segments,
.., invalid/control characters stripped; length capped) andReportDataJsonmust parse as JSON — malformed payloads fail fast withReportValidationExceptionbefore a generation row is persisted. - Failure resilience:
Failedstatus is persisted withCancellationToken.None, so client disconnects can't strand generations inRunning.
Parameters
- Definition schema:
report_definition_parameter(Key, Type, default Value, Required, validation, EncryptedValue, Options JSON picker source) - Generation instance:
report_generation_parameter(Key, Type, Value, EncryptedValue) ReportService.GenerateAsyncmerges requestParametersover definition defaults, validates, persists generation rows, and passes typed params plus a synthesized Key→Value JSON map to providers/renderers for transition.AllowMultiplekeys serialize as JSON arrays in that map, so no value is lost.
Parameters — Validation semantics
- Values are validated against the declared
ReportParameterType(Guid,Int,Long,Decimal,Bool,DateTime,DateOnly,TimeOnly,Json,Regex,Xml);String/Enum/Unknownaccept any string (Enumis constrained viaAllowedValues). ValidationRegexruns with a 1-second match timeout and a 500-character pattern cap; a timeout or invalid pattern is reported as a validation error, never an unhandled exception (ReDoS-safe).- When generating from a definition, request parameter keys not declared on the definition are rejected with a clear error listing the unknown keys. Definition-less (ad-hoc) generates accept any keys.
- A required parameter is satisfied by either
ValueorEncryptedValue. - Validation failures throw
ReportValidationException, which the API maps to HTTP 400.
Rerun
ReportService.RerunAsync(generationId, createdBy) replays a past generation from its stored snapshot (composition JSON, format, file name, path prefix, parameters) into a new generation row. The saved definition is intentionally not re-read, so a since-changed or deactivated definition cannot alter the rerun.
Retention cleanup
ReportRetentionService.CleanupAsync batch-deletes terminal (Succeeded/Failed) generations older than GenerationRetention, oldest first, keeping in-flight (Pending/ Running) rows. Before each row is removed, ReportGenerationHooks.OnCleanupAsync runs so the host can delete the persisted output blob; a hook failure logs and retains that row. Emits the reporting.generation.cleaned metric. The service is registered by AddPostgresReportingManagement but not scheduled — hosts trigger it themselves, e.g. via Lyo.Scheduler or a Lyo.Job interval job:
Dependencies
Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).
Lyo.Api— (direct, lyo)Lyo.Audit— (direct, lyo)Lyo.Common— (direct, lyo)Lyo.Csv— (direct, lyo)Lyo.Exceptions— (direct, lyo)Lyo.IO.Temp— (direct, lyo)Lyo.Metrics— (direct, lyo)Lyo.Postgres— (direct, lyo)Lyo.Query.Models— (direct, lyo)Lyo.Reporting.Models— (direct, lyo)Lyo.Xlsx— (direct, lyo)Microsoft.EntityFrameworkCore10.0.5— (direct, microsoft)Microsoft.EntityFrameworkCore.Design10.0.5— (direct, microsoft)Microsoft.Extensions.Configuration.Binder10.0.5— (direct, microsoft)Lyo.Api.Models— (transitive, lyo)Lyo.Cache— (transitive, lyo)Lyo.Compression— (transitive, lyo)Lyo.Csv.Models— (transitive, lyo)Lyo.DataTable.Models— (transitive, lyo)Lyo.DateAndTime— (transitive, lyo)Lyo.Diagnostic— (transitive, lyo)Lyo.Diagnostic.AspNetCore— (transitive, lyo)Lyo.Diff— (transitive, lyo)Lyo.Encryption— (transitive, lyo)Lyo.EntityReference.Models— (transitive, lyo)Lyo.Formatter— (transitive, lyo)Lyo.Hashing— (transitive, lyo)Lyo.Health— (transitive, lyo)Lyo.KeyStore— (transitive, lyo)Lyo.PackageMetadata— (transitive, lyo)Lyo.Query— (transitive, lyo)Lyo.Result— (transitive, lyo)Lyo.Streams— (transitive, lyo)Lyo.Validation— (transitive, lyo)Lyo.Xlsx.Models— (transitive, lyo)BouncyCastle.Cryptography2.6.2— (transitive, third-party, netstandard2.0)ClosedXML0.105.0— (transitive, third-party)DocumentFormat.OpenXml3.1.1— (transitive, third-party)EasyCompressor2.1.0— (transitive, third-party)ExcelDataReader3.9.0— (transitive, third-party)ExcelDataReader.DataSet3.9.0— (transitive, third-party)Konscious.Security.Cryptography.Argon21.3.1— (transitive, third-party)Microsoft.AspNetCore.Authorization10.0.5— (transitive, microsoft)Microsoft.AspNetCore.Http.Abstractions2.*— (transitive, microsoft)Microsoft.AspNetCore.OpenApi10.0.5— (transitive, microsoft)Microsoft.Bcl.AsyncInterfaces10.0.5— (transitive, microsoft, netstandard2.0)Microsoft.EntityFrameworkCore.Analyzers10.0.5— (transitive, microsoft)Microsoft.EntityFrameworkCore.Relational10.0.5— (transitive, microsoft)Microsoft.Extensions.Caching.Memory10.0.5— (transitive, microsoft)Microsoft.Extensions.Configuration10.0.5— (transitive, microsoft)Microsoft.Extensions.DependencyInjection10.0.5— (transitive, microsoft)Microsoft.Extensions.DependencyInjection.Abstractions10.0.5— (transitive, microsoft, net10.0, netstandard2.0)Microsoft.Extensions.Hosting.Abstractions10.0.5— (transitive, microsoft)Microsoft.Extensions.Logging.Abstractions10.0.5— (transitive, microsoft)Microsoft.Extensions.Options10.0.5— (transitive, microsoft)Microsoft.Extensions.Options.ConfigurationExtensions10.0.5— (transitive, microsoft)Npgsql.EntityFrameworkCore.PostgreSQL10.0.3— (transitive, third-party)SmartFormat.NET3.6.1— (transitive, third-party)System.Buffers4.6.1— (transitive, microsoft, netstandard2.0)System.ComponentModel.Annotations5.0.0— (transitive, microsoft)System.IO.Hashing10.0.5— (transitive, microsoft, net10.0)System.Memory4.6.3— (transitive, microsoft, netstandard2.0)System.Text.Encoding.CodePages10.0.5— (transitive, microsoft)System.Text.Json10.0.5— (transitive, microsoft, netstandard2.0)System.Threading.Tasks.Extensions4.6.3— (transitive, microsoft, netstandard2.0)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Lyo.Api (>= 1.0.1)
- Lyo.Audit (>= 1.0.1)
- Lyo.Common (>= 1.0.1)
- Lyo.Csv (>= 1.0.1)
- Lyo.Exceptions (>= 1.0.1)
- Lyo.IO.Temp (>= 1.0.1)
- Lyo.Metrics (>= 1.0.1)
- Lyo.Postgres (>= 1.0.1)
- Lyo.Query.Models (>= 1.0.1)
- Lyo.Reporting.Models (>= 1.0.1)
- Lyo.Xlsx (>= 1.0.1)
- Microsoft.EntityFrameworkCore (>= 10.0.5)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Lyo.Reporting.Postgres:
| Package | Downloads |
|---|---|
|
Lyo.Api.Reporting
HTTP API surface for Lyo Reporting: authenticated definition CRUD, read-only generations, and Generate. |
GitHub repositories
This package is not used by any popular GitHub repositories.