Using Depth-First Search to Transform Nested QuickBooks Data - And Why DSA Isn't Just for Interviews

5 min readVyshnav S Deepak
⚙️ Engineering & Development
Algorithms
Data Transformation
API Integration
FinTech
TypeScript

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:

  • AssetsCurrent AssetsBank AccountsIndividual accounts
  • LiabilitiesCurrent LiabilitiesCredit CardsIndividual 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.

© 2024 Vyshnav S Deepak