We built a time entry application for NetSuite in two months: 314 commits, 77,000 lines of code, 2,912 automated tests, and numerous hours of real-world user testing. This is the story of what it actually takes to go from "it works" to "it works in production," and why the prototype is only the beginning.
There's a seductive narrative in tech right now: AI tools have made software development fast and easy. You can "vibe code" a working prototype in a weekend. Dropdowns populate, buttons click, data saves. Demo complete.
And it's true. You can build a working time entry form in a few days. It would look impressive in a demo.
But we didn't stop there. From day one, we treated security, testing, and architecture as first-class concerns, not afterthoughts to bolt on later. That decision is what separates hobby projects from production systems, weekend experiments from enterprise software, things that work once from things that work reliably for years.
A working demo proves the concept. The other 98% of the work ensures it won't fall apart when someone enters unexpected data, won't leak credentials, won't corrupt records when two users edit simultaneously, and won't become an unmaintainable mess six months from now. We built that in from the start.
The Myth of "Vibe Coding"
Getting from "it works on my machine" to "it works reliably in production for real users with real data and real security requirements" is the difference between:
Prototype vs. Production
- A test drive around the parking lot vs. a vehicle that passes crash testing, emissions standards, and a 100,000-mile warranty
- A sketch on a napkin vs. architectural blueprints that a contractor can actually build from
- A home-cooked meal for friends vs. a restaurant kitchen that passes health inspection every day for years
- Playing guitar at a campfire vs. a live performance with sound engineering, lighting, and backup plans for equipment failure
The prototype is the exciting part. Features come to life, stakeholders nod approvingly, and momentum builds. But the prototype is roughly 2% of the total effort required to ship production software. The other 98% is invisible, unglamorous, and absolutely essential.
What Two Months Actually Looks Like
Our NetSuite Time Entry application started as a simple idea: let employees enter time from Outlook and their phones instead of logging into NetSuite. Two months later, here's what we shipped:
A working prototype might have been 2,000 lines of code. The production version is 77,000, and more than half of that is tests ensuring it stays working.
Where the Effort Actually Goes
When we break down where two months of development time went, the distribution reveals why "just build a prototype" is only the beginning:
The Real Breakdown
The feature development, the part that's visible in demos, represents about 2% of the work. Testing alone took fifteen times as long as building the features being tested. This isn't inefficiency. This is what production software requires.
Our codebase is 53% test code. That's not overhead. It's what allows us to confidently add features, fix bugs, and refactor without breaking existing functionality. Every time we change something, 2,912 automated checks verify we didn't break anything else.
The Actual Timeline
Here's how the project actually evolved over two months:
Notice the pattern: security and testing weren't afterthoughts bolted on at the end. They were there from day one, woven into every phase of development.
What "Enterprise-Grade" Actually Means
The gap between prototype and production isn't just about adding more features. It's about building the invisible infrastructure that makes software trustworthy:
Clean Architecture: 13 Layers of Separation
Our codebase follows enterprise-grade separation of concerns. Each layer has a single responsibility and clear boundaries:
Controllers Orchestration, business flow
Views DOM manipulation
Infrastructure Utilities, logging, DOM helpers
Domain Pure business logic (no I/O)
Gateway NetSuite API calls
Taskpane App coordinator
Persistence localStorage access
State AppState management
Services I/O orchestration
UI Notifications, toasts
Security Input validation
Platforms Mobile/Add-in entry points
Shared Constants
A prototype doesn't need architecture. Production code that will be maintained for years does. This structure means any developer can find what they're looking for, changes in one area don't ripple unpredictably, and bugs can be isolated quickly.
Security That Actually Protects
A prototype can store API keys in the JavaScript. A prototype can accept whatever the user types. A prototype can trust that inputs are well-formed. Production code cannot.
- SQL injection prevention via input sanitization on every query parameter
- XSS protection verified by 27 automated tests covering 12 attack vectors
- Rate limiting per user, designed to work behind NAT
- Secrets management with all OAuth credentials server-side only
- CORS enforcement through a dedicated proxy server
Error Handling That Doesn't Crash
Users do unexpected things. Networks fail. APIs return errors. Tokens expire. Production software handles all of this gracefully:
- Type-safe error utilities that transform technical errors into user-friendly messages
- Request timeouts on every API call (30 seconds default, 2 minutes for bulk operations)
- Token refresh handling before expiration
- Validation at system boundaries (user input, external APIs)
- Structured logging for debugging production issues
Software isn't done when it ships. It's done when it's retired. Every line of code you write today is code someone (probably you) will need to understand, debug, and modify in six months. Architecture, documentation, and tests aren't extras. They're what makes maintenance possible.
Why This Matters Beyond This Project
The pattern we followed here isn't unique to time entry applications. It's the universal pattern of professional software development:
- Build with security from day one, not as an afterthought
- Test continuously to prove it keeps working
- Refactor deliberately as requirements evolve
- Document clearly so others can maintain it
AI tools have made building faster than ever. But they haven't eliminated the need for security, testing, and architecture. If anything, the speed of AI-assisted development creates pressure to skip the hardening. That's exactly when organizations ship fragile systems that become liabilities.
AI makes it easier to generate code, which makes it even more important to have testing, architecture, and documentation practices that can verify and maintain that code. The faster you can build, the faster you can build yourself into a corner.
The Bottom Line
Anyone with AI tools can build a demo. The skill, and the work, is in building something that:
- Doesn't break when users do unexpected things
- Doesn't leak credentials or sensitive data
- Doesn't rot into unmaintainable spaghetti
- Doesn't require the original developer to fix every issue
The 2,912 tests aren't overhead. The 13 architecture layers aren't over-engineering. The 314 commits over two months aren't inefficiency. This is what production software looks like.
The demo is the easy part. Building something that works reliably, securely, and maintainably is the job. We started that job on day one.
Building Systems That Last
Whether it's internal tools, customer-facing applications, or integrations between business systems, the same principles apply: build with security from day one, test continuously, and never treat architecture as optional.