Simplify.Connect.Accelerate
Imagine
"Exploring the limitless bounds of imagination"

When Domain Knowledge Compounds: Two Applications, One Architecture

WB
January 2026
12 min read

The first NetSuite application took two months. The second took fifteen days. Same architecture, same quality standards, same comprehensive testing. This is the story of how domain knowledge compounds, and why the hardest part of building enterprise software isn't the code.

In November 2025, we started building a Time Entry application for NetSuite. Employees needed to log time from Outlook and their phones instead of navigating NetSuite's complex interface. Two months later, we shipped 77,000 lines of production code, 2,912 automated tests, and a dual-platform application running as both an Office Add-in and a Progressive Web App.

Then in January 2026, we started the Expense Report application. Same problem domain: NetSuite data, OAuth authentication, cascading dropdowns, budget tracking, mobile-first design. But this time, something was different. The patterns were familiar. The architecture was proven. The NetSuite quirks were documented.

Fifteen days later, we shipped 42,000 lines of code and 1,985 automated tests. A complete, production-ready expense management system with receipt uploads, image compression, billable/non-billable workflows, and real-time budget tracking.

The Compounding Effect

The second application was built 4x faster than the first, not because we cut corners, but because we'd already paid the learning tax. Domain knowledge compounds. Architecture decisions compound. Test patterns compound. The hard problems were solved once and reused many times.

The Numbers Tell the Story

Metric Time Entry Expense Report
Development Time ~60 days 15 days
Commits 343 97
Lines of Code 77,000 42,000
Automated Tests 2,912 1,985
TypeScript Files 135 89
Architecture Layers 13 15
Test Coverage 53% 51%

Look at those numbers carefully. The Expense Report application isn't a stripped-down version. It has more architecture layers, comparable test coverage, and domain-specific features like receipt upload with image compression, HEIC detection, and dual budget tracking for Engineering Expenses and Billable Consumables.

What We Learned Building Time Entry

The Time Entry application was our education in NetSuite development. Every lesson was hard-won:

NetSuite API Quirks

OAuth 2.0 Complexity

NetSuite's OAuth implementation has specific requirements around redirect URIs, CORS handling, and the authorization code flow. We built a proxy server architecture that handles all of this, keeping client secrets server-side and managing the token exchange securely.

Cascading Dropdown Performance

Loading customers, then projects, then tasks, with each dependent on the previous selection, creates complex state management. We built caching layers, debounced fetches, and optimistic UI patterns that make the experience feel instant.

The Architecture That Emerged

After two months of iteration, we arrived at a Clean Architecture with clear layer separation:

  • Domain: Pure business logic with no I/O dependencies
  • Gateway: All NetSuite API communication isolated here
  • Controllers: Orchestration layer connecting views to services
  • Views: DOM manipulation only, no business logic
  • State: Observable state container with indexed lookups
  • Persistence: AES-GCM encrypted token storage
  • Infrastructure: Shared utilities, error handling, telemetry

This architecture wasn't designed upfront. It evolved through solving real problems, then was codified for reuse.

Building Expense Report: The Compound Effect

When we started the Expense Report application, we didn't start from scratch. We started from understanding.

Day 1-2: Foundation Sprint

The entire project scaffolding, build configuration, testing setup, and authentication flow was copied and adapted. Not blindly copied, but intelligently reused. The OAuth proxy server needed zero changes. The encryption utilities worked identically. The error handling patterns transferred directly.

Day 3-5: Core API Integration

NetSuite's Expense Report API has different endpoints than Time Entry, but the patterns are identical. Pagination works the same way. Field resolution uses the same utilities. The gateway layer needed new functions, but the architecture was proven.

Day 6-10: Domain-Specific Features

This is where Expense Report diverged: receipt uploads with image compression, billable vs non-billable workflows, Engineering Expenses budget tracking. These were genuinely new features, but they plugged into the existing architecture cleanly.

Day 11-15: Polish and Testing

The testing patterns from Time Entry transferred directly. We knew what to test, how to mock NetSuite responses, and how to structure test files for maintainability. Writing 1,985 tests in five days is only possible when you know exactly what patterns work.

What Transferred Directly

  • Authentication system: OAuth flow, token storage, refresh logic
  • Encryption utilities: AES-GCM with PBKDF2 key derivation
  • Cascading dropdown architecture: Customer → Project → Task selection
  • Budget tracking patterns: Real-time remaining budget display
  • Build configuration: Webpack for dual-platform (Add-in + PWA)
  • Testing infrastructure: Jest setup, mock factories, test utilities
  • CSS architecture: Design tokens, component styles, themes

The Expense Report Feature Set

Despite the compressed timeline, the Expense Report application is feature-complete for production use:

42K
Lines of Code
1,985
Automated Tests
15
Architecture Layers
97
Commits
89
TypeScript Files
36
Test Suites

Receipt Upload with Intelligence

The receipt upload system demonstrates domain knowledge in action:

Dual Budget Tracking

For billable expenses, the system tracks two separate budgets from Sales Orders:

The Timeline Comparison

Nov 1, 2025
Time Entry: Project Start
Initial commit. Learning NetSuite APIs, OAuth flows, and Office Add-in development from scratch.
Nov 29-30
Time Entry: Dual Platform
Mobile PWA added alongside Office Add-in. Unified codebase serving both platforms.
Dec 30-31
Time Entry: Clean Architecture
Full TypeScript migration, 13-layer architecture, comprehensive test suite.
Jan 4, 2026
Expense Report: Project Start
Sprint 1 foundation complete in first commit. Authentication and platform support in Sprint 2.
Jan 10
Expense Report: Core Features
Budget system, dropdown cascades, receipt upload all functional.
Jan 19
Expense Report: Production Ready
v1.0.41 deployed with 1,985 tests, dual budget tracking, and full mobile support.

Why Domain Knowledge Matters More Than Code

The real value created during the Time Entry project wasn't the 77,000 lines of code. It was the understanding:

The Hidden Asset

When we talk about "reusable code," we're usually thinking too small. The reusable asset isn't the functions or classes. It's the mental model of the domain, the architectural decisions that survived real-world testing, and the patterns that proved they work under pressure.

Combined Platform Statistics

Together, the two applications represent a significant NetSuite integration platform:

119K
Total Lines of Code
4,897
Combined Tests
440
Total Commits
224
TypeScript Files
4
Production Platforms
1
Shared Proxy Server

What This Means for Future Development

The pattern is now clear. Each new NetSuite application we build will benefit from everything we've learned:

The third application won't take fifteen days. It might take ten. The fourth might take a week. This is what compounding looks like in software development.

The Real Investment

The two months spent on Time Entry wasn't just building one application. It was building the foundation for a family of NetSuite integrations. The expense application proved that investment pays dividends. Future applications will prove it again.

Lessons for Leaders

If you're planning enterprise software development, consider:

  1. The first project is an investment: It will take longer than you expect because you're learning the domain, not just writing code.
  2. Architecture matters for reuse: Quick hacks don't compound. Clean architecture does.
  3. Testing enables speed: The 2,912 tests on Time Entry gave us confidence to move fast on Expense Report.
  4. Document the quirks: Every API inconsistency, every workaround, every hard-won insight should be captured.
  5. Plan for the family: If you're building one NetSuite integration, you'll probably build more. Design accordingly.

Building on What You've Learned

The hardest part of enterprise software isn't writing code. It's understanding the domain deeply enough that code becomes obvious. That understanding compounds. Each project makes the next one faster, better, and more reliable.