Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,47 @@ services:
start_period: 30s
restart: unless-stopped

# ---------------------------------------------------------------------------
# Inicialização do banco — roda os scripts SQL na ordem correta e encerra
# ---------------------------------------------------------------------------
db-init:
image: mcr.microsoft.com/mssql/server:2022-latest
depends_on:
sqlserver:
condition: service_healthy
environment:
SA_PASSWORD: "${SA_PASSWORD:-DataPulseCM@2024!}"
volumes:
- ./database/scripts:/scripts:ro
user: root
entrypoint:
- /bin/bash
- -c
- |
set -e
SQLCMD=/opt/mssql-tools18/bin/sqlcmd
SERVER="sqlserver,1433"
PASS="$$SA_PASSWORD"

echo ">>> Criando banco DataPulseCM..."
$$SQLCMD -S $$SERVER -U sa -P "$$PASS" -No \
-Q "IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'DataPulseCM') CREATE DATABASE [DataPulseCM]"

echo ">>> 01 - Criando tabelas..."
$$SQLCMD -S $$SERVER -U sa -P "$$PASS" -d DataPulseCM -No -i /scripts/01-create-tables.sql

echo ">>> 02 - Criando stored procedures..."
$$SQLCMD -S $$SERVER -U sa -P "$$PASS" -d DataPulseCM -No -i /scripts/02-create-stored-procedures.sql

echo ">>> 03 - Inserindo dados de exemplo..."
$$SQLCMD -S $$SERVER -U sa -P "$$PASS" -d DataPulseCM -No -i /scripts/03-seed-data.sql

echo ">>> 04 - Enriquecendo campos de log..."
$$SQLCMD -S $$SERVER -U sa -P "$$PASS" -d DataPulseCM -No -i /scripts/04-enrich-log-fields.sql

echo ">>> Banco inicializado com sucesso!"
restart: "no"

# ---------------------------------------------------------------------------
# API .NET 9
# ---------------------------------------------------------------------------
Expand All @@ -36,6 +77,8 @@ services:
depends_on:
sqlserver:
condition: service_healthy
db-init:
condition: service_completed_successfully
volumes:
- api_logs:/app/logs
restart: unless-stopped
Expand Down
12 changes: 7 additions & 5 deletions src/EtlMonitoring.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());

// Exception Handler
// Exception Handler (registro opcional + middleware explicito no pipeline)
builder.Services.AddExceptionHandler<GlobalExceptionHandlerMiddleware>();
builder.Services.AddProblemDetails();

Expand Down Expand Up @@ -92,13 +92,15 @@
throw new InvalidOperationException("Connection string 'DefaultConnection' não encontrada.");
}

builder.Services.AddScoped<IJobExecutionRepository>(
provider => new JobExecutionRepository(connectionString)
);
// Registrar fábrica de conexão e repositório via DI
builder.Services.AddTransient<System.Func<Microsoft.Data.SqlClient.SqlConnection>>(provider =>
() => new Microsoft.Data.SqlClient.SqlConnection(connectionString));

builder.Services.AddScoped<IJobExecutionRepository, EtlMonitoring.Infrastructure.Repositories.JobExecutionRepository>();

var app = builder.Build();

// Adicionar Exception Handler no pipeline
// Adicionar Exception Handler no pipeline (usa implementação registrada via AddExceptionHandler)
app.UseExceptionHandler();

// Configurar pipeline HTTP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ namespace EtlMonitoring.Infrastructure.Repositories
{
public class JobExecutionRepository : IJobExecutionRepository
{
private readonly string _connectionString;
private readonly System.Func<Microsoft.Data.SqlClient.SqlConnection> _connectionFactory;

public JobExecutionRepository(string connectionString)
public JobExecutionRepository(System.Func<Microsoft.Data.SqlClient.SqlConnection> connectionFactory)
{
_connectionString = connectionString;
_connectionFactory = connectionFactory;
}

public async Task<long> CreateJobExecutionAsync(string jobName)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var parameters = new DynamicParameters();
parameters.Add("@JobName", jobName);
Expand All @@ -34,7 +34,7 @@ await connection.ExecuteAsync(

public async Task UpdateJobExecutionAsync(long executionId, string status, string? errorMessage = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var parameters = new DynamicParameters();
parameters.Add("@ExecutionId", executionId);
Expand All @@ -50,7 +50,7 @@ await connection.ExecuteAsync(

public async Task<IList<JobExecutionDto>> GetJobExecutionsAsync(JobExecutionFiltrosDto filtros)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var parameters = new DynamicParameters();
parameters.Add("@JobName", filtros.JobName);
Expand All @@ -70,7 +70,7 @@ public async Task<IList<JobExecutionDto>> GetJobExecutionsAsync(JobExecutionFilt

public async Task<JobExecution?> GetJobExecutionByIdAsync(long executionId)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT
Expand Down Expand Up @@ -113,7 +113,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<IEnumerable<JobExecution>> GetRecentExecutionsAsync(int limit = 50)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var result = await connection.QueryAsync<JobExecution>(
"usp_ETL_GetRecentExecutions",
Expand All @@ -126,7 +126,7 @@ public async Task<IEnumerable<JobExecution>> GetRecentExecutionsAsync(int limit

public async Task<int> GetTotalExecutionsAsync(DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT COUNT(*)
Expand All @@ -140,7 +140,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<int> GetSuccessfulExecutionsAsync(DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT COUNT(*)
Expand All @@ -155,7 +155,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<int> GetFailedExecutionsAsync(DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT COUNT(*)
Expand All @@ -170,7 +170,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<decimal> GetSuccessRateAsync(DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT
Expand All @@ -188,7 +188,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<IEnumerable<JobExecution>> GetFailedExecutionsAsync(int limit = 20)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT TOP (@Limit)
Expand Down Expand Up @@ -216,7 +216,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<IDictionary<string, int>> GetExecutionsByStatusAsync(DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT Status, COUNT(*) AS Count
Expand All @@ -231,7 +231,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<JobExecution?> GetLastExecutionByJobNameAsync(string jobName)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT TOP 1
Expand Down Expand Up @@ -259,7 +259,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<IEnumerable<JobExecution>> GetExecutionHistoryByJobNameAsync(string jobName, int limit = 50)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT TOP (@Limit)
Expand Down Expand Up @@ -287,7 +287,7 @@ FROM [dbo].[ETL_JobExecutionLog]

public async Task<decimal> GetJobSuccessRateAsync(string jobName, DateTime? startDate = null, DateTime? endDate = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT
Expand All @@ -307,7 +307,7 @@ FROM [dbo].[ETL_JobExecutionLog]
// Job Execution Details (Steps)
public async Task<long> CreateJobExecutionDetailAsync(long executionId, string stepName, int stepOrder, string? stepMessage = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
INSERT INTO [dbo].[ETL_JobExecutionDetails]
Expand All @@ -329,7 +329,7 @@ INSERT INTO [dbo].[ETL_JobExecutionDetails]

public async Task UpdateJobExecutionDetailAsync(long detailId, string stepStatus, string? stepMessage = null)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
UPDATE [dbo].[ETL_JobExecutionDetails]
Expand All @@ -349,7 +349,7 @@ UPDATE [dbo].[ETL_JobExecutionDetails]

public async Task<IEnumerable<JobExecutionDetail>> GetExecutionDetailsByExecutionIdAsync(long executionId)
{
using var connection = new SqlConnection(_connectionString);
using var connection = _connectionFactory();

var sql = @"
SELECT
Expand Down
Loading