Resuelve 4 de los followups creados post-archive de PRC-001: #55 — Decisión de negocio (2026-04-21): emojis NO se permiten en Symbol config. - WordCounterService.ContainsEmoji(string): helper publico que reutiliza los rangos Unicode de IsEmojiRune (Emoticons, Pictographs, Dingbats, VS-16, ZWJ). - CreateChargeableCharConfigCommandValidator: regla .Must que rechaza emoji en Symbol con mensaje claro. Defensiva: cubre clientes directos al API (Postman, adversariales) mas alla del SymbolInput blocker del frontend. - Tests: 5 emojis positivos (smile/car/fire/heart VS-16/sun) + 8 plain symbols ($, %, !, ¡, @, €, ##, ABCD) + actualizacion del Api test E2E (Post_WithEmojiSymbol). #57 — Alineacion FluentValidation con opt-in billing (CK_Price_NonNegative >= 0). - CreateChargeableCharConfigCommandValidator.PricePerUnit: GreaterThan(0) -> GreaterThanOrEqualTo(0). Mensaje explica el significado: 0 = no cobra. - Tests actualizados: PricePerUnit_Zero ahora Passes (era Fails). Negative sigue fallando. Api e2e usa -1 para el caso de rechazo. #58 — tsconfig ignoreDeprecations + MSW handler (parte a). - src/web/tsconfig.json: agrega "ignoreDeprecations": "6.0" para silenciar el warning TS5101 del baseUrl deprecated en TS 6.x. - (El MSW handler de /api/v1/admin/product-types no aplica — los tests ya mockean ProductTypeSelect directamente; warning residual no existe.) #54 — Seeder demo de overrides ficticios per-ProductType (V025). - database/migrations/V025__seed_chargeable_char_overrides_demo.sql: MERGE idempotente que crea overrides de ChargeableCharConfig para ProductTypes Clasificado/Notables/Fúnebres si existen en la DB. Precios ficticios ($ 5-8, % 3-5, ! 2-4, ¡ 2-4). No-op si los tipos no estan seedados (sera cuando PRD-008 haga seed de los 12 legacy). - V025_ROLLBACK.sql: elimina overrides demo preservando globales. - Aplicado en SIGCM2, SIGCM2_Test_App, SIGCM2_Test_Api. - database/README.md: V025 agregada al indice. Tests: 1659 .NET (1310 Application + 349 Api) + 510 vitest — todos GREEN. Closes #54, #55, #57, #58.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
-- V025__seed_chargeable_char_overrides_demo.sql
|
||||
-- PRC-001 followup #54: seeders de demo con valores ficticios per-ProductType.
|
||||
--
|
||||
-- Estrategia:
|
||||
-- 1. Los 4 globales de V022+V024 quedan en 0.0000 (opt-in billing baseline).
|
||||
-- 2. Para ProductTypes conocidos del roadmap (Clasificado, Notables, Fúnebres),
|
||||
-- inserta overrides con precios ficticios coherentes con datos de demo del resto
|
||||
-- del proyecto. Si el ProductType no existe, el bloque correspondiente no hace nada.
|
||||
-- 3. Cuando PRD-008 seede los 12 tipos legacy, V025 puede re-aplicarse y creará
|
||||
-- los overrides que falten (MERGE idempotente).
|
||||
--
|
||||
-- Precios ficticios (placeholders de demo — NO son tarifas reales):
|
||||
-- Clasificado: $ = 5.0000, % = 3.0000, ! = 2.0000, ¡ = 2.0000
|
||||
-- Notables: $ = 8.0000, % = 5.0000, ! = 4.0000, ¡ = 4.0000
|
||||
-- Fúnebres: $ = 6.0000, % = 4.0000, ! = 3.5000, ¡ = 3.5000
|
||||
--
|
||||
-- Reversa: V025_ROLLBACK.sql (elimina los overrides demo dejando solo los globales V022/V024).
|
||||
-- Run on: SIGCM2 (dev), SIGCM2_Test_App, SIGCM2_Test_Api.
|
||||
-- Idempotente: usa MERGE por (ProductTypeId, Symbol, ValidTo IS NULL).
|
||||
|
||||
SET QUOTED_IDENTIFIER ON;
|
||||
SET ANSI_NULLS ON;
|
||||
SET NOCOUNT ON;
|
||||
GO
|
||||
|
||||
DECLARE @ClasificadoId INT = (SELECT TOP 1 Id FROM dbo.ProductType WHERE Nombre = 'Clasificado' AND IsActive = 1);
|
||||
DECLARE @NotablesId INT = (SELECT TOP 1 Id FROM dbo.ProductType WHERE Nombre = 'Notables' AND IsActive = 1);
|
||||
DECLARE @FunebresId INT = (SELECT TOP 1 Id FROM dbo.ProductType WHERE Nombre IN ('Fúnebres','Funebres') AND IsActive = 1);
|
||||
|
||||
DECLARE @DemoValidFrom DATE = '2026-01-01';
|
||||
|
||||
-- Clasificado overrides
|
||||
IF @ClasificadoId IS NOT NULL
|
||||
BEGIN
|
||||
MERGE dbo.ChargeableCharConfig AS t
|
||||
USING (VALUES
|
||||
(@ClasificadoId, N'$', N'Currency', CAST(5.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@ClasificadoId, N'%', N'Percentage', CAST(3.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@ClasificadoId, N'!', N'Exclamation', CAST(2.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@ClasificadoId, N'¡', N'Exclamation', CAST(2.0000 AS DECIMAL(18,4)), @DemoValidFrom)
|
||||
) AS s (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom)
|
||||
ON (t.ProductTypeId = s.ProductTypeId AND t.Symbol = s.Symbol AND t.ValidTo IS NULL)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom, ValidTo, IsActive)
|
||||
VALUES (s.ProductTypeId, s.Symbol, s.Category, s.PricePerUnit, s.ValidFrom, NULL, 1);
|
||||
PRINT 'V025: Clasificado overrides seeded (ProductTypeId=' + CAST(@ClasificadoId AS NVARCHAR(10)) + ').';
|
||||
END
|
||||
ELSE
|
||||
PRINT 'V025: ProductType "Clasificado" not found — skipping Clasificado overrides.';
|
||||
GO
|
||||
|
||||
DECLARE @NotablesId INT = (SELECT TOP 1 Id FROM dbo.ProductType WHERE Nombre = 'Notables' AND IsActive = 1);
|
||||
DECLARE @DemoValidFrom DATE = '2026-01-01';
|
||||
|
||||
-- Notables overrides
|
||||
IF @NotablesId IS NOT NULL
|
||||
BEGIN
|
||||
MERGE dbo.ChargeableCharConfig AS t
|
||||
USING (VALUES
|
||||
(@NotablesId, N'$', N'Currency', CAST(8.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@NotablesId, N'%', N'Percentage', CAST(5.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@NotablesId, N'!', N'Exclamation', CAST(4.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@NotablesId, N'¡', N'Exclamation', CAST(4.0000 AS DECIMAL(18,4)), @DemoValidFrom)
|
||||
) AS s (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom)
|
||||
ON (t.ProductTypeId = s.ProductTypeId AND t.Symbol = s.Symbol AND t.ValidTo IS NULL)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom, ValidTo, IsActive)
|
||||
VALUES (s.ProductTypeId, s.Symbol, s.Category, s.PricePerUnit, s.ValidFrom, NULL, 1);
|
||||
PRINT 'V025: Notables overrides seeded (ProductTypeId=' + CAST(@NotablesId AS NVARCHAR(10)) + ').';
|
||||
END
|
||||
ELSE
|
||||
PRINT 'V025: ProductType "Notables" not found — skipping Notables overrides.';
|
||||
GO
|
||||
|
||||
DECLARE @FunebresId INT = (SELECT TOP 1 Id FROM dbo.ProductType WHERE Nombre IN ('Fúnebres','Funebres') AND IsActive = 1);
|
||||
DECLARE @DemoValidFrom DATE = '2026-01-01';
|
||||
|
||||
-- Fúnebres overrides
|
||||
IF @FunebresId IS NOT NULL
|
||||
BEGIN
|
||||
MERGE dbo.ChargeableCharConfig AS t
|
||||
USING (VALUES
|
||||
(@FunebresId, N'$', N'Currency', CAST(6.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@FunebresId, N'%', N'Percentage', CAST(4.0000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@FunebresId, N'!', N'Exclamation', CAST(3.5000 AS DECIMAL(18,4)), @DemoValidFrom),
|
||||
(@FunebresId, N'¡', N'Exclamation', CAST(3.5000 AS DECIMAL(18,4)), @DemoValidFrom)
|
||||
) AS s (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom)
|
||||
ON (t.ProductTypeId = s.ProductTypeId AND t.Symbol = s.Symbol AND t.ValidTo IS NULL)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (ProductTypeId, Symbol, Category, PricePerUnit, ValidFrom, ValidTo, IsActive)
|
||||
VALUES (s.ProductTypeId, s.Symbol, s.Category, s.PricePerUnit, s.ValidFrom, NULL, 1);
|
||||
PRINT 'V025: Fúnebres overrides seeded (ProductTypeId=' + CAST(@FunebresId AS NVARCHAR(10)) + ').';
|
||||
END
|
||||
ELSE
|
||||
PRINT 'V025: ProductType "Fúnebres/Funebres" not found — skipping Fúnebres overrides.';
|
||||
GO
|
||||
|
||||
PRINT '';
|
||||
PRINT 'V025 applied — demo overrides (fictitious prices) seeded for ProductTypes: Clasificado, Notables, Fúnebres (only where they exist).';
|
||||
PRINT 'NOTE: Los 4 globales (V022/V024) quedan intactos en 0.0000. Estos overrides son PLACEHOLDERS DE DEMO — reemplazar antes de go-live.';
|
||||
GO
|
||||
Reference in New Issue
Block a user