Activities of "alva.gabriel"

Hi ABP Team

We have a scenario where we need to present the audit trail of an entity’s changes on a custom frontend screen. We were reviewing the official ABP documentation but couldn’t find a specific or recommended approach to access this audit data from the backend in a way that suits our needs.

We found a third party forum post mentioning the use of EfCoreAuditLogRepository for a similar use case. Based on that hint, we installed the Volo.Abp.AuditLogging.EntityFrameworkCore package in the Application layer of our ABP module and explicitly instantiated it in the ProcurementApplicationModule class. With this setup, we were able to retrieve the entity changes as needed for our frontend.

We would like to clarify two things:

1. Is there any official or recommended approach by ABP to access an entity’s audit logs according to our use case? If so, we would really appreciate it if you could share a link to the official documentation or any related resources.

2. If ABP does not have an official or recommended approach for this scenario, would our current implementation (using EfCoreAuditLogRepository in the Application layer) cause any issues now or in the future, or is it acceptable to continue working this way?

For your reference, here is a simplified version of our code in the ApplicationModule and AppService classes:

// ApplicationModule
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.Application;
using Volo.Abp.BackgroundWorkers.Hangfire;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.BackgroundWorkers;
using Aptim.MiApptimWeb.Procurement.Orders;
using Volo.Abp.AuditLogging.EntityFrameworkCore;

namespace Aptim.MiApptimWeb.Procurement;

[DependsOn(
    typeof(ProcurementDomainModule),
    typeof(ProcurementApplicationContractsModule),
    typeof(AbpDddApplicationModule),
    typeof(AbpAutoMapperModule)
    )]
[DependsOn(typeof(AbpBackgroundWorkersHangfireModule))]
public class ProcurementApplicationModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddAutoMapperObjectMapper<ProcurementApplicationModule>();
        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<ProcurementApplicationModule>(validate: true);
        });

        context.Services.AddTransient<EfCoreAuditLogRepository>();
    }

    public override async Task OnApplicationInitializationAsync(
        ApplicationInitializationContext context)
    {
        await context.AddBackgroundWorkerAsync<MyLogWorker>();
    }
}
// AppService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories;

namespace Aptim.MiApptimWeb.Procurement.Orders;

public class ProcessedOrderAppService(
    IRepository<ProcessedOrders, Guid> _repository,
    IRepository<StagingPurchaseOrderDetail, Guid> _stagingRepository,
    EfCoreAuditLogRepository _auditLogRepository
) : ProcurementAppService, IProcessedOrderAppService
{
    public async Task<List<EntityChangeDto>> GetProcessedOrderChangesAsync(Guid entityId)
    {
        var entityChanges = await _auditLogRepository.GetEntityChangeListAsync(
            includeDetails: true,
            entityId: entityId.ToString()
        );

        var result = entityChanges
            .OrderBy(ec => ec.ChangeTime)
            .Select(ec => new EntityChangeDto
            {
                ChangeTime = ec.ChangeTime,
                ChangeType = ec.ChangeType.ToString(),
                PropertyChanges = ec.PropertyChanges
                    .Select(pc => new PropertyChangeDto
                    {
                        PropertyName = pc.PropertyName,
                        OriginalValue = DeserializeValue(pc.OriginalValue),
                        NewValue = DeserializeValue(pc.NewValue)
                    })
                    .ToList()
            })
            .ToList();

        return result;
    }

    private string DeserializeValue(string jsonValue)
    {
        if (jsonValue == null)
        {
            return null;
        }

        try
        {
            return JsonSerializer.Deserialize<string>(jsonValue);
        }
        catch
        {
            return jsonValue;
        }
    }
}

Thank you very much in advance for your support and clarifications.

Best regards, Gabriel

Hi sumeyye.kurtulus,

Thanks again for the follow-up!

Here’s a detailed update on the tsconfig.json configurations:

  • In the main Angular project (ModularCrm, Single Layer Application based on the ABP tutorial), the tsconfig.json contains the following path mappings:
"paths": {
  "@proxy": ["src/app/proxy/index.ts"],
  "@proxy/*": ["src/app/proxy/*"],
  ...
  "@modularcrm/products": [
    "../modules/modularcrm.products/angular/projects/products/src/public-api.ts"
  ],
  "@modularcrm/products/config": [
    "../modules/modularcrm.products/angular/projects/products/config/src/public-api.ts"
  ],
  ...
}
  • In the module-specific Angular project (ModularCrm.Products), the tsconfig.json includes:
"paths": {
  "@modular-crm/products": [
    "projects/products/src/public-api.ts"
  ],
  "@modular-crm/products/config": [
    "projects/products/config/src/public-api.ts"
  ],
  "@proxy": ["projects/products/src/lib/proxy/index.ts"],
  "@proxy/*": ["projects/products/src/lib/proxy/*"]
}

As you can see, in the module-specific tsconfig.json, the @proxy alias points correctly to the generated proxies (projects/products/src/lib/proxy/index.ts), and the files are correctly placed there. That’s why I find it a bit strange that the compilation fails with:

../modules/modularcrm.products/angular/projects/products/src/lib/components/products.component.ts:2:32 - error TS2307: Cannot find module '@proxy' or its corresponding type declarations.

Even though the structure and the tsconfig.json configuration seem correct. When I manually change the import to a relative path like:

tsCopiarEditarimport { ProductService } from '../proxy';

everything compiles and runs properly.

Is there perhaps an additional step I’m missing to make the @proxy alias work inside the module's Angular project?

Or should I be configuring something else (maybe in angular.json or the project references)? Thank you once again for your continued help—I really appreciate the support while working through this modular setup!

Kind regards, Gabriel

Hi sumeyye.kurtulus,

Thank you for your response. I was finally able to generate the Angular proxies inside the correct module folder by running the command you shared from within the Angular folder of the corresponding module (in this case, /modules/modularcrm.products/angular/). That resolved the proxy generation issue—thank you!

Now I’ve encountered a different problem. I’m following the ABP guide for the Modular Monolith Application template (ModularCrm), and while the proxy for the Products module is being generated correctly, I’m running into an issue with how imports are handled in the IDE.

For example, when I auto-import ProductService, the IDE generates:

 { ProductService } from '@proxy';

This used to work fine in a previous project based on ABP version 8. However, in this setup, I get the following compile-time error:

../modules/modularcrm.products/angular/projects/products/src/lib/components/products.component.ts:2:32 - error TS2307: Cannot find module '@proxy' or its corresponding type declarations.

If I manually change the import to:

 { ProductService } from '../proxy';

the application compiles and works as expected.

Is this the expected behavior in the new modular structure?

Do I have to manually adjust the import path for each service or DTO I need to use? Or is there a configuration I might be missing to make the @proxy alias resolve correctly in this context?

Thanks again for the support!

Kind regards, Gabriel

Hi

I'm working through the Modular Monolith tutorial using the latest ABP version with Angular as the frontend framework. The documentation has been very helpful overall, but I'm running into some issues with Angular integration that I'd appreciate help with. Initially, the Products module wasn’t appearing in the menu. I resolved this by following the solution in [GitHub Issue #20827](https://github.com/abpframework/abp/issues/20827). The main issue now is with Angular proxy generation:

The proxies are being generated in the main application folder (/angular/src/app) instead of the module-specific folder (/modules/modularcrm.products/angular/src), which breaks the intended modular architecture. I found a related report in [GitHub Issue #22124](https://github.com/abpframework/abp/issues/22124), where the suggested fix was to tweak generate-proxy parameters but it wasn't that helpful.

  1. What’s the correct way to generate Angular proxies inside module folders?
  2. Is there any official documentation on using Angular in a modular monolith setup?

Kind regards, Gabriel

Hi EngincanV

I can confirm I'm using the latest version of ABP Studio and CLI (in MacOS btw) and stil can't see the option for my old project.

Hi EngincanV,

I'm currently using ABP CLI 0.9.25 (Beta), but I still don't see the "Upgrade to Pro" option. Additionally, when I try running abp upgrade -t app, I get an error.

Here's the structure of my existing ABP project (version 8.0.5):

Kuppabit.Kissa
> angular
    > katze
    > kedi
    > neko
    > paka
    > popoki
> aspnet-core
    > src
        > Kissa.Application
        > Kissa.Application.Contracts
        ...
    > modules
        > Katze
            > src
            ...

I understand that the latest ABP CLI introduced changes in the project template structure, so I'm wondering: is there a recommended way to upgrade our current project to Pro, or is it necessary to create a new one using the updated CLI?

Thanks in advance for your help.

Best regards, Gabriel

Hi berkansasmaz,

I tried using the "Upgrade to Pro" option in ABP Studio, but I don’t see it available for any of the projects in our solution.

If I'm not mistaken, the screenshots you shared show a project using ABP 9+ being upgraded to Pro. However, our current project is still on version 8.0.5.

Regards, Gabriel

Hello,

We’ve been working on our Modular Monolith Application using ABP Framework Open Source version 8.0.5 for quite some time. In February 2025, we upgraded to the “Team” commercial license and would now like to migrate our existing project to the commercial edition.

However, we haven’t been able to find any official guide or tutorial on how to perform this migration — specifically regarding:

  • Upgrading the UI theme from LeptonX Lite to the commercial LeptonX version.
  • Installing and integrating PRO modules (Audit Logging, File Management, GDPR, Language Management, Text Template Management) into our current open source project.

Our setup uses SQL Server and has the Auth Server running as a separate project, in line with the standard ABP separated Auth Server architecture.

Could you please guide us on the recommended steps to follow? Or point us to any available documentation or tutorials that cover this migration path?

Thank you in advance for your support.

Best regards, Gabriel

Showing 1 to 8 of 8 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 18, 2025, 07:10