- WordCounterService: pure domain service, 7-step algorithm (null/empty fast path → length check → emoji detection via Rune.EnumerateRunes → count specials before replace → replace specials+hyphens → collapse whitespace → tokenize) - WordCountResult: sealed record with TotalWords + IReadOnlyDictionary<string,int> SpecialCharCounts - 4 domain exceptions extending DomainException: EmojiDetectedException, WordCountValidationException, ChargeableCharConfigInvalidException, ChargeableCharConfigForwardOnlyException - ChargeableCharConfig: rich entity with Create factory (invariants), Rehydrate reconstructor, ScheduleNewPrice (forward-only, returns new entity), Deactivate (idempotent) - ChargeableCharCategories: enum-as-string constants (Currency, Percentage, Exclamation, Question, Other) - DomainTimeProviderExtensions: internal GetArgentinaToday helper (mirrors Application.Common without creating Domain→Application dependency) - 60 new tests: 25 golden cases all GREEN, 12 entity invariant tests, 12 exception tests, 5 WordCountResult tests, 6 ChargeableCharConfig entity tests
11 lines
462 B
C#
11 lines
462 B
C#
namespace SIGCM2.Domain.Pricing.WordCounter;
|
|
|
|
/// <summary>
|
|
/// PRC-001 — Immutable value object representing the result of a word count operation.
|
|
/// TotalWords: number of whitespace-separated tokens after normalization.
|
|
/// SpecialCharCounts: map of category name → occurrence count in the ORIGINAL (pre-normalization) text.
|
|
/// </summary>
|
|
public sealed record WordCountResult(
|
|
int TotalWords,
|
|
IReadOnlyDictionary<string, int> SpecialCharCounts);
|