diff --git a/src/api/SIGCM2.Domain/Entities/Permiso.cs b/src/api/SIGCM2.Domain/Entities/Permiso.cs
new file mode 100644
index 0000000..ee08070
--- /dev/null
+++ b/src/api/SIGCM2.Domain/Entities/Permiso.cs
@@ -0,0 +1,49 @@
+namespace SIGCM2.Domain.Entities;
+
+///
+/// Entidad de dominio que representa un permiso atómico del catálogo RBAC.
+/// Inmutable — solo se puede leer desde BD (sin creación por API).
+///
+public sealed class Permiso
+{
+ public int Id { get; }
+ public string Codigo { get; }
+ public string Nombre { get; }
+ public string? Descripcion { get; }
+ public string Modulo { get; }
+ public bool Activo { get; }
+ public DateTime FechaCreacion { get; }
+
+ private Permiso(
+ int id,
+ string codigo,
+ string nombre,
+ string? descripcion,
+ string modulo,
+ bool activo,
+ DateTime fechaCreacion)
+ {
+ Id = id;
+ Codigo = codigo;
+ Nombre = nombre;
+ Descripcion = descripcion;
+ Modulo = modulo;
+ Activo = activo;
+ FechaCreacion = fechaCreacion;
+ }
+
+ ///
+ /// Factory para hidratación desde BD (read-only — el catálogo solo se modifica vía migraciones).
+ ///
+ public static Permiso ForRead(
+ int id,
+ string codigo,
+ string nombre,
+ string? descripcion,
+ string modulo,
+ bool activo,
+ DateTime fechaCreacion)
+ {
+ return new Permiso(id, codigo, nombre, descripcion, modulo, activo, fechaCreacion);
+ }
+}
diff --git a/src/api/SIGCM2.Domain/Exceptions/PermisoNotFoundException.cs b/src/api/SIGCM2.Domain/Exceptions/PermisoNotFoundException.cs
new file mode 100644
index 0000000..c9f95cb
--- /dev/null
+++ b/src/api/SIGCM2.Domain/Exceptions/PermisoNotFoundException.cs
@@ -0,0 +1,12 @@
+namespace SIGCM2.Domain.Exceptions;
+
+public sealed class PermisoNotFoundException : Exception
+{
+ public string Codigo { get; }
+
+ public PermisoNotFoundException(string codigo)
+ : base($"El permiso '{codigo}' no existe.")
+ {
+ Codigo = codigo;
+ }
+}
diff --git a/src/api/SIGCM2.Domain/Permissions/Permiso.cs b/src/api/SIGCM2.Domain/Permissions/Permiso.cs
new file mode 100644
index 0000000..e07dadf
--- /dev/null
+++ b/src/api/SIGCM2.Domain/Permissions/Permiso.cs
@@ -0,0 +1,53 @@
+namespace SIGCM2.Domain.Permissions;
+
+///
+/// Catálogo canónico de permisos RBAC del sistema.
+/// Source of truth: cada código aquí debe tener su fila en dbo.Permiso vía migración.
+/// Convención: al agregar un permiso nuevo → también asignarlo al rol admin en la misma migración.
+///
+public static class Permiso
+{
+ // ── Ventas: contado ──────────────────────────────────────────────────────
+ public const string VentasContadoCrear = "ventas:contado:crear";
+ public const string VentasContadoModificar = "ventas:contado:modificar";
+ public const string VentasContadoCobrar = "ventas:contado:cobrar";
+ public const string VentasContadoFacturar = "ventas:contado:facturar";
+
+ // ── Ventas: cuenta corriente ─────────────────────────────────────────────
+ public const string VentasCtacteCrear = "ventas:ctacte:crear";
+ public const string VentasCtacteFacturar = "ventas:ctacte:facturar";
+
+ // ── Textos ───────────────────────────────────────────────────────────────
+ public const string TextosEditar = "textos:editar";
+ public const string TextosReclamosVer = "textos:reclamos:ver";
+
+ // ── Pauta ────────────────────────────────────────────────────────────────
+ public const string PautaAzanuVer = "pauta:azanu:ver";
+ public const string PautaLimpiar = "pauta:limpiar";
+ public const string PautaRecursosFueraDeHora = "pauta:recursos:fueradehora";
+
+ // ── Productores ──────────────────────────────────────────────────────────
+ public const string ProductoresDeudaVer = "productores:deuda:ver";
+ public const string ProductoresPendientesCrear = "productores:pendientes:crear";
+ public const string ProductoresDeudaBypass = "productores:deuda:bypass";
+
+ // ── Administración ───────────────────────────────────────────────────────
+ public const string AdministracionUsuariosGestionar = "administracion:usuarios:gestionar";
+ public const string AdministracionTarifariosGestionar = "administracion:tarifarios:gestionar";
+ public const string AdministracionMediosGestionar = "administracion:medios:gestionar";
+ public const string AdministracionAuditoriaVer = "administracion:auditoria:ver";
+
+ ///
+ /// Set completo de todos los códigos canónicos (útil para validación y seeds).
+ ///
+ public static readonly IReadOnlySet Todos = new HashSet
+ {
+ VentasContadoCrear, VentasContadoModificar, VentasContadoCobrar, VentasContadoFacturar,
+ VentasCtacteCrear, VentasCtacteFacturar,
+ TextosEditar, TextosReclamosVer,
+ PautaAzanuVer, PautaLimpiar, PautaRecursosFueraDeHora,
+ ProductoresDeudaVer, ProductoresPendientesCrear, ProductoresDeudaBypass,
+ AdministracionUsuariosGestionar, AdministracionTarifariosGestionar,
+ AdministracionMediosGestionar, AdministracionAuditoriaVer,
+ };
+}