Initial commit
This commit is contained in:
123
AGENTS_STORED_PROCEDURES.md
Normal file
123
AGENTS_STORED_PROCEDURES.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Reglas obligatorias de procedimientos almacenados
|
||||
|
||||
Estas reglas complementan `AGENTS.md` y son obligatorias para toda consulta nueva o modificada en la aplicación.
|
||||
|
||||
## Acceso a datos
|
||||
|
||||
- Todas las lecturas y escrituras de la aplicación deben usar procedimientos almacenados.
|
||||
- No escribir `SELECT`, `INSERT`, `UPDATE`, `DELETE` ni `MERGE` directamente en C# dentro de repositorios, servicios, páginas, controles o la master page.
|
||||
- Los repositorios deben usar `CommandType.StoredProcedure`.
|
||||
- Todos los valores proporcionados por la aplicación deben enviarse como parámetros.
|
||||
- Nunca concatenar entrada del usuario en SQL.
|
||||
|
||||
## Nombres
|
||||
|
||||
- Usar el formato `PA_<Tipo>_<Entidad><Accion>`.
|
||||
- `PA` significa procedimiento almacenado.
|
||||
- `<Tipo>` identifica el grupo funcional: `Sis`, `Tra`, `Vta`, `Conta`, `Clientes`, `Fraccionamientos`, etcétera.
|
||||
- `<Entidad>` identifica el objeto y `<Accion>` describe claramente la operación; por ejemplo `Add`, `Update`, `List`, `Activate`, `Deactivate` o `Delete`.
|
||||
- Ejemplos: `PA_Sis_UsuarioAdd`, `PA_Sis_UsuarioUpdate`, `PA_Sis_UsuarioList`, `PA_Sis_UsuarioActivate`, `PA_Sis_UsuarioDeactivate` y `PA_Sis_UsuarioDelete`.
|
||||
|
||||
## Parámetros y resultado obligatorios
|
||||
|
||||
Todos los procedimientos deben declarar:
|
||||
|
||||
```sql
|
||||
@CveUsuarioEjecuta int,
|
||||
@ErrorMostrar varchar(max) OUTPUT,
|
||||
@ErrorTipo int OUTPUT,
|
||||
@Return bit OUTPUT
|
||||
```
|
||||
|
||||
- `@CveUsuarioEjecuta` identifica al usuario autenticado que ejecuta la operación.
|
||||
- Al inicio, establecer `@ErrorMostrar = NULL`, `@ErrorTipo = 0` y `@Return = 0`.
|
||||
- Establecer `@Return = 1` únicamente cuando la operación termine correctamente.
|
||||
- `@ErrorTipo = 0`: sin error ni advertencia.
|
||||
- `@ErrorTipo = 1`: error.
|
||||
- `@ErrorTipo = 2`: advertencia.
|
||||
- `@ErrorMostrar` contiene el mensaje amigable en español que puede mostrarse al usuario.
|
||||
- No devolver contraseñas, hashes, cadenas de conexión, SQL, stack traces ni detalles internos mediante `@ErrorMostrar`.
|
||||
- Los procedimientos de consulta pueden devolver un result set, pero también deben poblar los parámetros comunes.
|
||||
- El repositorio debe convertir los parámetros de salida en un modelo de resultado como `DbResult<T>`.
|
||||
|
||||
## Control de errores
|
||||
|
||||
- Usar `SET NOCOUNT ON` y `TRY/CATCH` en todos los procedimientos.
|
||||
- Usar `SET XACT_ABORT ON` cuando exista una mutación o transacción.
|
||||
- Iniciar la transacción dentro de `TRY`, confirmar sólo después del éxito y ejecutar rollback en `CATCH` cuando `XACT_STATE() <> 0`.
|
||||
- Una validación fallida debe establecer los parámetros de salida y ejecutar `RETURN`; no debe continuar la mutación.
|
||||
- Para validar existencia, usar normalmente `EXISTS` en lugar de `COUNT(*)`.
|
||||
- En `CATCH`, generar un mensaje técnico separado con `ERROR_NUMBER()`, `ERROR_PROCEDURE()`, `ERROR_LINE()` y `ERROR_MESSAGE()` para el log.
|
||||
- El mensaje técnico puede notificarse con severidad informativa para que el ejecutor lo registre, pero nunca debe mostrarse directamente al usuario.
|
||||
|
||||
## Borrado lógico
|
||||
|
||||
- Está prohibido usar `DELETE` físico en procedimientos CRUD normales.
|
||||
- Para borrar: `Borrado = 1` y `FechaBorrado = SYSDATETIME()`.
|
||||
- Para restaurar: `Borrado = 0` y `FechaBorrado = NULL`.
|
||||
- Las consultas normales deben filtrar `Borrado = 0` en cada tabla participante, excepto cuando el caso de uso solicite expresamente registros borrados.
|
||||
- La eliminación permanente sólo puede realizarse mediante el procedimiento controlado de retención y limpieza.
|
||||
- Ninguna página ASPX puede llamar directamente a la limpieza física.
|
||||
|
||||
## Plantilla requerida
|
||||
|
||||
```sql
|
||||
CREATE OR ALTER PROCEDURE [dbo].[PA_Sis_RolAdd]
|
||||
@Rol varchar(50),
|
||||
@CveUsuarioEjecuta int,
|
||||
@ErrorMostrar varchar(max) OUTPUT,
|
||||
@ErrorTipo int OUTPUT,
|
||||
@Return bit OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
SELECT
|
||||
@ErrorMostrar = NULL,
|
||||
@ErrorTipo = 0,
|
||||
@Return = 0;
|
||||
|
||||
BEGIN TRY
|
||||
IF EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM dbo.Sis_Roles
|
||||
WHERE NombreRol = @Rol
|
||||
AND Borrado = 0
|
||||
)
|
||||
BEGIN
|
||||
SET @ErrorMostrar = CONCAT('El rol ''', @Rol, ''' ya se encuentra registrado.');
|
||||
SET @ErrorTipo = 2;
|
||||
RETURN;
|
||||
END;
|
||||
|
||||
INSERT INTO dbo.Sis_Roles
|
||||
(NombreRol, Activo, FechaCreacion)
|
||||
VALUES
|
||||
(@Rol, 1, SYSDATETIME());
|
||||
|
||||
SET @Return = 1;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF XACT_STATE() <> 0
|
||||
ROLLBACK TRANSACTION;
|
||||
|
||||
SET @ErrorMostrar = 'Ocurrió un error al agregar el rol; favor de contactar a Sistemas.';
|
||||
SET @ErrorTipo = 1;
|
||||
SET @Return = 0;
|
||||
|
||||
DECLARE @ErrorTecnico nvarchar(2048) = CONCAT(
|
||||
'Número: ', ERROR_NUMBER(),
|
||||
'; Procedimiento: ', COALESCE(ERROR_PROCEDURE(), 'PA_Sis_RolAdd'),
|
||||
'; Línea: ', ERROR_LINE(),
|
||||
'; Detalle: ', ERROR_MESSAGE()
|
||||
);
|
||||
|
||||
RAISERROR(N'%s', 10, 1, @ErrorTecnico);
|
||||
END CATCH;
|
||||
END;
|
||||
GO
|
||||
```
|
||||
|
||||
Cuando el procedimiento use una transacción, debe incluir `BEGIN TRANSACTION` dentro de `TRY` y `COMMIT TRANSACTION` antes de establecer `@Return = 1`.
|
||||
Reference in New Issue
Block a user