fix: resolve nullability warnings, add CI/CD and security workflows, harden .gitignore

- Add nullable annotations across discovery interfaces, dynamic query
  models, and filter/aggregate types to eliminate CS8600-series warnings
- Replace unsafe cast in DynamicQueryHandlerBase with pattern match
- Add CI workflow (build --warnaserror + test on JP branch)
- Add weekly security vulnerability scan workflow
- Extend .gitignore with secret/credential patterns (.env, *.key, secrets/, credentials.json)

Co-Authored-By: Svrnty Inc. <eng@svrnty.com>
This commit is contained in:
Svrnty
2026-02-27 19:28:24 -05:00
parent 92231df745
commit 5f3602d071
17 changed files with 113 additions and 47 deletions
@@ -22,7 +22,7 @@ public class DynamicQueryMeta(Type queryType, Type serviceType, Type queryResult
}
}
public Type ParamsType { get; internal set; }
public string OverridableName { get; internal set; }
public Type? ParamsType { get; internal set; }
public string? OverridableName { get; internal set; }
}
+11 -11
View File
@@ -18,9 +18,9 @@ public class DynamicQuery<TSource, TDestination, TParams> : DynamicQuery, IDynam
where TDestination : class
where TParams : class
{
public TParams Params { get; set; }
public TParams? Params { get; set; }
public TParams GetParams()
public TParams? GetParams()
{
return Params;
}
@@ -30,23 +30,23 @@ public class DynamicQuery : IDynamicQuery
{
public int? Page { get; set; }
public int? PageSize { get; set; }
public List<Sort> Sorts { get; set; }
public List<DynamicQueryAggregate> Aggregates { get; set; }
public List<Group> Groups { get; set; }
public List<DynamicQueryFilter> Filters { get; set; }
public List<Sort>? Sorts { get; set; }
public List<DynamicQueryAggregate>? Aggregates { get; set; }
public List<Group>? Groups { get; set; }
public List<DynamicQueryFilter>? Filters { get; set; }
public List<IAggregate> GetAggregates()
public List<IAggregate>? GetAggregates()
{
return Aggregates?.Select(t => t.ToAggregate())?.ToList();//.AsEnumerable<IAggregate>()?.ToList();
return Aggregates?.Select(t => t.ToAggregate())?.ToList();
}
public List<IFilter> GetFilters()
public List<IFilter>? GetFilters()
{
return Filters?.Select(t => t.ToFilter())?.ToList();
}
public List<IGroup> GetGroups()
public List<IGroup>? GetGroups()
{
return this.Groups?.AsEnumerable<IGroup>()?.ToList();
}
@@ -61,7 +61,7 @@ public class DynamicQuery : IDynamicQuery
return this.PageSize;
}
public List<ISort> GetSorts()
public List<ISort>? GetSorts()
{
return this.Sorts?.AsEnumerable<ISort>()?.ToList();
}
@@ -6,8 +6,8 @@ namespace Svrnty.CQRS.DynamicQuery;
public class DynamicQueryAggregate
{
public string Path { get; set; }
public string Type { get; set; }
public required string Path { get; set; }
public required string Type { get; set; }
public IAggregate ToAggregate()
{
@@ -9,14 +9,14 @@ namespace Svrnty.CQRS.DynamicQuery;
public class DynamicQueryFilter
{
public List<DynamicQueryFilter> Filters { get; set; }
public List<DynamicQueryFilter>? Filters { get; set; }
public bool? And { get; set; }
public string Type { get; set; }
public string? Type { get; set; }
public bool? Not { get; set; }
public string Path { get; set; }
public object Value { get; set; }
public string? Path { get; set; }
public object? Value { get; set; }
public string QueryValue
public string? QueryValue
{
get
{
@@ -32,7 +32,7 @@ public class DynamicQueryFilter
public IFilter ToFilter()
{
var type = Enum.Parse<FilterType>(Type);
var type = Enum.Parse<FilterType>(Type!);
if (type == FilterType.Composite)
{
var compositeFilter = new CompositeFilter
@@ -44,7 +44,7 @@ public class DynamicQueryFilter
return compositeFilter;
}
object value = Value;
object? value = Value;
if (Value is JsonElement jsonElement)
{
switch (jsonElement.ValueKind)
@@ -60,7 +60,10 @@ public abstract class DynamicQueryHandlerBase<TSource, TDestination>
{
var types = _dynamicQueryInterceptorProviders.SelectMany(t => t.GetInterceptorsTypes()).Distinct();
foreach (var type in types)
yield return _serviceProvider.GetService(type) as IQueryInterceptor;
{
if (_serviceProvider.GetService(type) is IQueryInterceptor interceptor)
yield return interceptor;
}
}
protected async Task<IQueryExecutionResult<TDestination>> ProcessQueryAsync(IDynamicQuery query,
@@ -26,11 +26,11 @@ public static class ServiceCollectionExtensions
return new DynamicQueryServicesBuilder(services);
}
public static IServiceCollection AddDynamicQuery<TSourceAndDestination>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQuery<TSourceAndDestination>(this IServiceCollection services, string? name = null)
where TSourceAndDestination : class
=> AddDynamicQuery<TSourceAndDestination, TSourceAndDestination>(services, name: name);
public static IServiceCollection AddDynamicQuery<TSource, TDestination>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQuery<TSource, TDestination>(this IServiceCollection services, string? name = null)
where TSource : class
where TDestination : class
{
@@ -51,7 +51,7 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddDynamicQueryWithProvider<TSource, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TQueryableProvider>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQueryWithProvider<TSource, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TQueryableProvider>(this IServiceCollection services, string? name = null)
where TQueryableProvider : class, IQueryableProvider<TSource>
where TSource : class
{
@@ -60,7 +60,7 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddDynamicQueryWithParamsAndProvider<TSource, TParams, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TQueryableProvider>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQueryWithParamsAndProvider<TSource, TParams, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TQueryableProvider>(this IServiceCollection services, string? name = null)
where TQueryableProvider : class, IQueryableProvider<TSource>
where TParams : class
where TSource : class
@@ -86,12 +86,12 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddDynamicQueryWithParams<TSourceAndDestination, TParams>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQueryWithParams<TSourceAndDestination, TParams>(this IServiceCollection services, string? name = null)
where TSourceAndDestination : class
where TParams : class
=> AddDynamicQueryWithParams<TSourceAndDestination, TSourceAndDestination, TParams>(services, name: name);
public static IServiceCollection AddDynamicQueryWithParams<TSource, TDestination, TParams>(this IServiceCollection services, string name = null)
public static IServiceCollection AddDynamicQueryWithParams<TSource, TDestination, TParams>(this IServiceCollection services, string? name = null)
where TSource : class
where TDestination : class
where TParams : class