using Microsoft.EntityFrameworkCore; namespace HealthManager.Infrastructure.Data; public static class MigrationHelper { public static async Task EnsureNewTablesAsync(AppDbContext db) { var sql = """ CREATE TABLE IF NOT EXISTS "VerificationCodes" ( "Id" uuid PRIMARY KEY, "Phone" text NOT NULL, "Code" text NOT NULL, "Type" text NOT NULL DEFAULT 'login', "ExpiresAt" timestamptz NOT NULL, "IsUsed" boolean NOT NULL DEFAULT FALSE, "CreatedAt" timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS "IX_VerificationCodes_ExpiresAt" ON "VerificationCodes" ("ExpiresAt"); CREATE INDEX IF NOT EXISTS "IX_VerificationCodes_Phone_Type" ON "VerificationCodes" ("Phone", "Type"); CREATE TABLE IF NOT EXISTS "RateLimitEntries" ( "Id" uuid PRIMARY KEY, "Key" text NOT NULL, "Count" integer NOT NULL, "WindowStart" timestamptz NOT NULL, "ExpiresAt" timestamptz NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS "IX_RateLimitEntries_Key_WindowStart" ON "RateLimitEntries" ("Key", "WindowStart"); CREATE INDEX IF NOT EXISTS "IX_RateLimitEntries_ExpiresAt" ON "RateLimitEntries" ("ExpiresAt"); CREATE TABLE IF NOT EXISTS "TokenBlacklistEntries" ( "Id" uuid PRIMARY KEY, "Jti" text NOT NULL, "UserId" uuid NOT NULL, "ExpiresAt" timestamptz NOT NULL, "CreatedAt" timestamptz NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX IF NOT EXISTS "IX_TokenBlacklistEntries_Jti" ON "TokenBlacklistEntries" ("Jti"); CREATE INDEX IF NOT EXISTS "IX_TokenBlacklistEntries_ExpiresAt" ON "TokenBlacklistEntries" ("ExpiresAt"); CREATE TABLE IF NOT EXISTS "CacheEntries" ( "Id" uuid PRIMARY KEY, "Key" text NOT NULL, "Value" jsonb NOT NULL, "ExpiresAt" timestamptz NOT NULL, "CreatedAt" timestamptz NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX IF NOT EXISTS "IX_CacheEntries_Key" ON "CacheEntries" ("Key"); CREATE INDEX IF NOT EXISTS "IX_CacheEntries_ExpiresAt" ON "CacheEntries" ("ExpiresAt"); """; await db.Database.ExecuteSqlRawAsync(sql); } }