skip to content

A test case in a case repository stores a link to an item in an external issue tracker. Which identifier should that link store, and what happens to it when the item is renamed, moved to another project, or deleted?

level: juniorimportance: should knowfreq 50%

answer

  1. two names for the same item
  2. only one of them is editable
  3. a move rewrites the visible key
  4. not-found can also mean no permission
  5. keep the row, mark it unresolvable

basics

~20 s

Store the tracker's immutable internal identifier, not the human-readable key or the title. A rename or a move then leaves the link intact; only a delete truly breaks it, and the repository should show it as unresolvable rather than quietly drop it.

solid answer

~40 s

Trackers hand out two kinds of identity: an internal identifier minted once and never re-used, and a human-facing key or title that people type, quote and change. A link stored by the internal identifier survives a rename, and survives a move between projects, because only the display key changes. A link stored by the key or by a URL breaks the moment either is rewritten, and the repository cannot tell that break apart from a deletion. Deletion is the one event that genuinely destroys the target, and the right response is to mark the link unresolvable and keep it visible rather than delete the row — a repository that silently prunes links destroys the evidence that coverage ever existed. Cache the key and title for readability, but always resolve by the identifier.

go deeper

for a junior

Be ready to say that a tracker item has a stable internal identifier and a display key people can change, and that a link should be stored by the stable one.

for a middle

Explain why a move rewrites the display key while leaving the internal identifier untouched, and why a cached key and title are a convenience rather than the link's identity.

for a senior

Show the operational judgment: a not-found can be a deletion, an expired credential or a lost permission, so a link is marked unresolvable after repeated failures and never pruned on the first one.

for a principal

Own the policy that link history is evidence. Cascading a tracker deletion into your own store silently improves backward-looking numbers, so be able to argue what your product keeps and what it shows instead.

A link from a test case to a tracker item is a foreign key across a boundary you do not control. Everything hard about keeping it correct follows from that: the other side can change the thing you pointed at, at any time, without telling you, and the only leverage you have is the identifier you chose to store. ## Two identities, only one of them stable Trackers expose an item under at least two names: - an **internal identifier**, minted when the item is created, opaque, never re-used, and not shown to users in most workflows; - a **human-readable key** — the short string people paste into chat and commit messages — and a **title**, both of which are display surfaces and both of which are editable. A **rename** changes the title. A **move** to another project usually rewrites the human-readable key, because the key encodes the project it belongs to. Neither event touches the internal identifier. So the choice of what to store decides, in advance, how many ordinary tracker operations look to you like a broken link: | Event on the tracker side | Link stored by internal id | Link stored by key or URL | |---|---|---| | Title edited | intact | intact | | Item moved to another project | intact | resolves to nothing | | Item deleted | unresolvable | unresolvable | | Integration account loses visibility | looks unresolvable | looks unresolvable | The last row is the one that catches people out: an authorization failure and a deletion produce the same not-found answer from most trackers, deliberately, so that a caller cannot probe for the existence of items it is not allowed to see. ## Store the identifier, cache the label The shape most case repositories converge on is: 1. **Resolve by the internal identifier.** It is the only value in the link that is a promise. 2. **Cache the key and title alongside it**, refreshed on every successful read, purely so a list of links is readable without a round trip per row. 3. **Never treat the cache as identity.** If the cached key and the freshly read key disagree, the fresh one wins and the cache is updated; that disagreement is the normal signature of a move, not an error to raise. That split also buys a cheap staleness signal. If the cached label for a link has not been refreshed in a long time, the link has not been resolved successfully in a long time, which is worth surfacing before somebody builds an argument on it. ## What a delete should do to a stored link Deletion is the only event that genuinely destroys the target, and it is the one where a product's behaviour is a real design decision rather than a mechanical consequence: - **Do not cascade the delete into your own store.** That a test case once verified a requirement is a historical fact; erasing the link erases the evidence that the coverage existed, and quietly improves every backward-looking number. - **Mark the link unresolvable and keep it visible**, with the last known key and title, so a human can decide whether the item was deleted, merged into another, or simply moved out of the integration account's view. - **Do not decide on a single failure.** One not-found may be a transient outage, an expired credential, or a permission change. Requiring the same failure on several separate attempts, spread over time, keeps a five-minute credential problem from marking a whole project's links dead. - **Make the state reversible.** If the item reappears — restored from a backup, or visibility restored — the next successful resolution should clear the mark with no human involved. ## The failure this prevents The characteristic incident is not dramatic. Somebody reorganizes the tracker over a weekend, moving a few hundred items into a new project. A repository that stored keys sees a few hundred links stop resolving on Monday, prunes them on the assumption that the items are gone, and its coverage figures drop without anyone having deleted a test case or a requirement. Nothing errored. The numbers simply became wrong, and because the links were pruned there is nothing left to reconstruct them from. A repository that stored internal identifiers sees the same reorganization as a batch of changed display labels, refreshes its cache, and reports on Monday exactly what it reported on Friday.

  • Two tracker items are merged into one. What should happen to a case that linked to the one that disappeared?
    Treat it as a move rather than a delete when the tracker exposes the survivor: re-point the link at it and record that it was redirected, so the claim keeps its provenance. When nothing identifies the survivor, the honest outcome is an unresolvable link a human retargets. Guessing from a title match manufactures a link nobody asserted.
  • How would you display a link the repository can no longer resolve, without making a reader think the test case itself is broken?
    Show the case normally and the link as degraded: last known key and title, muted, with the time of the last successful resolution and the reason it failed. Then count it in its own bucket of links needing attention rather than folding it into a healthy total, so nobody reads silence as agreement.

saying these in an interview costs you the question

  • Storing the human-readable key because it reads nicely
  • Assuming a renamed item breaks a stored link
  • Deleting the stored link on the first failed lookup
  • Reading a not-found as proof the item was deleted
  • Treating the item's URL as its identity