Feat Varios 3

This commit is contained in:
2026-01-06 10:34:06 -03:00
parent 0fa77e4a98
commit 9fa21ebec3
65 changed files with 2897 additions and 373 deletions

View File

@@ -116,9 +116,181 @@ BEGIN
);
END
";
// Ejecutar creación de tablas
// Ejecutar creación de tablas base
await connection.ExecuteAsync(schemaSql);
// --- MIGRACIONES (Schema Update) ---
var migrationSql = @"
-- Listings Columns
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'PublicationStartDate' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD PublicationStartDate DATETIME2 NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'ApprovedAt' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD ApprovedAt DATETIME2 NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'IsFeatured' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD IsFeatured BIT NOT NULL DEFAULT 0;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'FeaturedExpiry' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD FeaturedExpiry DATETIME2 NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'AllowContact' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD AllowContact BIT NOT NULL DEFAULT 1;
-- Users Columns (Security & Profiles)
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'BillingName' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD BillingName NVARCHAR(200) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'BillingAddress' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD BillingAddress NVARCHAR(500) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'BillingTaxId' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD BillingTaxId NVARCHAR(50) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'BillingTaxType' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD BillingTaxType NVARCHAR(50) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'ClientId' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD ClientId INT NULL;
-- Audit & Security Columns for Users
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'FailedLoginAttempts' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD FailedLoginAttempts INT NOT NULL DEFAULT 0;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'LockoutEnd' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD LockoutEnd DATETIME NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'MustChangePassword' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD MustChangePassword BIT NOT NULL DEFAULT 1;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'IsActive' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD IsActive BIT NOT NULL DEFAULT 1;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'LastLogin' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD LastLogin DATETIME NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'GoogleId' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD GoogleId NVARCHAR(255) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'IsMfaEnabled' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD IsMfaEnabled BIT NOT NULL DEFAULT 0;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'MfaSecret' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD MfaSecret NVARCHAR(255) NULL;
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'Phone' AND Object_ID = Object_ID(N'Users'))
ALTER TABLE Users ADD Phone NVARCHAR(50) NULL;
-- Coupons Table
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Coupons')
BEGIN
CREATE TABLE Coupons (
Id INT IDENTITY(1,1) PRIMARY KEY,
Code NVARCHAR(50) NOT NULL,
DiscountType NVARCHAR(20) NOT NULL,
DiscountValue DECIMAL(18,2) NOT NULL,
ExpiryDate DATETIME2 NULL,
UsageCount INT NOT NULL DEFAULT 0,
MaxUsages INT NULL,
IsActive BIT NOT NULL DEFAULT 1,
CreatedAt DATETIME2 NOT NULL DEFAULT GETUTCDATE()
);
CREATE UNIQUE INDEX IX_Coupons_Code ON Coupons(Code);
-- Seed Default Coupon
INSERT INTO Coupons (Code, DiscountType, DiscountValue) VALUES ('WELCOME2025', 'Percentage', 10.00);
END
-- Listings CouponCode
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'CouponCode' AND Object_ID = Object_ID(N'Listings'))
ALTER TABLE Listings ADD CouponCode NVARCHAR(50) NULL;
-- Coupons MaxUsagesPerUser
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'MaxUsagesPerUser' AND Object_ID = Object_ID(N'Coupons'))
ALTER TABLE Coupons ADD MaxUsagesPerUser INT NULL;
-- Tabla de Notas/Mensajes de Avisos
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'ListingNotes') AND type in (N'U'))
BEGIN
CREATE TABLE ListingNotes (
Id INT IDENTITY(1,1) PRIMARY KEY,
ListingId INT NOT NULL,
SenderId INT NOT NULL,
IsFromModerator BIT NOT NULL DEFAULT 1,
Message NVARCHAR(MAX) NOT NULL,
CreatedAt DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
IsRead BIT NOT NULL DEFAULT 0,
FOREIGN KEY (ListingId) REFERENCES Listings(Id) ON DELETE CASCADE,
FOREIGN KEY (SenderId) REFERENCES Users(Id)
);
END
ELSE
BEGIN
-- Migración gradual si la tabla ya existía con ModeratorId
IF EXISTS(SELECT * FROM sys.columns WHERE Name = N'ModeratorId' AND Object_ID = Object_ID(N'ListingNotes'))
BEGIN
EXEC sp_rename 'ListingNotes.ModeratorId', 'SenderId', 'COLUMN';
END
IF NOT EXISTS(SELECT * FROM sys.columns WHERE Name = N'IsFromModerator' AND Object_ID = Object_ID(N'ListingNotes'))
BEGIN
ALTER TABLE ListingNotes ADD IsFromModerator BIT NOT NULL DEFAULT 1;
END
END
";
await connection.ExecuteAsync(migrationSql);
// --- MIGRACIÓN DE DATOS (Post-Schema Update) ---
var dataMigrationSql = @"
-- Data Migration: Clients to Users
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Clients')
BEGIN
-- Verificamos si la tabla Clients tiene la columna Phone para evitar errores
DECLARE @phoneColumnExists BIT = 0;
IF EXISTS(SELECT * FROM sys.columns WHERE Name = N'Phone' AND Object_ID = Object_ID(N'Clients'))
SET @phoneColumnExists = 1;
IF @phoneColumnExists = 1
BEGIN
INSERT INTO Users (Username, PasswordHash, Role, Email, BillingName, BillingTaxId, BillingAddress, Phone, MustChangePassword, IsActive)
SELECT
ISNULL(DniOrCuit, Name) as Username,
'N/A' as PasswordHash,
'Client' as Role,
Email,
Name as BillingName,
DniOrCuit as BillingTaxId,
Address as BillingAddress,
Phone,
0 as MustChangePassword,
1 as IsActive
FROM Clients
WHERE DniOrCuit NOT IN (SELECT BillingTaxId FROM Users WHERE BillingTaxId IS NOT NULL);
END
ELSE
BEGIN
INSERT INTO Users (Username, PasswordHash, Role, Email, BillingName, BillingTaxId, BillingAddress, MustChangePassword, IsActive)
SELECT
ISNULL(DniOrCuit, Name) as Username,
'N/A' as PasswordHash,
'Client' as Role,
Email,
Name as BillingName,
DniOrCuit as BillingTaxId,
Address as BillingAddress,
0 as MustChangePassword,
1 as IsActive
FROM Clients
WHERE DniOrCuit NOT IN (SELECT BillingTaxId FROM Users WHERE BillingTaxId IS NOT NULL);
END
-- 1. Actualizar Listings para que apunten a Users antes de romper nada (opcional pero recomendado si hay datos)
-- Solo lo hacemos para los que ya existen en Users por BillingTaxId
UPDATE l
SET l.ClientId = u.Id
FROM Listings l
JOIN Clients c ON l.ClientId = c.Id
JOIN Users u ON c.DniOrCuit = u.BillingTaxId;
-- 2. Eliminar todas las llaves foráneas que apuntan a Clients
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(parent_object_id)) +
' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
FROM sys.foreign_keys
WHERE referenced_object_id = OBJECT_ID('Clients');
IF @sql <> '' EXEC sp_executesql @sql;
-- 3. Finalmente borrar la tabla
DROP TABLE Clients;
END
";
await connection.ExecuteAsync(dataMigrationSql);
// --- SEED DE DATOS (Usuario Admin) ---
var adminCount = await connection.ExecuteScalarAsync<int>("SELECT COUNT(1) FROM Users WHERE Username = 'admin'");

View File

@@ -0,0 +1,69 @@
-- Run this script to update the database schema
-- Update Listings table
ALTER TABLE Listings ADD PublicationStartDate DATETIME2 NULL;
ALTER TABLE Listings ADD ApprovedAt DATETIME2 NULL;
ALTER TABLE Listings ADD IsFeatured BIT NOT NULL DEFAULT 0;
ALTER TABLE Listings ADD FeaturedExpiry DATETIME2 NULL;
ALTER TABLE Listings ADD AllowContact BIT NOT NULL DEFAULT 1;
-- Update Users table
ALTER TABLE Users ADD BillingName NVARCHAR(200) NULL;
ALTER TABLE Users ADD BillingAddress NVARCHAR(500) NULL;
ALTER TABLE Users ADD BillingTaxId NVARCHAR(50) NULL;
ALTER TABLE Users ADD BillingTaxType NVARCHAR(50) NULL;
ALTER TABLE Users ADD ClientId INT NULL;
ALTER TABLE Users ADD FailedLoginAttempts INT NOT NULL DEFAULT 0;
ALTER TABLE Users ADD LockoutEnd DATETIME NULL;
ALTER TABLE Users ADD MustChangePassword BIT NOT NULL DEFAULT 1;
ALTER TABLE Users ADD IsActive BIT NOT NULL DEFAULT 1;
ALTER TABLE Users ADD LastLogin DATETIME NULL;
ALTER TABLE Users ADD GoogleId NVARCHAR(255) NULL;
ALTER TABLE Users ADD IsMfaEnabled BIT NOT NULL DEFAULT 0;
ALTER TABLE Users ADD MfaSecret NVARCHAR(255) NULL;
ALTER TABLE Users ADD Phone NVARCHAR(50) NULL;
-- Create Coupons table
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Coupons' and xtype='U')
BEGIN
CREATE TABLE Coupons (
Id INT IDENTITY(1,1) PRIMARY KEY,
Code NVARCHAR(50) NOT NULL,
DiscountType NVARCHAR(20) NOT NULL,
DiscountValue DECIMAL(18,2) NOT NULL,
ExpiryDate DATETIME2 NULL,
UsageCount INT NOT NULL DEFAULT 0,
MaxUsages INT NULL,
IsActive BIT NOT NULL DEFAULT 1,
CreatedAt DATETIME2 NOT NULL DEFAULT GETUTCDATE()
);
CREATE UNIQUE INDEX IX_Coupons_Code ON Coupons(Code);
END
-- Data Migration and Consolidation
-- Copy clients to users if they don't exist
INSERT INTO Users (Username, PasswordHash, Role, Email, BillingName, BillingTaxId, BillingAddress, Phone, MustChangePassword, IsActive)
SELECT
ISNULL(DniOrCuit, Name), 'N/A', 'Client', Email, Name, DniOrCuit, Address, Phone, 0, 1
FROM Clients
WHERE DniOrCuit NOT IN (SELECT BillingTaxId FROM Users WHERE BillingTaxId IS NOT NULL);
-- Update Listings to point to new User IDs
UPDATE l
SET l.ClientId = u.Id
FROM Listings l
JOIN Clients c ON l.ClientId = c.Id
JOIN Users u ON c.DniOrCuit = u.BillingTaxId;
-- Drop foreign keys referencing Clients
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(parent_object_id)) +
' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
FROM sys.foreign_keys
WHERE referenced_object_id = OBJECT_ID('Clients');
IF @sql <> '' EXEC sp_executesql @sql;
-- DROP obsolete table
IF EXISTS (SELECT * FROM sysobjects WHERE name='Clients' and xtype='U')
DROP TABLE Clients;