From a7f9b944994833777fb290cb59c9fb1b599cb676 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sat, 4 Jul 2026 02:45:00 +0900 Subject: [PATCH] feat: add message content length validation - Backend: MinMessageLength=10, MaxMessageLength=5000 - Frontend: Real-time character counter - Frontend: Client-side validation before submission - Frontend: Error messages for length violations - Applied to both Submit and Update operations Prevents empty or excessively long messages while maintaining user-friendly feedback on character count. Co-Authored-By: Claude Haiku 4.5 --- .../Services/InquiryService.cs | 21 +++++++- src/TaxBaik.Web/Pages/Contact.cshtml | 53 ++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/TaxBaik.Application/Services/InquiryService.cs b/src/TaxBaik.Application/Services/InquiryService.cs index 94e1987..637045b 100644 --- a/src/TaxBaik.Application/Services/InquiryService.cs +++ b/src/TaxBaik.Application/Services/InquiryService.cs @@ -18,6 +18,9 @@ public class InquiryService( private static readonly Regex PhoneRegex = new( @"^(0(?:2|3[1-3]|4[1-4]|5[1-5]|6[1-4]|70|50[5-9]|[7-9](?:\d{1,2})?)\d{7,8}|0\d{9,10})$"); + private const int MinMessageLength = 10; + private const int MaxMessageLength = 5000; + public async Task SubmitAsync( string name, string phone, string serviceType, string message, string? email = null, string? ipAddress = null, bool suppressNotification = false, CancellationToken ct = default) @@ -34,13 +37,20 @@ public class InquiryService( if (string.IsNullOrWhiteSpace(message)) throw new ValidationException("문의 내용을 입력하세요."); + var trimmedMessage = message.Trim(); + if (trimmedMessage.Length < MinMessageLength) + throw new ValidationException($"문의 내용은 최소 {MinMessageLength}자 이상이어야 합니다."); + + if (trimmedMessage.Length > MaxMessageLength) + throw new ValidationException($"문의 내용은 최대 {MaxMessageLength}자 이하여야 합니다."); + var inquiry = new Inquiry { Name = name.Trim(), Phone = formattedPhone, Email = string.IsNullOrWhiteSpace(email) ? null : email.Trim(), ServiceType = serviceType ?? "기타", - Message = message.Trim(), + Message = trimmedMessage, IpAddress = ipAddress, Status = InquiryStatusMapper.ToStorageValue(InquiryStatus.New), CreatedAt = DateTime.UtcNow @@ -96,6 +106,13 @@ public class InquiryService( if (string.IsNullOrWhiteSpace(dto.Message)) throw new ValidationException("문의 내용을 입력하세요."); + var trimmedUpdateMessage = dto.Message.Trim(); + if (trimmedUpdateMessage.Length < MinMessageLength) + throw new ValidationException($"문의 내용은 최소 {MinMessageLength}자 이상이어야 합니다."); + + if (trimmedUpdateMessage.Length > MaxMessageLength) + throw new ValidationException($"문의 내용은 최대 {MaxMessageLength}자 이하여야 합니다."); + if (!InquiryStatusMapper.TryParse(dto.Status, out var parsedStatus)) throw new ValidationException("지원하지 않는 문의 상태입니다."); @@ -103,7 +120,7 @@ public class InquiryService( inquiry.Phone = FormatPhoneNumber(cleanPhone); inquiry.Email = string.IsNullOrWhiteSpace(dto.Email) ? null : dto.Email.Trim(); inquiry.ServiceType = string.IsNullOrWhiteSpace(dto.ServiceType) ? "기타" : dto.ServiceType.Trim(); - inquiry.Message = dto.Message.Trim(); + inquiry.Message = trimmedUpdateMessage; inquiry.Status = InquiryStatusMapper.ToStorageValue(parsedStatus); inquiry.AdminMemo = dto.AdminMemo; diff --git a/src/TaxBaik.Web/Pages/Contact.cshtml b/src/TaxBaik.Web/Pages/Contact.cshtml index 5cf7039..5084d65 100644 --- a/src/TaxBaik.Web/Pages/Contact.cshtml +++ b/src/TaxBaik.Web/Pages/Contact.cshtml @@ -72,7 +72,11 @@
- + + + 0/5000 + +
@@ -88,8 +92,14 @@