--- name: request-lifecycle-tracing description: Following one request from entry to storage and back, so a change can be reasoned about across layers. when_to_use: You need to understand how a specific operation works, or where to make a change that crosses layers. tags: [analysis, codebase] --- # One request, every layer, in order Tracing a single path end to end is the fastest way to learn a system, and the only reliable way to know where a cross-cutting change must land. ## The trace ``` route registration which handler, which method, what middleware extractors / auth what must be true before the handler body runs handler validation, then the call into real logic domain / service the actual decision persistence the query, the transaction boundary response what is serialised, what is deliberately omitted side effects events, jobs, background work ``` The last line is the one most often missed and the most likely to break: an operation that also enqueues a job, writes an event or invalidates a cache has consequences the response does not mention. ## Follow the data, not the call stack Call stacks show structure; data flow shows behaviour. For each step ask what changed shape and what was dropped. A field silently discarded between the handler and the query is a bug that no test asserting the response will catch. ## Find the transaction boundary explicitly Where does the transaction begin and commit? Anything outside it is not atomic with the write, and that is where "the row exists but the event never fired" comes from. Note it during the trace — reconstructing it later, mid-incident, is much harder. ## Note what happens on failure Walk it a second time asking what happens when each step fails. Errors that are logged and swallowed are where silent failures live: the operation reports success while a step did nothing. If a step's failure produces no observable signal, that is a finding, not a detail. ## Record the trace with file:line The output is a short document with a line per layer and the file and line for each. That is what makes the next change — or the next incident — cheap, and it is checkable by whoever reads it next.