diff --git a/.gitignore b/.gitignore index 3805c8a..62835eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,479 +1,3 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET -project.fragment.lock.json -artifacts/ - -# Tye -.tye/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.tlog -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# dotnet test code coverage results -coverage - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio 6 auto-generated project file (contains which files were open etc.) -*.vbp - -# Visual Studio 6 workspace and project file (working project files containing files to include in project) -*.dsw -*.dsp - -# Visual Studio 6 technical files -*.ncb -*.aps - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# Visual Studio History (VSHistory) files -.vshistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd - -# VS Code files for those working on multiple tools -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace - -# Local History for Visual Studio Code -.history/ - -# Windows Installer files from build outputs -*.cab -*.msi -*.msix -*.msm -*.msp - -# JetBrains Rider -*.sln.iml - -## -## Visual studio for Mac -## - - -# globs -Makefile.in -*.userprefs -*.usertasks -config.make -config.status -aclocal.m4 -install-sh -autom4te.cache/ -*.tar.gz -tarballs/ -test-results/ - -# Mac bundle stuff -*.dmg -*.app - -# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk +logs/ +bin/ +obj/ diff --git a/Dockerfile b/Dockerfile index 7eca9ca..37f94c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,73 @@ -# - Stage 1 -------------------------------------------------------------------- +# ------------------------------------------------------------------------------ +# Stage 1: Builder +# This stage builds the application and its dependencies. +# ------------------------------------------------------------------------------ +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder - FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build - WORKDIR /src +WORKDIR /src - # Copy and restore dependencies - COPY src/Dotnet.Samples.AspNetCore.WebApi/*.csproj ./Dotnet.Samples.AspNetCore.WebApi/ - RUN dotnet restore ./Dotnet.Samples.AspNetCore.WebApi +# Restore dependencies +COPY src/Dotnet.Samples.AspNetCore.WebApi/*.csproj ./Dotnet.Samples.AspNetCore.WebApi/ +RUN dotnet restore ./Dotnet.Samples.AspNetCore.WebApi - # Copy source and publish - COPY src/Dotnet.Samples.AspNetCore.WebApi ./Dotnet.Samples.AspNetCore.WebApi - WORKDIR /src/Dotnet.Samples.AspNetCore.WebApi - RUN dotnet publish -c Release -o /app/publish +# Copy source code and pre-seeded SQLite database +COPY src/Dotnet.Samples.AspNetCore.WebApi ./Dotnet.Samples.AspNetCore.WebApi -# - Stage 2 -------------------------------------------------------------------- +WORKDIR /src/Dotnet.Samples.AspNetCore.WebApi - FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime - WORKDIR /app +# Build solution and publish release +RUN dotnet publish -c Release -o /app/publish - # Copy published output - # Note: This includes the SQLite database because it's marked as with - # in the .csproj file. No need to copy it manually. - COPY --from=build /app/publish . +# ------------------------------------------------------------------------------ +# Stage 2: Runtime +# This stage creates the final, minimal image to run the application. +# ------------------------------------------------------------------------------ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime - # Add non-root user (aspnetcore) for security hardening - RUN adduser --disabled-password --gecos '' aspnetcore \ - && chown -R aspnetcore:aspnetcore /app - USER aspnetcore +WORKDIR /app - # Set environment variables - ENV ASPNETCORE_URLS=http://+:9000 - ENV ASPNETCORE_ENVIRONMENT=Production +# Install curl for health check +RUN apt-get update && apt-get install -y --no-install-recommends curl && \ + rm -rf /var/lib/apt/lists/* - # Default entrypoint - ENTRYPOINT ["dotnet", "Dotnet.Samples.AspNetCore.WebApi.dll"] +# Metadata labels for the image. These are useful for registries and inspection. +LABEL org.opencontainers.image.title="๐Ÿงช Web API made with .NET 8 (LTS) and ASP.NET Core" +LABEL org.opencontainers.image.description="Proof of Concept for a Web API made with .NET 8 (LTS) and ASP.NET Core" +LABEL org.opencontainers.image.licenses="MIT" +LABEL org.opencontainers.image.source="https://github.com/nanotaboada/Dotnet.Samples.AspNetCore.WebApi" + +# Set environment variables +ENV ASPNETCORE_URLS=http://+:9000 +ENV ASPNETCORE_ENVIRONMENT=Production + +# Copy published app from builder +COPY --from=builder /app/publish . + +# Copy metadata docs for container registries (e.g.: GitHub Container Registry) +COPY --chmod=444 README.md ./ +COPY --chmod=555 assets ./assets + +# https://rules.sonarsource.com/docker/RSPEC-6504/ + +# Copy entrypoint and healthcheck scripts +COPY --chmod=555 scripts/entrypoint.sh ./entrypoint.sh +COPY --chmod=555 scripts/healthcheck.sh ./healthcheck.sh + + +# Copy pre-seeded SQLite database as init bundle +COPY --from=builder /src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db ./docker-compose/players-sqlite3.db + +# Create non-root user and make volume mount point writable +RUN adduser --disabled-password --gecos '' aspnetcore && \ + mkdir -p /storage && \ + chown -R aspnetcore:aspnetcore /storage + +USER aspnetcore + +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ + CMD ["./healthcheck.sh"] + +EXPOSE 9000 + +ENTRYPOINT ["./entrypoint.sh"] +CMD ["dotnet", "Dotnet.Samples.AspNetCore.WebApi.dll"] diff --git a/README.md b/README.md index e129022..f4470a3 100644 --- a/README.md +++ b/README.md @@ -36,20 +36,39 @@ https://localhost:9000/swagger/index.html ## Container -This project includes a multi-stage `Dockerfile` for local development and production builds. +### Docker Compose -### Build the image +This setup uses [Docker Compose](https://docs.docker.com/compose/) to build and run the app and manage a persistent SQLite database stored in a Docker volume. + +#### Build the image + +```bash +docker compose build +``` + +#### Start the app ```bash -docker build -t aspnetcore-app . +docker compose up ``` -### Run the container +> On first run, the container copies a pre-seeded SQLite database into a persistent volume +> On subsequent runs, that volume is reused and the data is preserved + +#### Stop the app ```bash -docker run -p 9000:9000 aspnetcore-app +docker compose down ``` +#### Optional: database reset + +```bash +docker compose down -v +``` + +> This removes the volume and will reinitialize the database from the built-in seed file the next time you `up`. + ## Credits The solution has been coded using [Visual Studio Code](https://code.visualstudio.com/) with the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) extension. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6eabc7a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +services: + api: + image: dotnet-samples-aspnetcore-webapi + container_name: aspnetcore-app + build: + context: . + dockerfile: Dockerfile + ports: + - "9000:9000" + volumes: + - storage:/storage/ + environment: + - STORAGE_PATH=/storage/players-sqlite3.db + restart: unless-stopped + +volumes: + storage: diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100644 index 0000000..4f0d58d --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +IMAGE_STORAGE_PATH="/app/docker-compose/players-sqlite3.db" +VOLUME_STORAGE_PATH="/storage/players-sqlite3.db" + +echo "โœ” Starting container..." + +if [ ! -f "$VOLUME_STORAGE_PATH" ]; then + echo "โš ๏ธ No existing database file found in volume." + if [ -f "$IMAGE_STORAGE_PATH" ]; then + echo "๐Ÿ”„ Copying database file to writable volume..." + cp "$IMAGE_STORAGE_PATH" "$VOLUME_STORAGE_PATH" + echo "โœ” Database initialized at $VOLUME_STORAGE_PATH" + else + echo "โš ๏ธ Database file missing at $IMAGE_STORAGE_PATH" + exit 1 + fi +else + echo "โœ” Existing database file found. Skipping seed copy." +fi + +echo "โœ” Ready!" +echo "๐Ÿš€ Launching app..." +exec "$@" diff --git a/scripts/healthcheck.sh b/scripts/healthcheck.sh new file mode 100644 index 0000000..9f5a04b --- /dev/null +++ b/scripts/healthcheck.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e + +# Simple health check using curl +curl --fail http://localhost:9000/health diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Dotnet.Samples.AspNetCore.WebApi.csproj b/src/Dotnet.Samples.AspNetCore.WebApi/Dotnet.Samples.AspNetCore.WebApi.csproj index 4f65b3e..77cd3ef 100644 --- a/src/Dotnet.Samples.AspNetCore.WebApi/Dotnet.Samples.AspNetCore.WebApi.csproj +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Dotnet.Samples.AspNetCore.WebApi.csproj @@ -28,7 +28,7 @@ - + PreserveNewest true diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Program.cs b/src/Dotnet.Samples.AspNetCore.WebApi/Program.cs index d3bffcb..cc43933 100644 --- a/src/Dotnet.Samples.AspNetCore.WebApi/Program.cs +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Program.cs @@ -36,8 +36,10 @@ /* Entity Framework Core ---------------------------------------------------- */ builder.Services.AddDbContextPool(options => { - var dataSource = Path.Combine(AppContext.BaseDirectory, "Data", "players-sqlite3.db"); + var dataSource = Path.Combine(AppContext.BaseDirectory, "storage", "players-sqlite3.db"); + options.UseSqlite($"Data Source={dataSource}"); + if (builder.Environment.IsDevelopment()) { options.EnableSensitiveDataLogging(); @@ -48,6 +50,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddMemoryCache(); +builder.Services.AddHealthChecks(); /* AutoMapper --------------------------------------------------------------- */ builder.Services.AddAutoMapper(typeof(PlayerMappingProfile)); @@ -91,4 +94,7 @@ // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing#endpoints app.MapControllers(); +// https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks +app.MapHealthChecks("/health"); + await app.RunAsync(); diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Data/players-sqlite3.db b/src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db similarity index 100% rename from src/Dotnet.Samples.AspNetCore.WebApi/Data/players-sqlite3.db rename to src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db diff --git a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/packages.lock.json b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/packages.lock.json index 6bb560a..f602d62 100644 --- a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/packages.lock.json +++ b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/packages.lock.json @@ -546,8 +546,8 @@ }, "Microsoft.AspNetCore.OpenApi": { "type": "Transitive", - "resolved": "8.0.15", - "contentHash": "Nu/I5tek+FbumgyrfNAxcPZd8uQi6VTYfZ+6Wr/JYrHFM6zb6DJx99v5QjMnsf9ePHkUto0zvUFVaA2gpiV9mQ==", + "resolved": "8.0.16", + "contentHash": "jeZBYi62BKGRZXEkXAr9hj1L6u71HRKE7EPaZBouF1xmKdQIX7GO5oSRLTQLQmmST0y/aaI+Mr4OzyyRjmBFog==", "dependencies": { "Microsoft.OpenApi": "1.4.3" } @@ -726,8 +726,8 @@ }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "rnVGier1R0w9YEAzxOlUl8koFwq4QLwuYKiJN6NFqbCNCPrRLGW3f7x0OtL/Sp1KBMVhgffUIP6jWPppzhpa2Q==", + "resolved": "9.0.5", + "contentHash": "cP5eBSqra4Ae80X72g0h2N+jdrA4BgoMQmz9JaQmKAEXUHw9N21DPIBqIyMjOo2fK9ISiGytlAOxBAJf1hEvqg==", "dependencies": { "SQLitePCLRaw.core": "2.1.10" } @@ -760,88 +760,88 @@ }, "Microsoft.EntityFrameworkCore": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "+5IAX0aicQYCRfN4pAjad+JPwdEYoVEM3Z1Cl8/EiEv3FVHQHdd8TJQpQIslQDDQS/UsUMb0MsOXwqOh+TJtRw==", + "resolved": "9.0.5", + "contentHash": "TeCtb/vc+jxvgkVAqeJlZKOoG5w/w8AigWQQyOmeJsJ7+0SkONX8bqEV/wB+ojnT0sXuJrrfXQOEC3ws6asEng==", "dependencies": { - "Microsoft.EntityFrameworkCore.Abstractions": "9.0.4", - "Microsoft.EntityFrameworkCore.Analyzers": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.EntityFrameworkCore.Abstractions": "9.0.5", + "Microsoft.EntityFrameworkCore.Analyzers": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5" } }, "Microsoft.EntityFrameworkCore.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "E0pkWzI0liqu2ogqJ1kohk2eGkYRhf5tI75HGF6IQDARsshY/0w+prGyLvNuUeV7B8I7vYQZ4CzAKYKxw7b9gQ==" + "resolved": "9.0.5", + "contentHash": "81fGyIibhGc4rq4ZxmVZE/1CFSvGMQOZqdRyCBLKz/Hb8eE973dmSfcdXpXhQ/5f+nbax4VGkWhwPGxWUNWaCQ==" }, "Microsoft.EntityFrameworkCore.Analyzers": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "cMsm1O7g9X5qbB2wjHf3BVVvGwkG+zeXQ+M91I1Bm6RfylFMImqBPzs0+vmuef7fPxr2yOzPhIfJ2wQJfmtaSw==" + "resolved": "9.0.5", + "contentHash": "kWRrD69qCXo7lahPZPt7C127UfK0I024laFZEDMfT3JbALB1EWneFvq1utWM0cNKPFuYis1E1oaYTuRGI/9inQ==" }, "Microsoft.EntityFrameworkCore.InMemory": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "VHjUwjvN8UKjb8xtKJ/o+dc9tTeHOW3QzlfkzX3JrUspLkPIjwMdZCcw6eS4gsFjby0NFkcXBjHtrgTjVOfO5Q==", + "resolved": "9.0.5", + "contentHash": "+nC0uyM5ztN3rV7yUraTlQhXZMV98MP1ZEn4OLlz4c0l5bOGbvHIcvsHA5RitzJTsP5UX/rwfpc3aOsTBS02jA==", "dependencies": { - "Microsoft.EntityFrameworkCore": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.EntityFrameworkCore": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5" } }, "Microsoft.EntityFrameworkCore.Relational": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "OjJ+xh/wQff5b0wiC3SPvoQqTA2boZeJQf+15+3+OJPtjBKzvxuwr25QRIu1p1t+K8ryQ8pzaoZ7eOpXfNzVGA==", + "resolved": "9.0.5", + "contentHash": "6eErbrZFd9yNnncemtDdmHZ3KC792OQCIYITuMsjK2oh4CLzlYo8mzNsozgUzQ+utHnne11/3eV8zMWbYF5Puw==", "dependencies": { - "Microsoft.EntityFrameworkCore": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4" + "Microsoft.EntityFrameworkCore": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5" } }, "Microsoft.EntityFrameworkCore.Sqlite": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "YruNASPuiCjLOVxO09lpQT4e2OYvpsoD0e5NGEQKOcPCu143RDzWTNlpzcxhArBgAS0FPwQ+OEGZOWhwgWHvOA==", + "resolved": "9.0.5", + "contentHash": "dy9e3TUiU9COlFTyut6e12bZALM25PDskd6Kk10gbS3rAPYsuaKTkgq3mHDIQOR2bb3WEX7cdNpNF1+r2BIBMg==", "dependencies": { - "Microsoft.EntityFrameworkCore.Sqlite.Core": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.DependencyModel": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", + "Microsoft.EntityFrameworkCore.Sqlite.Core": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.DependencyModel": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5", "SQLitePCLRaw.bundle_e_sqlite3": "2.1.10", "SQLitePCLRaw.core": "2.1.10", - "System.Text.Json": "9.0.4" + "System.Text.Json": "9.0.5" } }, "Microsoft.EntityFrameworkCore.Sqlite.Core": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "96NFbmjcZsO9HkSdWAwh5tn/7LKIu7cLW+zubyGV1BR1w8xpcqPXZcTW4S/0eA0d9BxyFnH8tSDRjUerWGoU/Q==", + "resolved": "9.0.5", + "contentHash": "YU11QeQz53xKvr9hV9XABU9nwMMPOJFYuLB5bWgPMoE73ibiprksFzpnWhifRQu0c35jwVTj7kxHIAi/800CXA==", "dependencies": { - "Microsoft.Data.Sqlite.Core": "9.0.4", - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.DependencyModel": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", + "Microsoft.Data.Sqlite.Core": "9.0.5", + "Microsoft.EntityFrameworkCore.Relational": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.DependencyModel": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5", "SQLitePCLRaw.core": "2.1.10", - "System.Text.Json": "9.0.4" + "System.Text.Json": "9.0.5" } }, "Microsoft.EntityFrameworkCore.SqlServer": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "UCo6rRUIx2Rhl6xVkMPf1yL/97jcYkwrryOKB5e68YCZ7NdQyk+7wfXJzEDvkFcjTw45H5sy4/1vW6vXCs/Kag==", + "resolved": "9.0.5", + "contentHash": "Y4194uyqwMivN2ioKd7GYBFVeeG2kZFFC1ZCmOTvXy3G6Wd05ZVyUyR/3mB+SHCequMPt/DI4f58WMmVaOS6eg==", "dependencies": { "Microsoft.Data.SqlClient": "5.1.6", - "Microsoft.EntityFrameworkCore.Relational": "9.0.4", - "Microsoft.Extensions.Caching.Memory": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.Logging": "9.0.4", - "System.Formats.Asn1": "9.0.4", - "System.Text.Json": "9.0.4" + "Microsoft.EntityFrameworkCore.Relational": "9.0.5", + "Microsoft.Extensions.Caching.Memory": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.Logging": "9.0.5", + "System.Formats.Asn1": "9.0.5", + "System.Text.Json": "9.0.5" } }, "Microsoft.Extensions.ApiDescription.Server": { @@ -851,39 +851,39 @@ }, "Microsoft.Extensions.Caching.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "imcZ5BGhBw5mNsWLepBbqqumWaFe0GtvyCvne2/2wsDIBRa2+Lhx4cU/pKt/4BwOizzUEOls2k1eOJQXHGMalg==", + "resolved": "9.0.5", + "contentHash": "RV6wOTvH5BeVRs6cvxFuaV1ut05Dklpvq19XRO1JxAayfLWYIEP7K94aamY0iSUhoehWk1X5H6gMcbZkHuBjew==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Caching.Memory": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "G5rEq1Qez5VJDTEyRsRUnewAspKjaY57VGsdZ8g8Ja6sXXzoiI3PpTd1t43HjHqNWD5A06MQveb2lscn+2CU+w==", + "resolved": "9.0.5", + "contentHash": "qDmoAzIUBup5KZG1Abv51ifbHMCWFnaXbt05l+Sd92mLOpF9OwHOuoxu3XhzXaPGfq0Ns3pv1df5l8zuKjFgGw==", "dependencies": { - "Microsoft.Extensions.Caching.Abstractions": "9.0.4", - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4", - "Microsoft.Extensions.Logging.Abstractions": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Caching.Abstractions": "9.0.5", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.5", + "Microsoft.Extensions.Logging.Abstractions": "9.0.5", + "Microsoft.Extensions.Options": "9.0.5", + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Configuration": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "KIVBrMbItnCJDd1RF4KEaE8jZwDJcDUJW5zXpbwQ05HNYTK1GveHxHK0B3SjgDJuR48GRACXAO+BLhL8h34S7g==", + "resolved": "9.0.5", + "contentHash": "uYXLg2Gt8KUH5nT3u+TBpg9VrRcN5+2zPmIjqEHR4kOoBwsbtMDncEJw9HiLvZqGgIo2TR4oraibAoy5hXn2bQ==", "dependencies": { - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Configuration.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0LN/DiIKvBrkqp7gkF3qhGIeZk6/B63PthAHjQsxymJfIBcz0kbf4/p/t4lMgggVxZ+flRi5xvTwlpPOoZk8fg==", + "resolved": "9.0.5", + "contentHash": "ew0G6gIznnyAkbIa67wXspkDFcVektjN3xaDAfBDIPbWph+rbuGaaohFxUSGw28ht7wdcWtTtElKnzfkcDDbOQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Configuration.Binder": { @@ -896,48 +896,48 @@ }, "Microsoft.Extensions.Configuration.FileExtensions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "UY864WQ3AS2Fkc8fYLombWnjrXwYt+BEHHps0hY4sxlgqaVW06AxbpgRZjfYf8PyRbplJqruzZDB/nSLT+7RLQ==", + "resolved": "9.0.5", + "contentHash": "ifrA7POOJ7EeoEJhC8r03WufBsEV4zgnTLQURHh1QIS/vU6ff/60z8M4tD3i2csdFPREEc1nGbiOZhi7Q5aMfw==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.4", - "Microsoft.Extensions.FileProviders.Physical": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Configuration": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.5", + "Microsoft.Extensions.FileProviders.Physical": "9.0.5", + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Configuration.Json": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "vVXI70CgT/dmXV3MM+n/BR2rLXEoAyoK0hQT+8MrbCMuJBiLRxnTtSrksNiASWCwOtxo/Tyy7CO8AGthbsYxnw==", + "resolved": "9.0.5", + "contentHash": "LiWV+Sn5yvoQEd/vihGwkR3CZ4ekMrqP5OQiYOlbzMBfBa6JHBWBsTO5ta6dMYO9ADMiv9K6GBKJSF9DrP29sw==", "dependencies": { - "Microsoft.Extensions.Configuration": "9.0.4", - "Microsoft.Extensions.Configuration.Abstractions": "9.0.4", - "Microsoft.Extensions.Configuration.FileExtensions": "9.0.4", - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.4", - "System.Text.Json": "9.0.4" + "Microsoft.Extensions.Configuration": "9.0.5", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.5", + "Microsoft.Extensions.Configuration.FileExtensions": "9.0.5", + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.5", + "System.Text.Json": "9.0.5" } }, "Microsoft.Extensions.DependencyInjection": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "f2MTUaS2EQ3lX4325ytPAISZqgBfXmY0WvgD80ji6Z20AoDNiCESxsqo6mFRwHJD/jfVKRw9FsW6+86gNre3ug==", + "resolved": "9.0.5", + "contentHash": "N1Mn0T/tUBPoLL+Fzsp+VCEtneUhhxc1//Dx3BeuQ8AX+XrMlYCfnp2zgpEXnTCB7053CLdiqVWPZ7mEX6MPjg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.5" } }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "UI0TQPVkS78bFdjkTodmkH0Fe8lXv9LnhGFKgKrsgUJ5a5FVdFRcgjIkBVLbGgdRhxWirxH/8IXUtEyYJx6GQg==" + "resolved": "9.0.5", + "contentHash": "cjnRtsEAzU73aN6W7vkWy8Phj5t3Xm78HSqgrbh/O4Q9SK/yN73wZVa21QQY6amSLQRQ/M8N+koGnY6PuvKQsw==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "ACtnvl3H3M/f8Z42980JxsNu7V9PPbzys4vBs83ZewnsgKd7JeYK18OMPo0g+MxAHrpgMrjmlinXDiaSRPcVnA==", + "resolved": "9.0.5", + "contentHash": "+jdJ9Vz+5Ia21l3KjahtmeHCIgQ7urfkdcJPxSfeqB40Jqryi27Lt4fKBmKyvc0YrfTUJ0cEB7QmoQRlU8FH0g==", "dependencies": { - "System.Text.Encodings.Web": "9.0.4", - "System.Text.Json": "9.0.4" + "System.Text.Encodings.Web": "9.0.5", + "System.Text.Json": "9.0.5" } }, "Microsoft.Extensions.Diagnostics.Abstractions": { @@ -952,26 +952,26 @@ }, "Microsoft.Extensions.FileProviders.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "gQN2o/KnBfVk6Bd71E2YsvO5lsqrqHmaepDGk+FB/C4aiQY9B0XKKNKfl5/TqcNOs9OEithm4opiMHAErMFyEw==", + "resolved": "9.0.5", + "contentHash": "LLm+e8lvD+jOI+blHRSxPqywPaohOTNcVzQv548R1UpkEiNB2D+zf3RrqxBdB1LDPicRMTnfiaKJovxF8oX1bQ==", "dependencies": { - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.FileProviders.Physical": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "qkQ9V7KFZdTWNThT7ke7E/Jad38s46atSs3QUYZB8f3thBTrcrousdY4Y/tyCtcH5YjsPSiByjuN+L8W/ThMQg==", + "resolved": "9.0.5", + "contentHash": "cMQqvK0rclKzAm2crSFe9JiimR+wzt6eaoRxa8/mYFkqekY4JEP8eShVZs4NPsKV2HQFHfDgwfFSsWUrUgqbKA==", "dependencies": { - "Microsoft.Extensions.FileProviders.Abstractions": "9.0.4", - "Microsoft.Extensions.FileSystemGlobbing": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.FileProviders.Abstractions": "9.0.5", + "Microsoft.Extensions.FileSystemGlobbing": "9.0.5", + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.FileSystemGlobbing": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "05Lh2ItSk4mzTdDWATW9nEcSybwprN8Tz42Fs5B+jwdXUpauktdAQUI1Am4sUQi2C63E5hvQp8gXvfwfg9mQGQ==" + "resolved": "9.0.5", + "contentHash": "TWJZJGIyUncH4Ah+Sy9X5mPJeoz02lRlFx9VWaFo4b4o0tkA1dk2u6HRHrfEC2L6N4IC+vFzfRWol1egyQqLtg==" }, "Microsoft.Extensions.Hosting.Abstractions": { "type": "Transitive", @@ -987,36 +987,36 @@ }, "Microsoft.Extensions.Logging": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "xW6QPYsqhbuWBO9/1oA43g/XPKbohJx+7G8FLQgQXIriYvY7s+gxr2wjQJfRoPO900dvvv2vVH7wZovG+M1m6w==", + "resolved": "9.0.5", + "contentHash": "rQU61lrgvpE/UgcAd4E56HPxUIkX/VUQCxWmwDTLLVeuwRDYTL0q/FLGfAW17cGTKyCh7ywYAEnY3sTEvURsfg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection": "9.0.4", - "Microsoft.Extensions.Logging.Abstractions": "9.0.4", - "Microsoft.Extensions.Options": "9.0.4" + "Microsoft.Extensions.DependencyInjection": "9.0.5", + "Microsoft.Extensions.Logging.Abstractions": "9.0.5", + "Microsoft.Extensions.Options": "9.0.5" } }, "Microsoft.Extensions.Logging.Abstractions": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "0MXlimU4Dud6t+iNi5NEz3dO2w1HXdhoOLaYFuLPCjAsvlPQGwOT6V2KZRMLEhCAm/stSZt1AUv0XmDdkjvtbw==", + "resolved": "9.0.5", + "contentHash": "pP1PADCrIxMYJXxFmTVbAgEU7GVpjK5i0/tyfU9DiE0oXQy3JWQaOVgCkrCiePLgS8b5sghM3Fau3EeHiVWbCg==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4", - "System.Diagnostics.DiagnosticSource": "9.0.4" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.5", + "System.Diagnostics.DiagnosticSource": "9.0.5" } }, "Microsoft.Extensions.Options": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "fiFI2+58kicqVZyt/6obqoFwHiab7LC4FkQ3mmiBJ28Yy4fAvy2+v9MRnSvvlOO8chTOjKsdafFl/K9veCPo5g==", + "resolved": "9.0.5", + "contentHash": "vPdJQU8YLOUSSK8NL0RmwcXJr2E0w8xH559PGQl4JYsglgilZr9LZnqV2zdgk+XR05+kuvhBEZKoDVd46o7NqA==", "dependencies": { - "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.4", - "Microsoft.Extensions.Primitives": "9.0.4" + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.5", + "Microsoft.Extensions.Primitives": "9.0.5" } }, "Microsoft.Extensions.Primitives": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "SPFyMjyku1nqTFFJ928JAMd0QnRe4xjE7KeKnZMWXf3xk+6e0WiOZAluYtLdbJUXtsl2cCRSi8cBquJ408k8RA==" + "resolved": "9.0.5", + "contentHash": "b4OAv1qE1C9aM+ShWJu3rlo/WjDwa/I30aIPXqDWSKXTtKl1Wwh6BZn+glH5HndGVVn3C6ZAPQj5nv7/7HJNBQ==" }, "Microsoft.Identity.Client": { "type": "Transitive", @@ -1624,8 +1624,8 @@ }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "Be0emq8bRmcK4eeJIFUt9+vYPf7kzuQrFs8Ef1CdGvXpq/uSve22PTSkRF09bF/J7wmYJ2DHf2v7GaT3vMXnwQ==" + "resolved": "9.0.5", + "contentHash": "WoI5or8kY2VxFdDmsaRZ5yaYvvb+4MCyy66eXo79Cy1uMa7qXeGIlYmZx7R9Zy5S4xZjmqvkk2V8L6/vDwAAEA==" }, "System.Diagnostics.EventLog": { "type": "Transitive", @@ -1634,8 +1634,8 @@ }, "System.Formats.Asn1": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "WklXbMuiSM9X7UyM6t9UzNnMGGO9RV3OTtLjR++mvR4fcrMnuPPH3ui+BKVe2RhmDC3Z7ytWJCl+j8KOqKsVzw==" + "resolved": "9.0.5", + "contentHash": "GpMHKhuwUgnp1jKiZQ1slyAQnLp4HG2MgzCJ4u4oZEfi6aBzE3HOx01JFStaiC8dtJqsv0WlrGAWVixv8TEN1w==" }, "System.IdentityModel.Tokens.Jwt": { "type": "Transitive", @@ -1648,8 +1648,8 @@ }, "System.IO.Pipelines": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "luF2Xba+lTe2GOoNQdZLe8q7K6s7nSpWZl9jIwWNMszN4/Yv0lmxk9HISgMmwdyZ83i3UhAGXaSY9o6IJBUuuA==" + "resolved": "9.0.5", + "contentHash": "5WXo+3MGcnYn54+1ojf+kRzKq1Q6sDUnovujNJ2ky1nl1/kP3+PMil9LPbFvZ2mkhvAGmQcY07G2sfHat/v0Fw==" }, "System.Memory": { "type": "Transitive", @@ -1755,16 +1755,16 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "V+5cCPpk1S2ngekUs9nDrQLHGiWFZMg8BthADQr+Fwi59a8DdHFu26S2oi9Bfgv+d67bqmkPqctJXMEXiimXUg==" + "resolved": "9.0.5", + "contentHash": "HJPmqP2FsE+WVUUlTsZ4IFRSyzw40yz0ubiTnsaqm+Xo5fFZhVRvx6Zn8tLXj92/6pbre6OA4QL2A2vnCSKxJA==" }, "System.Text.Json": { "type": "Transitive", - "resolved": "9.0.4", - "contentHash": "pYtmpcO6R3Ef1XilZEHgXP2xBPVORbYEzRP7dl0IAAbN8Dm+kfwio8aCKle97rAWXOExr292MuxWYurIuwN62g==", + "resolved": "9.0.5", + "contentHash": "rnP61ZfloTgPQPe7ecr36loNiGX3g1PocxlKHdY/FUpDSsExKkTxpMAlB4X35wNEPr1X7mkYZuQvW3Lhxmu7KA==", "dependencies": { - "System.IO.Pipelines": "9.0.4", - "System.Text.Encodings.Web": "9.0.4" + "System.IO.Pipelines": "9.0.5", + "System.Text.Encodings.Web": "9.0.5" } }, "System.Threading.Channels": { @@ -1827,11 +1827,11 @@ "dependencies": { "AutoMapper": "[14.0.0, )", "FluentValidation": "[12.0.0, )", - "Microsoft.AspNetCore.OpenApi": "[8.0.15, )", - "Microsoft.EntityFrameworkCore.InMemory": "[9.0.4, )", - "Microsoft.EntityFrameworkCore.SqlServer": "[9.0.4, )", - "Microsoft.EntityFrameworkCore.Sqlite": "[9.0.4, )", - "Microsoft.Extensions.Configuration.Json": "[9.0.4, )", + "Microsoft.AspNetCore.OpenApi": "[8.0.16, )", + "Microsoft.EntityFrameworkCore.InMemory": "[9.0.5, )", + "Microsoft.EntityFrameworkCore.SqlServer": "[9.0.5, )", + "Microsoft.EntityFrameworkCore.Sqlite": "[9.0.5, )", + "Microsoft.Extensions.Configuration.Json": "[9.0.5, )", "Microsoft.VisualStudio.Web.CodeGeneration.Design": "[9.0.0, )", "Serilog.AspNetCore": "[9.0.0, )", "Serilog.Settings.Configuration": "[9.0.0, )",