chore(prc-001): followups #54 #55 #57 #58 + cierre #52 #53 #60

Merged
dmolinari merged 1 commits from chore/prc-001-followups into main 2026-04-21 16:28:29 +00:00
Owner

Resumen

Resuelve los 6 followups post-archive de PRC-001 (excepto #56 que queda para FAC-001).

# Decisión/Fix Cierre
#52 R1.7 hyphens Confirmado: default = 2 palabras (coincide con impl actual) Cerrado sin código
#53 GC-24 all-specials Confirmado: TotalWords=0 + conteo por categoría es correcto Cerrado sin código
#54 Seeds demo per-ProductType V025 con overrides ficticios idempotentes (Clasificado/Notables/Fúnebres) Código
#55 Emoji en Symbol No se permiten (decisión negocio). Validator usa WordCounterService.ContainsEmoji Código
#57 FluentValidation opt-in PricePerUnit >= 0 (alineado con CK_Price_NonNegative de V023) Código
#58 tsconfig + MSW ignoreDeprecations: "6.0" agregado (MSW handler ya existente, sin cambios necesarios) Código

Cambios técnicos

Backend

  • src/api/SIGCM2.Domain/Pricing/WordCounter/WordCounterService.cs: nuevo método público ContainsEmoji(string?) que reutiliza IsEmojiRune para detección de emoji en cualquier string. Permite reuso desde validators.
  • src/api/SIGCM2.Application/Pricing/ChargeableChars/Create/CreateChargeableCharConfigCommandValidator.cs:
    • Symbol: nueva regla .Must(s => !WordCounterService.ContainsEmoji(s)) con mensaje claro.
    • PricePerUnit: GreaterThan(0m)GreaterThanOrEqualTo(0m) con mensaje que documenta la semántica "0 = desactiva cobro (opt-in billing)".

BD

  • database/migrations/V025__seed_chargeable_char_overrides_demo.sql: MERGE idempotente. Para cada uno de los 3 ProductTypes (Clasificado/Notables/Fúnebres), si existe activo, inserta overrides con precios ficticios. Si el tipo no existe, bloque correspondiente es no-op.
  • V025_ROLLBACK.sql: elimina overrides demo preservando globales.
  • Aplicado en las 3 DBs (SIGCM2 + Test_App + Test_Api).
  • database/README.md: V025 agregada al índice de migraciones.

Frontend

  • src/web/tsconfig.json: "ignoreDeprecations": "6.0" para silenciar warning TS5101 (baseUrl deprecation en TS 6.x).

Tests

  • tests/SIGCM2.Application.Tests/Pricing/ChargeableChars/CreateChargeableCharConfigCommandValidatorTests.cs:
    • PricePerUnit_Zero_Passes_OptInBilling (antes _FailsValidation, ahora documenta la intención opt-in)
    • Symbol_WithEmoji_FailsValidation[Theory] con 5 emojis (😀 🚗 🔥 ❤️ ☀️)
    • Symbol_WithoutEmoji_Passes[Theory] con 8 plain symbols
  • tests/SIGCM2.Api.Tests/Pricing/ChargeableChars/ChargeableCharConfigControllerTests.cs:
    • Post_InvalidPrice_Returns400ValidationFailure: usa -1 en lugar de 0 (ya que 0 es válido)
    • Post_WithEmojiSymbol_Returns400 (antes _Returns201_BecauseEmojiRejectionIsDeferred)

Verify

  • dotnet test: 1659/1659 green (1310 Application + 349 Api)
  • cd src/web && npx vitest run: 510/510 green
  • cd src/web && npx tsc --noEmit: 0 errors, 0 warnings (TS5101 silenciado)

Issues cerrados

Closes #52, #53, #54, #55, #57, #58.

Quedan abiertos:

  • #56 — FAC-001 guards (heredado, se cierra cuando se implemente FAC-001; recordatorio en callout [!important] del UDT doc + label followup).
## Resumen Resuelve los 6 followups post-archive de PRC-001 (excepto #56 que queda para FAC-001). | # | Decisión/Fix | Cierre | |---|---|---| | **#52** R1.7 hyphens | Confirmado: default = 2 palabras (coincide con impl actual) | Cerrado sin código | | **#53** GC-24 all-specials | Confirmado: `TotalWords=0` + conteo por categoría es correcto | Cerrado sin código | | **#54** Seeds demo per-ProductType | **V025** con overrides ficticios idempotentes (Clasificado/Notables/Fúnebres) | ✅ Código | | **#55** Emoji en Symbol | **No se permiten** (decisión negocio). Validator usa `WordCounterService.ContainsEmoji` | ✅ Código | | **#57** FluentValidation opt-in | `PricePerUnit >= 0` (alineado con `CK_Price_NonNegative` de V023) | ✅ Código | | **#58** tsconfig + MSW | `ignoreDeprecations: "6.0"` agregado (MSW handler ya existente, sin cambios necesarios) | ✅ Código | ## Cambios técnicos ### Backend - `src/api/SIGCM2.Domain/Pricing/WordCounter/WordCounterService.cs`: nuevo método público `ContainsEmoji(string?)` que reutiliza `IsEmojiRune` para detección de emoji en cualquier string. Permite reuso desde validators. - `src/api/SIGCM2.Application/Pricing/ChargeableChars/Create/CreateChargeableCharConfigCommandValidator.cs`: - **Symbol**: nueva regla `.Must(s => !WordCounterService.ContainsEmoji(s))` con mensaje claro. - **PricePerUnit**: `GreaterThan(0m)` → `GreaterThanOrEqualTo(0m)` con mensaje que documenta la semántica "0 = desactiva cobro (opt-in billing)". ### BD - `database/migrations/V025__seed_chargeable_char_overrides_demo.sql`: MERGE idempotente. Para cada uno de los 3 ProductTypes (Clasificado/Notables/Fúnebres), si existe activo, inserta overrides con precios ficticios. Si el tipo no existe, bloque correspondiente es no-op. - `V025_ROLLBACK.sql`: elimina overrides demo preservando globales. - **Aplicado en las 3 DBs** (SIGCM2 + Test_App + Test_Api). - `database/README.md`: V025 agregada al índice de migraciones. ### Frontend - `src/web/tsconfig.json`: `"ignoreDeprecations": "6.0"` para silenciar warning TS5101 (baseUrl deprecation en TS 6.x). ### Tests - `tests/SIGCM2.Application.Tests/Pricing/ChargeableChars/CreateChargeableCharConfigCommandValidatorTests.cs`: - `PricePerUnit_Zero_Passes_OptInBilling` (antes `_FailsValidation`, ahora documenta la intención opt-in) - `Symbol_WithEmoji_FailsValidation` — `[Theory]` con 5 emojis (😀 🚗 🔥 ❤️ ☀️) - `Symbol_WithoutEmoji_Passes` — `[Theory]` con 8 plain symbols - `tests/SIGCM2.Api.Tests/Pricing/ChargeableChars/ChargeableCharConfigControllerTests.cs`: - `Post_InvalidPrice_Returns400ValidationFailure`: usa `-1` en lugar de `0` (ya que 0 es válido) - `Post_WithEmojiSymbol_Returns400` (antes `_Returns201_BecauseEmojiRejectionIsDeferred`) ## Verify - `dotnet test`: **1659/1659 green** (1310 Application + 349 Api) - `cd src/web && npx vitest run`: **510/510 green** - `cd src/web && npx tsc --noEmit`: **0 errors, 0 warnings** (TS5101 silenciado) ## Issues cerrados Closes #52, #53, #54, #55, #57, #58. Quedan abiertos: - **#56** — FAC-001 guards (heredado, se cierra cuando se implemente FAC-001; recordatorio en callout `[!important]` del UDT doc + label `followup`).
dmolinari added 1 commit 2026-04-21 16:28:23 +00:00
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.
dmolinari merged commit dfeb5fb7e1 into main 2026-04-21 16:28:29 +00:00
dmolinari deleted branch chore/prc-001-followups 2026-04-21 16:28:29 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dmolinari/SIG-CM2.0#60