Skip to content

feat(mediator): add persisted sample auditing#790

Merged
AndreaCuneo merged 24 commits into
masterfrom
copilot/proceed-with-next-tasks
Jul 24, 2026
Merged

feat(mediator): add persisted sample auditing#790
AndreaCuneo merged 24 commits into
masterfrom
copilot/proceed-with-next-tasks

Conversation

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

The mediator sample only tracked audits with an in-memory counter. Implement persisted, transactional auditing with a queryable HTTP endpoint, matching the SMP-03 task requirements.

  • Audit persistence

    • Add SQL Audit table and test reset support.
    • Persist user, contract name, timestamp, and identifier in the same transaction as greeting mutations.
    • Support SQL and in-memory stores.
  • Audit query

    • Add paged GET /api/v{version}/audits.
    • Validate Skip and Limit.
    • Include OpenAPI and JSON serialization metadata.
  • Coverage

    • Add behavioral scenario verifying audit records after greeting creation.
    • Mark SMP-03 complete in the task tracker.
GET /api/v1/audits?skip=0&limit=25

Copilot AI and others added 3 commits July 19, 2026 17:30
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
@AndreaCuneo
AndreaCuneo marked this pull request as ready for review July 19, 2026 17:57
@AndreaCuneo
AndreaCuneo requested a review from a team as a code owner July 19, 2026 17:57
Comment thread samples/Ark.MediatorFramework.Sample/Database/dbo/Tables/Audit.sql Outdated
Copilot AI and others added 2 commits July 19, 2026 20:07
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI requested a review from AndreaCuneo July 19, 2026 20:14
Copilot AI and others added 2 commits July 20, 2026 06:36
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI requested a review from AndreaCuneo July 20, 2026 06:45
Copilot AI and others added 2 commits July 20, 2026 07:34
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI requested a review from AndreaCuneo July 20, 2026 07:46
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 24, 2026 05:59

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

remove explicit TypeConverter support in Generator. is not needed as if type is string convertible is already supported by minimalapi. Nodatime types works without the decoration.

@copilot

Removed the explicit generator TypeConverter path in b5d8e79. Native Minimal API binding rejects Instant? in this runtime because it has no static TryParse; a separate approved binding strategy is needed for that sample filter.

Copilot AI requested a review from AndreaCuneo July 24, 2026 06:03
Copilot AI review requested due to automatic review settings July 24, 2026 12:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds persisted, queryable auditing to the MediatorFramework sample, and extends the Minimal API generator + OpenAPI conventions to support richer query/route binding (type-converter-based values, enum-as-string, and string collection query params) needed by the new audit query endpoint.

Changes:

  • Persist audit records (SQL + in-memory) alongside greeting mutations and expose a paged audit query endpoint contract.
  • Extend Minimal API generator + OpenAPI conventions for type-converter-wrapped parameters and string collection query binding.
  • Add/adjust tests (generator snapshots + behavioral scenario) and update task tracker/docs.

Reviewed changes

Copilot reviewed 30 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Ark.Tools.MediatorFramework.Tests/MinimalApiHostingExtensionsTests.cs Adds runtime binding/OpenAPI tests for type-converter wrappers and enum string binding.
tests/Ark.Tools.MediatorFramework.Tests/GeneratorSnapshotTests.cs Adds generator snapshots for string collection binding, type-converter wrapping, and enum handling.
src/mediator-framework/Ark.Tools.MediatorFramework.MinimalApi/ArkTypeConverterValue.cs Introduces parameter wrapper using TypeConverter binding + endpoint metadata for OpenAPI.
src/mediator-framework/Ark.Tools.MediatorFramework.MinimalApi/ArkOpenApiEx.cs Adds OpenAPI transformer to emit schemas for wrapped CLR types.
src/mediator-framework/Ark.Tools.MediatorFramework.MinimalApi.Generators/MinimalApiEndpointGenerator.cs Updates generator binding strategy (collections, type converters, GET/DELETE bindings).
src/common/Ark.Tools.Nodatime/NodaTimeConverters.cs Adds NodaTimeConverter.Register() facade for NodaTime TypeConverter registration.
src/common/Ark.Tools.Nodatime.Protobuf/Ark.Tools.Nodatime.Protobuf.csproj Normalizes proto import path separators.
samples/Ark.MediatorFramework.Sample/test/Ark.MediatorFramework.Sample.Tests/Steps/GreetingSteps.cs Adds step verifying audit records via HTTP query (including timestamp filter).
samples/Ark.MediatorFramework.Sample/test/Ark.MediatorFramework.Sample.Tests/Features/Greetings.feature Adds scenario asserting persisted audit visibility after greeting creation.
samples/Ark.MediatorFramework.Sample/test/Ark.MediatorFramework.Sample.Tests/Ark.MediatorFramework.Sample.Tests.csproj Fixes database project reference path.
samples/Ark.MediatorFramework.Sample/test/Ark.MediatorFramework.Sample.GrpcClient/Ark.MediatorFramework.Sample.GrpcClient.csproj Normalizes proto import paths for cross-platform builds.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.WebInterface/SampleStartup.cs Registers NodaTime type converters and wires new OpenAPI transformer.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.WebInterface/SampleJsonSerializerContext.cs Adds JSON source-gen metadata for audit query/records and paged result.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/Security/Schemas.sql Adds ops schema for test reset procedure.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/Script.PostDeployment.sql Adds post-deploy guard for DB existence.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/packages.lock.json Adds lockfile for DB project (restore locked mode compatibility).
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/ops/ResetFull_OnlyForTesting.sql Extends reset procedure to clear new Audit table.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/dbo/Tables/Outbox.sql Adds Outbox table definition to DB project.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/dbo/Tables/Greeting.sql Adds AuditId column to greeting storage.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/dbo/Tables/Audit.sql Adds Audit table definition.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/Ark.MediatorFramework.Sample.Database.sqlproj Adds ProjectGuid to DB project (but currently all-zero).
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/SampleDataContext.cs Writes/reads audits transactionally; adds audit paging/query logic; persists AuditId with greetings.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/GreetingStore.cs Extends store interface for audit persistence/query; adds in-memory audit queue.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/GreetingHandlers.cs Writes audit entries on greeting mutations and adds GetAuditsHandler.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/GreetingContracts.cs Adds AuditId to GreetingResponse contract.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/AuditValidators.cs Adds paging validation for audit query (needs Sort validation too).
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/AuditContracts.cs Adds audit entry/record contracts and GetAuditsQuery endpoint contract.
samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/ApplicationComposition.cs Registers clock and audit query handler.
samples/Ark.MediatorFramework.Sample/README.md Updates database project path reference.
docs/mediator-framework/tasks/sample-parity/SMP-03-persisted-auditing.md Marks SMP-03 acceptance items as completed.
docs/mediator-framework/tasks/README.md Marks SMP-03 complete and adds GEN-07/GEN-08 to task list.
docs/mediator-framework/tasks/generator-dx/GEN-08-from-assembly-api-names.md Adds new release-blocker task doc.
docs/mediator-framework/tasks/generator-dx/GEN-07-automatic-proto-export.md Adds new release-blocker task doc.
.vscode/launch.json Adds a launch profile for the sample web interface.
Comments suppressed due to low confidence (1)

samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/Ark.MediatorFramework.Sample.Database.sqlproj:15

  • ProjectGuid is set to all zeros, which is not a stable unique project identifier and can confuse tooling/MSBuild (compare Ark.Reference.Core.Database.sqlproj which uses a real GUID). Either remove this element or replace it with a real, unique GUID.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Andrea Cuneo <kaildio@gmail.com>
Copilot AI review requested due to automatic review settings July 24, 2026 12:39
<CompatibilityMode>160</CompatibilityMode>
<EnableDefaultSqlItems>false</EnableDefaultSqlItems>
<IsPackable>false</IsPackable>
<ProjectGuid>{00000000-0000-0000-0000-000000000000}</ProjectGuid>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use a valid random guid @copilot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the all-zeros placeholder with a valid random GUID (A3F7C251-8E14-4B9D-BE62-5D1F2C830947) in the latest commit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 34 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/GreetingStore.cs:153

  • InMemoryGreetingStore assigns a new Guid to AuditRecord.Id instead of using the provided AuditEntry.Id. This breaks correlation with GreetingResponse.AuditId and diverges from the SQL store behavior (which persists audit.Id).
        _audits.Enqueue(new AuditRecord
        {
            Id = Guid.NewGuid(),
            UserId = audit.UserId,
            EntityType = audit.EntityType,
            Identifier = audit.Identifier,
            Operation = audit.Operation,
            Timestamp = audit.Timestamp,
        });

samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Database/Ark.MediatorFramework.Sample.Database.sqlproj:14

  • ProjectGuid is set to the all-zero GUID, which is not a valid unique project identifier and can cause tooling/solution conflicts. Use a real, stable GUID (see Ark.Reference.Core.Database.sqlproj for precedent).

…Api generator

MinimalApi natively handles TypeConverter-backed types when they are string-convertible, so the generator wrapper (ArkTypeConverterValue<T>) is not needed. The ArkTypeConverterValue class is retained for manual use.

- Remove RequiresTypeConverterBinding method and PropertyModel field
- Simplify BindingType/BindingValue to drop TypeConverter paths
- Rename/update snapshot test to verify direct binding for unknown types
- Fix sqlproj ProjectGuid placeholder with valid random GUID

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 24, 2026 12:49

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

remove explicit TypeConverter support in Generator. is not needed as if type is string convertible is already supported by minimalapi. Nodatime types works without the decoration.

@copilot

Removed RequiresTypeConverterBinding detection and ArkTypeConverterValue<T> auto-wrapping from the generator in the latest commit. Unknown types now bind directly — MinimalApi handles TypeConverter-backed types natively. The ArkTypeConverterValue class is retained for manual use.

Copilot AI requested a review from AndreaCuneo July 24, 2026 12:50
Copilot AI review requested due to automatic review settings July 24, 2026 13:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 34 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

samples/Ark.MediatorFramework.Sample/src/Ark.MediatorFramework.Sample.Application/GreetingStore.cs:148

  • In-memory audit records should preserve the provided AuditEntry.Id so callers can correlate GreetingResponse.AuditId / audit entry IDs with queried AuditRecord.Id. Generating a new Guid here breaks that correlation and diverges from the SQL store behavior.
        _audits.Enqueue(new AuditRecord
        {
            Id = Guid.NewGuid(),
            UserId = audit.UserId,

@AndreaCuneo
AndreaCuneo merged commit 1706040 into master Jul 24, 2026
8 checks passed
@AndreaCuneo
AndreaCuneo deleted the copilot/proceed-with-next-tasks branch July 24, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants