Appearance
Configuration
GrydReports configuration is split into:
GrydReportsOptions(main module behavior)ReportStorageOptions(file storage provider)ReportDeliveryOptions(delivery defaults)ReportScheduleOptions(recurring scheduling guardrails)
Recommended Setup (Facade)
Use the facade for the standard stack (Application + Infrastructure + API):
csharp
builder.Services.AddGrydReports(
builder.Configuration,
db => db.UseNpgsql(builder.Configuration.GetConnectionString("GrydReports"))
);This automatically binds GrydReportsOptions from GrydReports section in appsettings.json.
Advanced Setup (Fine-Grained)
Use Infrastructure registration directly when you need explicit option callbacks:
csharp
builder.Services.AddGrydReportsApplication();
builder.Services.AddGrydReportsInfrastructure(
configureOptions: options =>
{
options.LocalStoragePath = "/data/reports";
options.RetentionDays = 90;
options.EnableAutoCleanup = true;
options.MaxSyncGenerationSize = 50 * 1024 * 1024; // 50 MB
options.SyncGenerationTimeout = TimeSpan.FromMinutes(2);
options.ForceAsyncAboveBytes = 10 * 1024 * 1024; // 10 MB
options.AutoRegisterTemplates = true;
options.TemplateAssemblies.Add(typeof(Program).Assembly);
options.Caching.Enabled = true;
options.Caching.DefaultExpiration = TimeSpan.FromHours(1);
options.Caching.TemplateExpirations["daily-sales"] = TimeSpan.FromMinutes(30);
options.DigitalSignature = new DigitalSignatureOptions
{
Enabled = true,
CertificatePath = "/certs/report-signing.pfx",
CertificatePassword = "secure-password",
Reason = "Official Document",
Location = "Sao Paulo, BR"
};
},
configureDbContext: db =>
db.UseNpgsql(builder.Configuration.GetConnectionString("GrydReports"))
);
builder.Services.AddGrydReportsApi();appsettings.json
GrydReports section is bound to GrydReportsOptions. ConnectionStrings:Jobs is only needed when you enable recurring scheduling with GrydJobs.
json
{
"ConnectionStrings": {
"GrydReports": "Host=localhost;Database=gryd_reports;Username=postgres;Password=postgres",
"Jobs": "Host=localhost;Port=5432;Database=gryd_jobs;Username=postgres;Password=postgres"
},
"GrydReports": {
"LocalStoragePath": "./reports-storage",
"RetentionDays": 90,
"EnableAutoCleanup": true,
"MaxSyncGenerationSize": 52428800,
"SyncGenerationTimeout": "00:02:00",
"ForceAsyncAboveBytes": 10485760,
"AutoRegisterTemplates": true,
"Caching": {
"Enabled": false,
"DefaultExpiration": "01:00:00",
"TemplateExpirations": {
"daily-sales": "00:30:00"
}
},
"DigitalSignature": {
"Enabled": false,
"CertificatePath": "",
"CertificatePassword": "",
"Reason": "Official Document",
"Location": ""
}
}
}Storage Configuration
Configure storage provider behavior:
csharp
builder.Services.ConfigureGrydReportsStorage(opts =>
{
opts.Provider = StorageProvider.LocalFileSystem;
opts.LocalBasePath = "/data/reports";
opts.PresignedUrlExpiration = TimeSpan.FromHours(1);
// Optional cloud providers
// opts.S3BucketName = "company-reports";
// opts.S3Region = "us-east-1";
// opts.S3Prefix = "reports";
// opts.AzureBlobConnectionString = "...";
// opts.AzureBlobContainerName = "reports";
});Custom Storage Provider
Implement IReportFileStore when you need custom persistence (S3, Azure Blob, etc):
csharp
public class S3ReportFileStore : IReportFileStore
{
// ... custom implementation for SaveAsync/GetAsync/DeleteAsync/etc
}
builder.Services.AddScoped<IReportFileStore, S3ReportFileStore>();Delivery Configuration
Configure default delivery constraints and message templates:
csharp
builder.Services.ConfigureGrydReportsDelivery(opts =>
{
opts.DefaultSenderEmail = "reports@company.com";
opts.DefaultSenderName = "Report System";
opts.DefaultEmailSubject = "Report: {ReportName} - {Date}";
opts.DefaultEmailBody = "Please find the attached report.";
opts.MaxRecipients = 50;
opts.WebhookTimeout = TimeSpan.FromSeconds(30);
opts.RetryCount = 3;
});Scheduling Configuration (Optional)
Recurring scheduling is optional and only applies when:
GrydReports.Scheduling.GrydJobspackage is installedbuilder.Services.AddGrydReportsScheduling()is registered
csharp
builder.Services.ConfigureGrydReportsScheduling(opts =>
{
// 0 = unlimited schedules per tenant
opts.MaxSchedulesPerTenant = 0;
opts.MaxConsecutiveFailures = 3;
opts.MinimumInterval = TimeSpan.FromHours(1);
opts.NotifyOnAutoPause = true;
});Per-Template Permissions
Configure RBAC per template through GrydReportsOptions:
csharp
builder.Services.Configure<GrydReportsOptions>(opts =>
{
opts.Permissions["financial-report"] = new ReportPermissions
{
Generate = ["admin", "finance-manager"],
View = ["admin", "finance-manager", "finance-analyst"],
Download = ["admin", "finance-manager"],
Schedule = ["admin"]
};
opts.Permissions["inventory-report"] = new ReportPermissions
{
Generate = ["admin", "warehouse-manager"],
View = ["admin", "warehouse-manager", "warehouse-staff"],
Download = ["admin", "warehouse-manager"],
Schedule = ["admin", "warehouse-manager"]
};
});Global Reports
Mark templates that do not require tenant scope filtering:
csharp
builder.Services.Configure<GrydReportsOptions>(opts =>
{
opts.GlobalReports.Add(typeof(SystemHealthTemplate));
opts.GlobalReports.Add(typeof(PlatformUsageTemplate));
});Health Checks
Register module health checks:
csharp
builder.Services.AddGrydReportsHealthChecks(builder.Configuration);This registers:
grydreports-database: PostgreSQL connectivitygrydreports-self: module self-check
Map endpoint:
csharp
app.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("grydreports")
});Option Reference
GrydReportsOptions
| Option | Type | Default | Description |
|---|---|---|---|
ConnectionString | string? | null | Report metadata connection string |
LocalStoragePath | string? | null | Local storage base path |
RetentionDays | int | 90 | Days to keep generated reports |
EnableAutoCleanup | bool | true | Enables automatic retention cleanup |
MaxSyncGenerationSize | long | 50 MB | Max file size for sync generation |
SyncGenerationTimeout | TimeSpan | 2 min | Timeout for sync generation |
ForceAsyncAboveBytes | long? | null | Forces async generation above threshold |
AutoRegisterTemplates | bool | true | Auto-discovers report templates |
Caching.Enabled | bool | false | Enables output caching |
Caching.DefaultExpiration | TimeSpan | 1 hour | Default cache TTL |
DigitalSignature.Enabled | bool | false | Enables PDF digital signing |
ReportStorageOptions
| Option | Type | Default | Description |
|---|---|---|---|
Provider | StorageProvider | LocalFileSystem | Active storage backend |
LocalBasePath | string? | null | Base path for local filesystem storage |
S3BucketName | string? | null | S3 bucket name |
S3Region | string? | null | S3 region |
S3Prefix | string? | null | S3 key prefix |
AzureBlobConnectionString | string? | null | Azure Blob connection string |
AzureBlobContainerName | string? | null | Azure Blob container |
PresignedUrlExpiration | TimeSpan | 1 hour | Download URL expiration |
ReportDeliveryOptions
| Option | Type | Default | Description |
|---|---|---|---|
DefaultSenderEmail | string? | null | Default sender email |
DefaultSenderName | string? | null | Default sender display name |
DefaultEmailSubject | string | Report: {ReportName} - {Date} | Subject template |
DefaultEmailBody | string | Please find the attached report. | Body template |
MaxRecipients | int | 50 | Max email recipients |
WebhookTimeout | TimeSpan | 30s | Webhook timeout |
RetryCount | int | 3 | Delivery retry attempts |
ReportScheduleOptions (optional scheduling)
| Option | Type | Default | Description |
|---|---|---|---|
MaxSchedulesPerTenant | int | 0 | Max active schedules per tenant (0 = unlimited) |
MaxConsecutiveFailures | int | 3 | Auto-pause threshold |
MinimumInterval | TimeSpan | 1 hour | Minimum allowed schedule interval |
NotifyOnAutoPause | bool | true | Notify when schedule auto-pauses |