Fix retirement propagation and task counts

This commit is contained in:
A R R R Associates
2026-09-19 15:11:56 +05:30
parent f565e8309d
commit cc8691d4cd
4 changed files with 107 additions and 22 deletions
+44 -1
View File
@@ -109,6 +109,29 @@ def firm_task_hash(target: FirmServiceTaskTemplate) -> str:
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
def _legacy_retirement_equivalent(
source: ServiceDefaultTaskTemplate,
target: FirmServiceTaskTemplate,
) -> bool:
"""Return True when a legacy firm row differs only because the system row was retired.
Full-sync retirement moves omitted system rows into a high temporary sequence range
before setting is_active=False. Legacy firm rows created before provenance tracking still
carry their old active flag and old sequence. Those two differences must not make an
otherwise inherited task look like a deliberate firm customization.
Any substantive field difference still protects the firm row as customized.
"""
source_snapshot = _snapshot_dict(source)
target_snapshot = _snapshot_dict(target)
source_snapshot.pop("is_active", None)
target_snapshot.pop("is_active", None)
if int(getattr(source, "sequence_no", 0) or 0) >= 100000:
source_snapshot.pop("sequence_no", None)
target_snapshot.pop("sequence_no", None)
return source_snapshot == target_snapshot
def system_task_diff(source: ServiceDefaultTaskTemplate, target: FirmServiceTaskTemplate) -> list[dict[str, Any]]:
labels = {
"task_name": "Task name",
@@ -367,11 +390,31 @@ def sync_firm_tasks_from_system_defaults(
# For legacy rows with no inheritance history, infer whether they were
# already firm-customized by comparing the full portable snapshot.
if linked_from_legacy and target.last_synced_system_hash is None:
target.is_customized = firm_task_hash(target) != latest_hash
if not source.is_active and _legacy_retirement_equivalent(source, target):
# This was an inherited legacy row whose system source has just been
# retired by Full Synchronization. Do not misclassify the active/old
# sequence difference as a firm customization; allow normal retirement
# propagation below.
target.is_customized = False
else:
target.is_customized = firm_task_hash(target) != latest_hash
if not target.is_customized:
target.last_synced_system_hash = latest_hash
target.last_reviewed_system_hash = latest_hash
# Repair rows linked by an earlier rollout where retirement-only differences
# were incorrectly interpreted as customization. This is deliberately limited
# to rows that have never had a successful inherited snapshot recorded.
if (
not source.is_active
and target.is_customized
and target.last_synced_system_hash is None
and _legacy_retirement_equivalent(source, target)
):
target.is_customized = False
target.system_update_available = False
target.system_update_detected_at_utc = None
# Detect out-of-band edits to a linked inherited row as customization.
if (
not target.is_customized