fix(tasks): add a max length to task Description (and record the DTO validation audit)

Đang mở
#365 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
68/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
csharp
Lĩnh vực
api, backend

Hướng nghiên cứu

Start with TaskItemValidator and ProjectValidator to follow the existing description-length rule pattern, then review the controller validation paths noted in the issue. Add validator tests under TaskFlow.Api.Tests/Validators/ and controller tests covering PUT and PATCH rejection with no task changes. Done means all acceptance criteria pass, including POST/PUT/PATCH behavior, and dotnet test plus dotnet format --verify-no-changes pass.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

tech-debt

Groomed 2026-10-30 — ready for implementation.

Waits for the monorepo move (#397). This changes the API, so it is built after the assistant moves into this repo and the MCP change ships in the same PR (checked by the integration and error-code tests).

Original Description

Problem

UpdateTaskItemDto and PatchTaskItemDto have fields with no DTO-level validator. #207 (PR #363) added validators for CreateTaskItemDto, UpdateTaskItemDto and PatchTaskItemDto, but each covers only TimezoneOffsetMinutes.

During validation of #207 the reviewer noted that other fields, for example Title length and Description length, are not checked at the DTO level. In PATCH, Title appears to be checked only through the TaskItem model validator (TaskItemValidator) after the changes are applied to the entity.

This has not been verified as a real gap. The TaskItem validator may already cover these fields, in which case the only difference is where the error is raised. This issue is to find out.

What to check
  1. For each field on CreateTaskItemDto, UpdateTaskItemDto and PatchTaskItemDto, list which rule (if any) validates it today, and where (DTO validator, TaskItemValidator, EF constraint, or none).
  2. Identify any field where invalid input can reach the database, or cause a 500, or be accepted by one endpoint and rejected by another. Examples to try: over-long Title or Description, empty or whitespace-only Title on PATCH, BlockedReason length, DueDate extremes.
  3. Compare the three endpoints (POST, PUT, PATCH) for consistent behavior on the same invalid input.
Outcome
  • If every field is already covered by TaskItemValidator, close this issue with a short table of findings.
  • If there are gaps, add the missing rules (in Validators/, following the .InclusiveBetween / WithMessage pattern used for the offset) and tests under TaskFlow.Api.Tests/Validators/, or split out one issue per gap.
Context

Raised as a note-only observation by the implementation-validator during /feature-factory 207 (PR #363). Out of scope there.


Audit findings (2026-10-30, by reading the code; no requests were sent)

TaskItemValidator validates the entity after the DTO is mapped onto it. It runs on create (TaskItemsController.cs, around line 192) and in ApplyUpdateAsync (around line 437), so POST, PUT and PATCH are covered the same way. The three DTO validators cover only TimezoneOffsetMinutes, which is fine.

Field Validated by Gap
Title TaskItemValidator: not empty, max 100 none
Status, Priority TaskItemValidator: IsInEnum none
BlockedReason TaskItemValidator: max 200, only while Blocked none
Description nothing (no rule in TaskItemValidator, no length constraint in TaskDbContext) no length limit on POST, PUT or PATCH
DueDate nothing no range check; extremes are covered by #238
ParentTaskItemId, ProjectId controller checks not examined here

Comparable text fields are bounded: Project description 2000, Note content 2000, JournalNote content 2000, JournalLogEntry content 2000, JournalEntry summary 10000. Task Description is the only unbounded user text field.

Stored data check (2026-10-30, via the TaskFlow MCP list_tasks, 11 tasks, detailed format): the longest description is about 110 characters (task #68). Caveats: the MCP's target instance was not confirmed to be production, and the detailed format may truncate descriptions.

User Story

As a task owner, I want an over-long task description to be rejected with a clear message, so that task data stays bounded like every other text field and an accidental paste cannot bloat the database or the responses.

Acceptance Criteria

  1. Given a POST with a Description longer than 2000 characters, then the response is 400 with the message "Description must not exceed 2000 characters." and no task is created.
  2. Given a PUT with a Description longer than 2000 characters, then the response is 400 with the same message and the task is unchanged.
  3. Given a PATCH with a Description longer than 2000 characters, then the response is 400 with the same message and the task is unchanged.
  4. Given a Description of exactly 2000 characters, null, or empty, then POST, PUT and PATCH accept it.
  5. Given the rule, then it lives in TaskItemValidator (Validators/), not in the three DTO validators, so one rule covers every endpoint and the parent auto-complete path. Errors keep the BadRequest(validationResult.Errors) shape.
  6. Given the validator, then unit tests under TaskFlow.Api.Tests/Validators/ cover 2000 accepted, 2001 rejected, null and empty accepted, with the exact message. Controller tests cover PUT and PATCH rejection with the task unchanged.
  7. Given the finished change, then dotnet test and dotnet format --verify-no-changes pass, and backend line coverage stays at 75% or above.

Edge Cases

  • Existing data above the limit. PUT resends Description, so a stored description longer than 2000 characters would make every later update of that task fail until it is shortened. The MCP check found nothing near the limit, but it could not be confirmed against production. Check production data (for example with the MCP against the live instance) before merging.
  • Parent auto-complete. TryAutoCompleteParentAsync validates the parent entity (around line 575). A parent with an over-limit legacy description would fail validation there. Confirm what the user sees.
  • Counting. MaximumLength counts UTF-16 code units, not characters as the user perceives them. 2000 is the same unit the other validators use; do not change it.
  • Frontend. Check how the task forms surface a 400 on Description. Adding a maxLength attribute is optional and not required by this story.
  • The message and rule follow ProjectValidator (Description max 2000).

Out of Scope

  • DueDate range or wire format (#238).
  • Title, Status, Priority and BlockedReason rules (already covered).
  • Changing the TimezoneOffsetMinutes rules from #207.
  • Changing the error shape (BadRequest(validationResult.Errors) is the convention; see #364).
  • Global FluentValidation auto-validation.
  • Adding a database column constraint or migration.
  • ParentTaskItemId and ProjectId validation.
Ngôn ngữ chính
C#
Star
1
Fork
0
Merge trung bình
2 giờ 2 phút
Pull request đã merge (30 ngày)
98

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nevridge/TaskFlow

Tất cả issue của nevridge/TaskFlow

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.