When most developers hear "DFS" (Depth-First Search), they picture whiteboard interview questions about binary trees or graphs.
But classic data structures and algorithms (DSA) often shine brightest in real-world engineering problems — sometimes in places we don't expect.
At Creditflow, we faced exactly such a scenario while building a financial data integration layer with QuickBooks. Let's explore how a textbook algorithm became the simplest, cleanest solution to a real business need.
🧩 The Problem: Deeply Nested Data
QuickBooks' Balance Sheet API doesn't return a flat list of account balances.
Instead, it mirrors real-world accounting structure: nested groups like:
- Assets → Current Assets → Bank Accounts → Individual accounts
- Liabilities → Current Liabilities → Credit Cards → Individual cards
Here's a simplified JSON snippet illustrating what the API might return:
{
"Rows": [
{
"type": "Section",
"Header": { "value": "Assets" },
"Rows": [
{
"type": "Section",
"Header": { "value": "Current Assets" },
"Rows": [
{
"type": "Data",
"ColData": [
{ "value": "XYZ Bank" },
{ "value": "15000" }
]
},
{
"type": "Data",
"ColData": [
{ "value": "ABC Savings" },
{ "value": "8000" }
]
}
]
}
]
}
]
}
In real data, this nesting can go even deeper: custom groups, tax details, or other accounting adjustments.
⚙️ What We Needed
Our downstream services — like cash forecasting and reporting dashboards — wanted data as a flat list:
- Each row: account name + balance
- Plus the full path (Assets → Current Assets) so the UI could rebuild the same nested view
Example target output:
📊 Flattened Data Structure:
┌─────────────────────────────────────────────────────────────────┐
│ Path │ Account │ Amount │
├─────────────────────────────────────────────────────────────────┤
│ Assets → Current Assets │ XYZ Bank │ 15,000 │
│ Assets → Current Assets │ ABC Savings │ 8,000 │
└─────────────────────────────────────────────────────────────────┘
Or in a more hierarchical view:
Assets
└── Current Assets
├── XYZ Bank: $15,000
└── ABC Savings: $8,000
🧠 The Cleanest Solution: DFS with Path Preservation
At its core, this problem is:
Traverse every node in a tree, remember the path you took, and emit a flat record at each leaf.
That's exactly what Depth-First Search (DFS) does naturally.
✏️ Pseudo-code (Standard DFS Style)
procedure DFS(node, path, output)
if node.type == "Section" then
// Add this section name to path
path.append(node.Header.value)
// Recurse into child nodes
for each child in node.Rows do
DFS(child, path, output)
end for
// Backtrack: remove section name
path.removeLast()
else if node.type == "Data" then
// Extract data
accountName ← node.ColData[0].value
amount ← node.ColData[1].value
// Record current path + data
record ← {
path: copy(path),
account: accountName,
amount: amount
}
output.append(record)
end if
end procedure
✅ What Makes This Powerful
- Unknown depth? DFS handles it: no need to hardcode how many levels
- Path preserved: we remember the route we took, so the UI can re-create the hierarchy
- Simple to extend: if QuickBooks adds new nested sections tomorrow, the traversal still works
📦 The Final Transformed Data
[
{
"path": ["Assets", "Current Assets"],
"account": "XYZ Bank",
"amount": "15000"
},
{
"path": ["Assets", "Current Assets"],
"account": "ABC Savings",
"amount": "8000"
}
]
From here, the frontend can:
- Build collapsible tree views
- Group by any level (e.g., totals per section)
- Dynamically render unknown categories
🚀 TypeScript Implementation
Here's the actual code we used:
interface FlattenedRecord {
path: string[];
account: string;
amount: string;
}
function dfsTraverse(
rows: QuickBooksRow[],
currentPath: string[],
output: FlattenedRecord[]
): void {
for (const row of rows) {
if (row.type === "Section" && row.Header?.value) {
// Add section to path
currentPath.push(row.Header.value);
// Recurse into children
if (row.Rows) {
dfsTraverse(row.Rows, currentPath, output);
}
// Backtrack
currentPath.pop();
} else if (row.type === "Data" && row.ColData) {
// Extract leaf data
output.push({
path: [...currentPath], // Copy current path
account: row.ColData[0]?.value ?? "Unknown",
amount: row.ColData[1]?.value ?? "0"
});
}
}
}
🚀 Why This Is More Than Just "Interview DSA"
It's common to hear engineers say:
"DSA is just for cracking coding interviews."
But here, DFS wasn't about passing an interview:
- It made the data transformation cleaner and safer
- It handled complexity (unknown nesting) without messy nested loops
- It kept the code maintainable even as the data model changed
This is what real-world DSA looks like: Algorithms helping us reason about data, write correct code, and future-proof systems.
🧡 Closing Thought
When we learn algorithms, we often see them on toy problems.
But keep them in your toolkit — because one day, you'll run into messy real-world data, and a textbook algorithm might turn out to be the simplest, most elegant solution.
The next time someone says "DSA is just for interviews," you can point to this: a classic traversal algorithm solving a real business problem, making code cleaner, and keeping systems maintainable.
That's the true power of understanding your fundamentals.
Have you used classic algorithms to solve real-world problems? I'd love to hear your stories — reach out on Twitter or LinkedIn.