diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs
new file mode 100644
index 0000000..f4de5dd
--- /dev/null
+++ b/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs
@@ -0,0 +1,43 @@
+using SIGCM2.Application.Common;
+using SIGCM2.Domain.Fiscal;
+using IibbEntity = SIGCM2.Domain.Entities.IngresosBrutos;
+
+namespace SIGCM2.Application.Abstractions.Persistence;
+
+///
+/// Persistence contract for IngresosBrutos. Implemented by Dapper repo in Infrastructure.
+///
+public interface IIngresosBrutosRepository
+{
+ /// Inserts a new IngresosBrutos record and returns the generated identity Id.
+ Task InsertAsync(IibbEntity entity, CancellationToken ct = default);
+
+ /// Returns the IngresosBrutos with the given Id, or null if not found.
+ Task GetByIdAsync(int id, CancellationToken ct = default);
+
+ ///
+ /// Updates cosmetic fields only (Descripcion, Activo).
+ /// Never touches Alicuota, Provincia, or vigencia dates.
+ ///
+ Task UpdateCosmeticoAsync(int id, string descripcion, bool activo, CancellationToken ct = default);
+
+ ///
+ /// Closes the vigencia of the predecessor: UPDATE SET VigenciaHasta = @vigenciaHasta
+ /// WHERE Id = @id AND VigenciaHasta IS NULL (optimistic guard for race conditions).
+ /// Returns true if one row was affected, false if the row was already closed (race detected).
+ ///
+ Task UpdateCierreVigenciaAsync(int id, DateOnly vigenciaHasta, CancellationToken ct = default);
+
+ /// Sets Activo to the given value. Returns true if one row was affected.
+ Task SetActivoAsync(int id, bool activo, CancellationToken ct = default);
+
+ /// Returns a paged list applying optional Activo and Provincia filters.
+ Task> ListAsync(IngresosBrutosQuery query, CancellationToken ct = default);
+
+ ///
+ /// Returns the full version chain for the record identified by ,
+ /// ordered from root (no PredecesorId) to the requested Id (inclusive).
+ /// Implemented via a recursive CTE in the concrete repository.
+ ///
+ Task> GetHistorialAsync(int id, CancellationToken ct = default);
+}
diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs
new file mode 100644
index 0000000..18c75b3
--- /dev/null
+++ b/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs
@@ -0,0 +1,42 @@
+using SIGCM2.Application.Common;
+using SIGCM2.Domain.Entities;
+
+namespace SIGCM2.Application.Abstractions.Persistence;
+
+///
+/// Persistence contract for TipoDeIva. Implemented by Dapper repo in Infrastructure.
+///
+public interface ITipoDeIvaRepository
+{
+ /// Inserts a new TipoDeIva and returns the generated identity Id.
+ Task InsertAsync(TipoDeIva entity, CancellationToken ct = default);
+
+ /// Returns the TipoDeIva with the given Id, or null if not found.
+ Task GetByIdAsync(int id, CancellationToken ct = default);
+
+ ///
+ /// Updates cosmetic fields only (Codigo, Descripcion, AplicaIVA, Activo).
+ /// Never touches Porcentaje or vigencia dates.
+ ///
+ Task UpdateCosmeticoAsync(int id, string codigo, string descripcion, bool aplicaIVA, bool activo, CancellationToken ct = default);
+
+ ///
+ /// Closes the vigencia of the predecessor: UPDATE SET VigenciaHasta = @vigenciaHasta
+ /// WHERE Id = @id AND VigenciaHasta IS NULL (optimistic guard for race conditions).
+ /// Returns true if one row was affected, false if the row was already closed (race detected).
+ ///
+ Task UpdateCierreVigenciaAsync(int id, DateOnly vigenciaHasta, CancellationToken ct = default);
+
+ /// Sets Activo to the given value. Returns true if one row was affected.
+ Task SetActivoAsync(int id, bool activo, CancellationToken ct = default);
+
+ /// Returns a paged list applying optional Activo and Codigo filters.
+ Task> ListAsync(TiposDeIvaQuery query, CancellationToken ct = default);
+
+ ///
+ /// Returns the full version chain for the record identified by ,
+ /// ordered from root (no PredecesorId) to the requested Id (inclusive).
+ /// Implemented via a recursive CTE in the concrete repository.
+ ///
+ Task> GetHistorialAsync(int id, CancellationToken ct = default);
+}
diff --git a/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs b/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs
new file mode 100644
index 0000000..f293d22
--- /dev/null
+++ b/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs
@@ -0,0 +1,11 @@
+using SIGCM2.Domain.Fiscal;
+
+namespace SIGCM2.Application.Common;
+
+/// Query parameters for listing ingresos brutos with optional filters and paging.
+public sealed record IngresosBrutosQuery(
+ int Page,
+ int PageSize,
+ bool? Activo,
+ ProvinciaArgentina? Provincia
+);
diff --git a/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs b/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs
new file mode 100644
index 0000000..dc36440
--- /dev/null
+++ b/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs
@@ -0,0 +1,9 @@
+namespace SIGCM2.Application.Common;
+
+/// Query parameters for listing tipos de IVA with optional filters and paging.
+public sealed record TiposDeIvaQuery(
+ int Page,
+ int PageSize,
+ bool? Activo,
+ string? Codigo
+);
diff --git a/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs b/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs
new file mode 100644
index 0000000..e482d5c
--- /dev/null
+++ b/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs
@@ -0,0 +1,15 @@
+namespace SIGCM2.Domain.Exceptions;
+
+///
+/// Thrown when a requested IngresosBrutos record does not exist in the system.
+///
+public sealed class IngresosBrutosNotFoundException : DomainException
+{
+ public int Id { get; }
+
+ public IngresosBrutosNotFoundException(int id)
+ : base($"El registro de Ingresos Brutos con id '{id}' no existe.")
+ {
+ Id = id;
+ }
+}
diff --git a/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs b/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs
new file mode 100644
index 0000000..352f382
--- /dev/null
+++ b/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs
@@ -0,0 +1,15 @@
+namespace SIGCM2.Domain.Exceptions;
+
+///
+/// Thrown when a requested TipoDeIva does not exist in the system.
+///
+public sealed class TipoDeIvaNotFoundException : DomainException
+{
+ public int Id { get; }
+
+ public TipoDeIvaNotFoundException(int id)
+ : base($"El tipo de IVA con id '{id}' no existe.")
+ {
+ Id = id;
+ }
+}