Skip to content

fix: validate work item date ranges on partial updates - #9947

Open
GODOSTROYER wants to merge 1 commit into
makeplane:previewfrom
GODOSTROYER:codex/fix-work-item-partial-date-validation
Open

GODOSTROYER wants to merge 1 commit into
makeplane:previewfrom
GODOSTROYER:codex/fix-work-item-partial-date-validation

Conversation

@GODOSTROYER

@GODOSTROYER GODOSTROYER commented Oct 5, 2026 •

Copy link
Copy Markdown

Description

Updating only one work-item date could bypass the existing date-range validation in both the public API and the API used by the web app. The validators compared dates only when both were present in the request.

For a work item with start_date=2026-01-10 and target_date=2026-01-20:

PATCH /api/v1/workspaces/{slug}/projects/{project_id}/work-items/{id}/
Content-Type: application/json
X-API-Key: <api-key>

{"start_date":"2026-01-21"}

Previously, this saved an inverted date range. It now returns HTTP 400 with {"non_field_errors":["Start date cannot exceed target date"]} and leaves the work item unchanged. Updating only target_date to 2026-01-09 is rejected in the same way. The app's /api/workspaces/{slug}/projects/{project_id}/issues/{id}/ endpoint follows the same rule.

Both validators now use the saved value for an omitted date. Explicit null still clears a date, equal dates remain valid, and updates containing neither date retain their existing behavior.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Not applicable; backend request validation.

Test Scenarios

  • Added serializer coverage for invalid single-date edits, valid/equal dates, explicit nulls, unset opposite dates, create requests, and unrelated updates.
  • Added endpoint regressions for API-key and session-cookie requests. Invalid updates assert HTTP 400 and unchanged persisted name, dates, and modification time; valid updates and date clearing assert persistence.
  • On the unchanged base, the new endpoint tests produce 4 failures and 2 passes. With the fix: 96 serializer tests and 17 selected endpoint tests pass.
  • Two additional local socket-level HTTP checks pass against isolated PostgreSQL 15.19 and Redis 8.0.5. Only deferred background-task dispatch is mocked.
  • Production-settings Django checks and makemigrations --check --dry-run pass. The exact CI Ruff command passes on a disposable source snapshot, and copyright checks pass for all changed Python files.

Focused regression command, from apps/api with the repository's test services configured:

python -m pytest plane/tests/unit/serializers/test_issue_date_validation.py plane/tests/contract/api/test_issue_date_validation.py --reuse-db --nomigrations -q

References

No linked issue. The reproduction above and the regression tests describe the defect; no matching issue or existing fix was found during triage.

Summary by CodeRabbit

  • Bug Fixes
    • Partial issue updates now validate start and target dates together, including dates already saved on the issue. Updates that would put the start date after the target date are rejected without changing the issue.
    • Matching start and target dates remain valid, and either date can be cleared.

Copilot AI balanced review requested due to automatic review settings October 5, 2026 08:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2a373814-d23c-47d8-9ef4-077867b57034
📥 Commits

Reviewing files that changed from the base of the PR and between 7466675 and 14c2d77.

📒 Files selected for processing (4)
  • apps/api/plane/api/serializers/issue.py
  • apps/api/plane/app/serializers/issue.py
  • apps/api/plane/tests/contract/api/test_issue_date_validation.py
  • apps/api/plane/tests/unit/serializers/test_issue_date_validation.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Both issue serializers now validate supplied date changes against the effective start and target dates, including existing values omitted from partial updates. Unit and contract tests cover invalid and valid date updates.

Changes

Issue date validation

Layer / File(s) Summary
Validate effective date pairs
apps/api/plane/api/serializers/issue.py, apps/api/plane/app/serializers/issue.py, apps/api/plane/tests/unit/serializers/test_issue_date_validation.py
Both serializers compare supplied dates with existing instance values for omitted fields. Unit tests cover reversed ranges, valid ranges, equal dates, cleared dates, and unrelated updates to issues with pre-existing reversed dates.
Verify API update outcomes
apps/api/plane/tests/contract/api/test_issue_date_validation.py
Contract tests check that invalid partial updates return HTTP 400 without changing issue fields or updated_at. They also check that equal dates and clearing target_date are accepted and persisted through both endpoints.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 14c2d

The date-validation change is ready to merge after normal checks.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to 14c2d

The change rejects invalid date ranges without expanding access or authority. Existing authorization and work-item ownership remain unchanged, and rejected requests do not enter the save path. No material security risk introduced or worsened by this change was identified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed behavior is bounded to date updates on issues already reachable through existing project-authorized endpoints. Request dates influence validation and the existing save path, but the change adds no tenant selection, caller, privilege, or cross-service authority. Its effect is to reject additional requests rather than enable a new sensitive operation.

Trust Boundaries and Controls

  • observed — The public endpoint retains ProjectEntityPermission and workspace/project/issue lookup. The app endpoint retains its project-role authorization and workspace/project-filtered queryset. Serializer updates derive relationship ownership from the existing issue, not the supplied dates. These boundaries predate and remain unchanged by this PR.

Resilience and Maintainability Implications

  • observed — The unchanged update methods can replace assignee or label relations before saving the issue, and the handlers dispatch activity after saving. This PR does not add transactional recovery, concurrency control, or delivery guarantees. Those existing failure-containment limits are not newly exposed by the stricter date validation; interruption and concurrent execution were not directly verified.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: validating work-item date ranges during partial updates.
Description check ✅ Passed The description covers the change, marks the bug-fix type, explains that screenshots do not apply, lists test scenarios and results, and states that there is no linked issue.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CLAassistant

CLAassistant commented Oct 5, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants