Skip to content
ERPNext Data Model
Esc
navigateopen⌘Jpreview
On this page

Document Rename and Cascading Reference Update

A design reference for changing a master record's identifying key without hand-editing every referencing record

1. Requirements

1.1 Functional requirements

  • Let an operator rename a batch of master records — old key to new key, pair by pair — from a single uploaded two-column file, rather than one record at a time.
  • Restrict eligible record types to ones the system itself marks as rename-capable, excluding record types reserved for core platform mechanics.
  • Enforce the same write-permission check a single rename would require.
  • Split an arbitrarily large uploaded file into fixed-size groups and enqueue one background job per group, because the underlying rename mechanism accepts only a bounded number of rows per call.
  • Let a master record participate in its own rename: re-sync a denormalized display field configured to mirror its identity, and reject a merge-style rename outright when it would combine ledger activity posted in incompatible currencies for the same legal entity.
  • Surface, without leaving the tool, how many resulting jobs are queued, running, finished, or failed.

1.2 Non-functional requirements

  • Long-running-safe: batches run on a queue for slow jobs, not inline with the request.
  • No cross-job coordination assumed: each job commits independently; nothing guarantees all-or-nothing across a batch.

1.3 Constraints

  • The tool holds no rename logic itself — a permission check, a file read, and a batching loop over a mechanism that lives in the platform layer, outside this record type’s own code.
  • The resulting fan-out — every other record type’s fields that pointed at the old key — is therefore describable only by contract from here, not by algorithm or failure behavior.

2. High-Level Design

2.1 Component diagram

There is no preview step between “file attached” and “jobs enqueued” — the operator’s own read of the file is the only check before commitment.


3. Deep Dive

3.1 What the tool itself is

The upload form is one shared instance system-wide, not one record per run, holding the target record type, the attached file, and an inline log that polls the queue for job counts. No history of a past batch persists on the form itself; whatever record exists lives only in the generic queue’s own job listing. An older action that listed rename-eligible record types is still present but explicitly marked no longer supported — a sign the tool was trimmed to one responsibility without a full cleanup pass.

3.2 The participation contract

Two master records were read in full, each independently implementing the same two hook points:

  • Before the rename completes, and only when it is a merge (the new key already names an existing record, so the two records’ history is being consolidated), the master record checks whether the two posted ledger activity in different currencies for the same legal entity, and blocks the merge if so.
  • After the rename completes, the master record re-syncs its own display-name field to the new key — but only when this deployment’s naming configuration ties identity to that display field. When identity comes from a series or another rule instead, this step is a no-op.

What actually rewrites every other record type’s fields that pointed at the old key is a mechanism outside this tree, described here only by that contract — what a participating record is handed (old key, new key, merge flag) and what it does with it — not by algorithm or transaction boundaries.

One of the two records also imports a generic link-propagation helper from the same platform family that backs renames, but for an unrelated purpose: propagating a classification-field change to every linking record, not the identity change itself — the same “find every linking record and fix a field” idea, reused for value propagation generally.

3.3 No dry run

There is no dry run or preview anywhere in this tool. Past the operator’s own read of the file and whichever guard a participating record happens to implement, a mistake surfaces only as a failed background job. Separately, this codebase’s own upgrade history calls the same rename mechanism directly and repeatedly as an ordinary step in version-upgrade routines — evidence that renaming is treated as routine maintenance here, not an exceptional, guarded operation.


4. Scale and Reliability

  • Batching satisfies a hard limit, not a throughput target — the 500-row group size is fixed by what the underlying mechanism accepts per call.
  • Jobs are independent. One group failing does not block or roll back any other; a large upload can finish partially renamed, visible only in per-job status counts.
  • No per-run history. A single shared form cannot distinguish today’s batch from an earlier one — only the generic job queue retains anything.

5. Trade-off Analysis

Decision Trade-off
A single shared instance, not one record per run Simplest possible interface, but no audit trail of past batches inside the tool itself.
Fixed-size batching driven by the platform mechanism’s row limit A correctness necessity, not a tunable scale choice.
No dry run or preview Cheapest to build; the only safety net is the operator’s own read of the file plus whatever a participating record guards on its own.
Rename participation left to each master record individually Keeps the platform mechanism generic, but whether a record type re-syncs a display field or guards a merge depends entirely on whether someone wrote that hook.

6. What to Revisit as the System Grows

  • No audit trail per batch — if volume grows, the single shared instance would need to become a per-run record, as the deletion tooling elsewhere in this module already is.
  • No pre-commit check for the one failure mode observed — even a cheap “would this pair be a merge” pass before enqueuing would catch what a guard today only catches after the fact.
  • Uneven participation — only two record types were confirmed to implement rename hooks; whether other rename-capable record types lack equivalent guards was not surveyed.

Was this page helpful?