Skip to content

[WIP] EPIC FOUR-29110 - Cases Retention Policy#8721

Open
sanjacornelius wants to merge 9 commits intodevelopfrom
task/FOUR-29110
Open

[WIP] EPIC FOUR-29110 - Cases Retention Policy#8721
sanjacornelius wants to merge 9 commits intodevelopfrom
task/FOUR-29110

Conversation

@sanjacornelius
Copy link
Contributor

@sanjacornelius sanjacornelius commented Feb 5, 2026

[WIP]
ci:deploy

Issue & Reproduction Steps

Describe the issue this ticket solves and describe how to reproduce the issue (please attach any fixtures used to reproduce the issue).

Solution

  • List the changes you've introduced to solve the issue.

How to Test

Describe how to test that this solution works.

Related Tickets & Packages

  • Link to any related FOUR tickets, PRDs, or packages

Code Review Checklist

  • I have pulled this code locally and tested it on my instance, along with any associated packages.
  • This code adheres to ProcessMaker Coding Guidelines.
  • This code includes a unit test or an E2E test that tests its functionality, or is covered by an existing test.
  • This solution fixes the bug reported in the original ticket.
  • This solution does not alter the expected output of a component in a way that would break existing Processes.
  • This solution does not implement any breaking changes that would invalidate documentation or cause existing Processes to fail.
  • This solution has been tested with enterprise packages that rely on its functionality and does not introduce bugs in those packages.
  • This code does not duplicate functionality that already exists in the framework or in ProcessMaker.
  • This ticket conforms to the PRD associated with this part of ProcessMaker.

Note

High Risk
Automatically deletes case records in production on a schedule; incorrect cutoff logic or configuration could cause unintended data loss despite test coverage.

Overview
Adds a new daily cases:retention:evaluate scheduled command that fans out per-process queue jobs to enforce a case retention policy.

Introduces EvaluateProcessRetentionJob, gated by CASE_RETENTION_POLICY_ENABLED, which deletes CaseNumber records in chunks based on each process’ properties.retention_period (default 6 months) and properties.retention_updated_at rules (different cutoffs for cases created before vs after the update). Adds a CaseNumberFactory and a comprehensive job test suite covering deletes, non-deletes, batching, policy updates, disabled policy, and default behavior.

Written by Cursor Bugbot for commit f3d2573. This will update automatically on new commits. Configure here.

@processmaker-sonarqube
Copy link

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Fixed issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

// Get deleted timestamp
// $deletedAt = Carbon::now();
// RetentionPolicyLog::record($process->id, $caseIds, $deletedAt);
});
Copy link

Choose a reason for hiding this comment

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

Retention policy deletes CaseNumber instead of ProcessRequest

High Severity

The retention policy deletes CaseNumber records, which are just sequence generators for creating unique IDs, not the actual case data. The actual cases are stored in ProcessRequest. Deleting CaseNumber records doesn't remove any case data - it only affects the ID generation mechanism. The retention policy should target ProcessRequest records and their associated data to actually delete cases.

Fix in Cursor Fix in Web

@vladyrichter
Copy link

QA server K8S was successfully deployed https://ci-4c7e0ec47b.engk8s.processmaker.net

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

}

// Default to 6 months if retention_period is not set
$retentionPeriod = $process->properties['retention_period'] ?? '6_months';
Copy link

Choose a reason for hiding this comment

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

Null properties causes TypeError on array access

High Severity

The code accesses $process->properties['retention_period'] using the null coalescing operator, but if $process->properties is null (which is possible since the database column is nullable according to migrations), PHP 7.4+ throws a "Trying to access array offset on value of type null" error. The null coalescing operator only handles the case when the array key doesn't exist, not when the array itself is null. This would cause the job to fail for any process with null properties.

Fix in Cursor Fix in Web


namespace ProcessMaker\Models;

use Database\Factories\ProcessMaker\Models\CaseNumberFactory;
Copy link

Choose a reason for hiding this comment

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

Unused import added to CaseNumber model

Low Severity

The import Database\Factories\ProcessMaker\Models\CaseNumberFactory is added but never referenced in the class body. Laravel's HasFactory trait auto-resolves factories based on naming conventions, making this explicit import unnecessary. Other models in the codebase (like Bookmark, Bundle, etc.) use HasFactory without importing their factory class explicitly.

Fix in Cursor Fix in Web

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.

2 participants