{"id":15011552,"url":"https://github.com/pandatecham/be-lib-efcore-audit-base","last_synced_at":"2025-04-12T03:43:46.219Z","repository":{"id":231313519,"uuid":"781435887","full_name":"PandaTechAM/be-lib-efcore-audit-base","owner":"PandaTechAM","description":"EF Core Auditing made easy - Track entity changes, handle deletions, and manage versioning with optimistic concurrency control.","archived":false,"fork":false,"pushed_at":"2025-04-04T08:56:41.000Z","size":183,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"development","last_synced_at":"2025-04-04T09:34:06.629Z","etag":null,"topics":["audit","ef-core","nuget","optimistic-locking","pandatech","soft-delete","tracking","versioning"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PandaTechAM.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-03T11:31:53.000Z","updated_at":"2025-04-04T08:56:18.000Z","dependencies_parsed_at":"2024-07-12T18:48:48.817Z","dependency_job_id":"48ea5a7e-47e5-47fa-93b5-e3d47c10c542","html_url":"https://github.com/PandaTechAM/be-lib-efcore-audit-base","commit_stats":{"total_commits":7,"total_committers":4,"mean_commits":1.75,"dds":0.7142857142857143,"last_synced_commit":"db1753cb0ae4793516416d6b0ebc333a1e282bc8"},"previous_names":["pandatecham/be-lib-efcore-audit-base"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-efcore-audit-base","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-efcore-audit-base/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-efcore-audit-base/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PandaTechAM%2Fbe-lib-efcore-audit-base/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PandaTechAM","download_url":"https://codeload.github.com/PandaTechAM/be-lib-efcore-audit-base/tar.gz/refs/heads/development","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514212,"owners_count":21116899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audit","ef-core","nuget","optimistic-locking","pandatech","soft-delete","tracking","versioning"],"created_at":"2024-09-24T19:41:14.523Z","updated_at":"2025-04-12T03:43:46.202Z","avatar_url":"https://github.com/PandaTechAM.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pandatech.EFCore.AuditBase\n\nPandatech.EFCore.AuditBase is a comprehensive auditing library for Entity Framework Core, designed to make entity\ntracking, deletion management, and concurrency control straightforward and efficient.\n\n## Features\n\n- **Automatic Auditing**: Automatically tracks creation and update times, along with the corresponding user IDs.\n- **Soft Delete Support**: Implements soft deletion logic, allowing entities to be marked as deleted without physical\n  removal from the database.\n- **Concurrency Control**: Integrates versioning to handle concurrency, minimizing data conflicts.\n- **Enforced Best Practices**: Enforces the use of provided methods for updates and deletions, ensuring consistent audit\n  trails.\n- **Query Filter Management**: Allows for the exclusion of soft-deleted entities from queries, with an option to include\n  them when necessary.\n- **Seamless Integration**: Designed to integrate smoothly with EF Core projects, enhancing data integrity and\n  compliance.\n\n## Getting Started\n\nTo integrate Pandatech.EFCore.AuditBase into your project, install the NuGet package:\n\n```bash\nInstall-Package Pandatech.EFCore.AuditBase\n```\n\n## Usage\n\n1. Inherit from `AuditEntityBase` in your entity classes to enable auditing.\n2. Use `MarkAsUpdated(userId)` and `MarkAsDeleted(userId)` methods to handle entity updates and deletions.\n3. Apply `OptionsBuilderExtensions.UseAuditBaseValidatorInterceptor` during the DbContext registration in your DI configuration.\n4. Leverage `ModelBuilderExtensions.FilterOutDeletedMarkedObjects` to automatically exclude soft-deleted entities from\n   EF Core queries.\n\n### Registering DbContext with `UseAuditBaseValidatorInterceptor`:\n\nWhen configuring your `DbContext`, ensure you call `UseAuditBaseValidatorInterceptor` during the service registration phase:\n```csharp\nvar connectionString = configuration.GetConnectionString(\"Postgres\");\n\nbuilder.Services.AddDbContextPool\u003cPostgresContext\u003e(options =\u003e\n    options.UseNpgsql(connectionString)\n           .UseAuditBaseValidatorInterceptor()); // Enforce audit method usage\n```\n\n### Entity Inheritance Example:\n\nAssuming you have a `Product` entity in your application, you would inherit from `AuditEntityBase` to include auditing\nproperties:\n\n```csharp\nusing Pandatech.VerticalSlices.Domain.Shared;\n\npublic class Product : AuditEntityBase\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public decimal Price { get; set; }\n}\n```\n\nBy inheriting from `AuditEntityBase`, Product automatically gains auditing properties\nlike `CreatedAt`, `CreatedByUserId`, `UpdatedAt`, `UpdatedByUserId`, `Deleted` and `Version`.\n\n### Using `MarkAsUpdated` and `MarkAsDeleted`:\n\nWhen updating or deleting an entity, use the provided methods to ensure the audit properties are correctly updated:\n\n```csharp\npublic void UpdateProduct(Product product, long updatingUserId)\n{\n    // Perform your update logic...\n    \n    product.MarkAsUpdated(updatingUserId); //optional UpdatedAt DateTime parameter\n    _dbContext.SaveChanges();\n}\n\npublic void DeleteProduct(Product product, long deletingUserId)\n{\n    product.MarkAsDeleted(deletingUserId); //optional UpdatedAt DateTime parameter\n    _dbContext.SaveChanges();\n}\n```\n\n### DbContext Configuration:\n\nIn your `DbContext`, you can use the `FilterOutDeletedMarkedObjects` method to apply a global query filter for soft-deleted entities:\n\n```csharp\nusing Microsoft.EntityFrameworkCore;\nusing Pandatech.VerticalSlices.Infrastructure.Context;\n\npublic class MyDbContext : DbContext\n{\n    public DbSet\u003cProduct\u003e Products { get; set; }\n\n    protected override void OnModelCreating(ModelBuilder modelBuilder)\n    {\n        base.OnModelCreating(modelBuilder);\n\n        modelBuilder.FilterOutDeletedMarkedObjects(); // Apply global query filter for soft deletes\n    }\n}\n```\n\n### Using `ExecuteUpdateAndMarkUpdatedAsync`:\n\nThis extension method allows developers to update multiple properties while still maintaining audit consistency by\nupdating `UpdatedAt`, `UpdatedByUserId`, and `Version` behind the scenes.\n\n```csharp\npublic async Task UpdateProductPricesAsync(MyDbContext dbContext, long userId)\n{\n    var expensiveProducts = dbContext.Products.Where(p =\u003e p.Price \u003e 100);\n\n    await expensiveProducts.ExecuteUpdateAndMarkUpdatedAsync(\n        userId,\n        x =\u003e x.SetProperty(p =\u003e p.Price, p =\u003e p.Price * 0.9) // Apply 10% discount\n    );\n}\n```\n\n### Using `ExecuteSoftDeleteAsync`:\n\nTo perform a soft delete on multiple entities, use the `ExecuteSoftDeleteAsync` extension method.\n\n```csharp\npublic async Task SoftDeleteProductsAsync(MyDbContext dbContext, long userId)\n{\n    var productsToSoftDelete = dbContext.Products.Where(p =\u003e p.Price \u003e 100);\n\n    await productsToSoftDelete.ExecuteSoftDeleteAsync(userId);\n}\n```\n\n### Ignoring Soft Delete Filter:\n\nIf you need to include soft-deleted entities in a specific query, use `IgnoreQueryFilters()`:\n\n```csharp\nvar allProductsIncludingDeleted = _dbContext.Products.IgnoreQueryFilters().ToList();\n```\n\n## Handling Concurrency\n\nThe `AuditEntityBase` includes a versioning mechanism to manage concurrent updates. In the event of a conflict, a\nconcurrency exception will be thrown. This can be gracefully handled using try-catch blocks or integrated\nwith `Pandatech.ResponseCrafter` for automated response management.\n\nHowever, `ExecuteUpdateAndMarkUpdatedAsync` and `ExecuteSoftDeleteAsync` **ignore optimistic locking**, meaning they\nwill not throw a concurrency exception if the `Version` field changes during the operation. This is because these\nmethods only increment the `Version` field by one, regardless of the current value.\n\n## Contributing\n\nContributions are welcome! Please submit a pull request or open an issue to propose changes or report bugs.\n\n## License\n\nPandatech.EFCore.AuditBase is licensed under the MIT License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-efcore-audit-base","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpandatecham%2Fbe-lib-efcore-audit-base","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpandatecham%2Fbe-lib-efcore-audit-base/lists"}