using line_gestao_api.Data; using Microsoft.EntityFrameworkCore; namespace line_gestao_api.Services; public sealed class MveAuditSchemaBootstrapper { private readonly AppDbContext _db; public MveAuditSchemaBootstrapper(AppDbContext db) { _db = db; } public async Task EnsureSchemaAsync(CancellationToken cancellationToken = default) { await _db.Database.ExecuteSqlRawAsync( """ ALTER TABLE "Aparelhos" ADD COLUMN IF NOT EXISTS "Fabricante" character varying(120) NULL; """, cancellationToken); await _db.Database.ExecuteSqlRawAsync( """ CREATE INDEX IF NOT EXISTS "IX_Aparelhos_TenantId_Fabricante" ON "Aparelhos" ("TenantId", "Fabricante"); """, cancellationToken); await _db.Database.ExecuteSqlRawAsync( """ CREATE TABLE IF NOT EXISTS "MveAuditRuns" ( "Id" uuid NOT NULL, "TenantId" uuid NOT NULL, "FileName" character varying(260) NULL, "FileHashSha256" character varying(64) NULL, "FileEncoding" character varying(40) NULL, "Status" character varying(40) NOT NULL, "TotalSystemLines" integer NOT NULL, "TotalReportLines" integer NOT NULL, "TotalConciliated" integer NOT NULL, "TotalStatusDivergences" integer NOT NULL, "TotalDataDivergences" integer NOT NULL, "TotalOnlyInSystem" integer NOT NULL, "TotalOnlyInReport" integer NOT NULL, "TotalDuplicateReportLines" integer NOT NULL, "TotalDuplicateSystemLines" integer NOT NULL, "TotalInvalidRows" integer NOT NULL, "TotalUnknownStatuses" integer NOT NULL, "TotalSyncableIssues" integer NOT NULL, "AppliedIssuesCount" integer NOT NULL, "AppliedLinesCount" integer NOT NULL, "AppliedFieldsCount" integer NOT NULL, "ImportedAtUtc" timestamp with time zone NOT NULL, "AppliedAtUtc" timestamp with time zone NULL, "AppliedByUserId" uuid NULL, "AppliedByUserName" character varying(200) NULL, "AppliedByUserEmail" character varying(200) NULL, CONSTRAINT "PK_MveAuditRuns" PRIMARY KEY ("Id") ); """, cancellationToken); await _db.Database.ExecuteSqlRawAsync( """ CREATE TABLE IF NOT EXISTS "MveAuditIssues" ( "Id" uuid NOT NULL, "TenantId" uuid NOT NULL, "AuditRunId" uuid NOT NULL, "SourceRowNumber" integer NULL, "NumeroLinha" character varying(64) NOT NULL, "MobileLineId" uuid NULL, "SystemItem" integer NULL, "IssueType" character varying(60) NOT NULL, "Situation" character varying(80) NOT NULL, "Severity" character varying(40) NOT NULL, "Syncable" boolean NOT NULL, "Applied" boolean NOT NULL, "AppliedAtUtc" timestamp with time zone NULL, "ActionSuggestion" character varying(160) NULL, "Notes" character varying(500) NULL, "SystemStatus" character varying(120) NULL, "ReportStatus" character varying(120) NULL, "SystemPlan" character varying(200) NULL, "ReportPlan" character varying(200) NULL, "SystemSnapshotJson" jsonb NOT NULL, "ReportSnapshotJson" jsonb NOT NULL, "DifferencesJson" jsonb NOT NULL, "CreatedAtUtc" timestamp with time zone NOT NULL, CONSTRAINT "PK_MveAuditIssues" PRIMARY KEY ("Id") ); """, cancellationToken); await _db.Database.ExecuteSqlRawAsync( """ DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'FK_MveAuditIssues_MveAuditRuns_AuditRunId' ) THEN ALTER TABLE "MveAuditIssues" ADD CONSTRAINT "FK_MveAuditIssues_MveAuditRuns_AuditRunId" FOREIGN KEY ("AuditRunId") REFERENCES "MveAuditRuns" ("Id") ON DELETE CASCADE; END IF; END $$; """, cancellationToken); await _db.Database.ExecuteSqlRawAsync( """ CREATE INDEX IF NOT EXISTS "IX_MveAuditIssues_AuditRunId" ON "MveAuditIssues" ("AuditRunId"); CREATE INDEX IF NOT EXISTS "IX_MveAuditIssues_IssueType" ON "MveAuditIssues" ("IssueType"); CREATE INDEX IF NOT EXISTS "IX_MveAuditIssues_NumeroLinha" ON "MveAuditIssues" ("NumeroLinha"); CREATE INDEX IF NOT EXISTS "IX_MveAuditIssues_Syncable" ON "MveAuditIssues" ("Syncable"); CREATE INDEX IF NOT EXISTS "IX_MveAuditIssues_TenantId" ON "MveAuditIssues" ("TenantId"); CREATE INDEX IF NOT EXISTS "IX_MveAuditRuns_ImportedAtUtc" ON "MveAuditRuns" ("ImportedAtUtc"); CREATE INDEX IF NOT EXISTS "IX_MveAuditRuns_Status" ON "MveAuditRuns" ("Status"); CREATE INDEX IF NOT EXISTS "IX_MveAuditRuns_TenantId" ON "MveAuditRuns" ("TenantId"); """, cancellationToken); } }