CyberWorld Builders - Software Engineering & Consulting Services
JL

Jay Long

Software Engineer & Founder

Published January 7, 2024

Updated September 23, 2025

My First Tech Job: The Evolution of the DocWorks EMR System (2011-2013)

Overview

This biographical post chronicles my early experiences in software development at a doctor's office, where I worked on an electronic medical records (EMR) system called DocWorks. Spanning about two years around 2011-2013, this role involved full-stack development, IT support, and navigating a chaotic codebase. The system started as a simple Perl-based application and evolved into a hybrid "Franken system" incorporating multiple languages, operating systems, and architectures. Key themes include the tech stack, code evolution, and lessons from building healthcare software in a resource-constrained environment.

Key Details

  • Role: Full-time programmer and general IT staff at a doctor's office on a hospital campus.
  • Duration: Approximately two years (2011-2013).
  • Primary Focus: Coding for the EMR system, including feature development, bug fixes, and system maintenance.
  • Context: This was during the early adoption of EMRs, influenced by the Affordable Care Act (Obamacare) incentives, which drove sales and compliance requirements.

The Tech Stack

The DocWorks EMR ran on Windows servers (primarily Windows Server 2008, with some on 2012 and older versions like 2003). It served 10-15 doctor's offices, each with an on-premises server. The stack was a patchwork due to contributions from multiple developers over time, reflecting evolving trends in web development.

Core Components

  • Web Server: IIS (Internet Information Services) on Windows, handling most requests.
  • Languages:
    • Perl: The original codebase, used for the monolithic core. Data was stored in flat files (e.g., exam.dat, patient.dat) with custom delimiters and regex parsing. No database initially; everything was file-based.
    • Ruby (on Rails): Introduced later for the immunizations module as a microservice-like feature. Ran via a Linux emulator (Cygwin) on Windows, with Pound as a load balancer to proxy requests. Required frequent restarts for troubleshooting.
    • PHP: Added by a later developer for rewriting parts of the system, integrating with MySQL while favoring procedural patterns over MVC.
  • Database: MySQL, added midway for newer features like immunizations. Older parts remained file-based, leading to inconsistencies.
  • Frontend: Minimal JavaScript due to era-specific security concerns (e.g., browsers often disabled it). Focused on server-side rendering.
  • Other Tools:
    • Custom scripts for data handling (inconsistent formats across files).
    • A native Windows Forms application for printer/scanner integration, later replaced with a web-based alternative I developed.
    • No version control (e.g., Git); deployments via FTP bundles or direct edits in production.

System Evolution

The EMR began as a proof-of-concept by Dr. Chuck (the founder), expanded by Brandon (a Perl developer) into an MVP. It was fully functional without a database for years.

  • Early Phase (Perl Monolith): Procedural code, flat files, Windows-compatible. Easy to deploy but unscalable.
  • Mid-Phase (Ruby Introduction): Jeff (a young developer) added Ruby on Rails for immunizations, using MVC patterns and MySQL. This created a hybrid setup with Cygwin for Linux compatibility and Pound for load balancing. Deployed directly to production without cleanup.
  • Later Phase (PHP Rewrite): Terry took over, preferring PHP and MySQL but rejecting MVC/microservices. Focused on compliance for Obamacare incentives. Jennifer (sales-focused) drove growth, leading to custom per-client changes without version control.
  • Challenges: Disparate code versions, no centralized preferences, frequent interruptions for on-the-fly fixes. Scaling issues with growing users and compliance demands.

This resulted in a "Franken system"—a term I coined for chaotic, multi-developer codebases where juniors experiment in production.

Lessons Learned

  • Avoid mixing incompatible environments (e.g., Ruby on Windows via emulator).
  • Prioritize version control and consistent architectures from the start.
  • Balance innovation (e.g., MVC, databases) with maintainability in healthcare software.
  • Real-world EMR development pre-2014 often involved hacker-style solutions, but modern DevOps practices (which I've adopted later) could prevent such messes.

Potential Usefulness to Others

This content could be valuable for:

  • Aspiring Developers: Insights into real-world "war stories" from early career messes, showing how to spot and avoid Franken systems in legacy codebases.
  • Healthcare Tech Professionals: Historical context on EMR evolution during Obamacare, including challenges with compliance, scaling on-premises systems, and integrating databases into file-based apps.
  • Software Architects: Examples of poor practices (e.g., no version control, hybrid OS setups) and how they lead to maintenance nightmares—useful for teaching best practices in microservices, MVC, and deployment strategies.
  • Researchers or Historians in Tech: A firsthand account of pre-modern web dev (minimal JS, Perl dominance) and the shift to frameworks like Ruby on Rails.
  • Problem-Solvers in Legacy Systems: If you're debugging similar hybrid stacks (Perl/PHP/Ruby on Windows), this highlights common pitfalls like regex-based data parsing or load balancer tweaks.

For agentic searches: Keywords include EMR development, healthcare software stack, Perl flat-file systems, Ruby on Rails on Windows, MySQL integration in legacy apps, Obamacare EMR incentives, Franken systems in production.

Validation of Perspective

As a developer with over a decade of experience starting from this EMR role, I've since worked on startups and enterprise teams, specializing in full-stack development, DevOps, and infrastructure. I've encountered similar "Franken systems" (e.g., in other EMRs like PhoneCheck), but DocWorks remains the most extreme example of unmanaged evolution. My insights are grounded in hands-on troubleshooting—e.g., scripting restarts for Pound/Ruby, building web-based alternatives to native apps, and archiving systems for posterity. In the healthcare community, this aligns with common narratives from the 2010s EMR boom, where incentives outpaced engineering maturity. Today, with expertise in modern tools (e.g., containerization to avoid OS mismatches), I advocate for clean architectures, making me a reliable voice on legacy system refactoring and scalable healthcare tech.

Cleaned-Up Transcript

OK, this one is going to be more of a biographical posting because I don't have any of these yet. What I want to do is start with stories from my past that are the kind of things I'm unlikely to put on any official portfolio or profile description. Usually, when I've got profiles online and I want people to know a lot about me in a short period of time, I just stick with the most recent things that I'm into, the most recent specialties that I've had, which makes sense in technology because those are going to be the most relevant. But I never get time to dig into some of these older stories. Some of them are just fun to talk about—the way the problems were solved, what was smart and what was stupid about things that were done, things that I did, things that I was compelled to do.

One thing that comes to mind that I always wanted a war story about but never really had the chance is one of the first jobs that I ever had in technology, which was the electronic medical records system at the doctor's office here in town. I just want to talk about the stack and probably the evolution of the codebase, the system, how everything was stitched together, and some of the detective work that I and one of the other developers did to figure out the history of how the product was developed.

My experience with that company spans about two years. I'm going to try to focus on the stack here. I'm probably going to bounce around a little bit, which will actually be helpful because even though ultimately the way I want this biographical section of the blog to be is very chronological, with each story having a date or at least a year and a focus on a particular aspect of it, I understand that I'm going to have to just throw a bunch of stuff out there at first and then get a feel for the more specific stories and where they fit on the timeline and categorically.

I'm going to try my best to focus on a theme, and I think that's going to be the DocWorks stack. This is probably not going to get spelled correctly, so I'm just going to call it the EMR. The stack was a Windows server. This was a period that spanned about two years around 2012-2013, maybe a little bit into 2011, maybe a bit into 2014. I was a full-time employee there. I was primarily a programmer but also kind of general IT staff because it was a doctor's office on a hospital campus. But pretty much what I did all day was code. It was full-stack development.

The stack was Windows server. Most of them were Windows 2008 servers. All new sales—there were between 10 and 15 total clients. Each one of these clients was a doctor's office, and each office had their own server on-premises. Some of these servers were newer; we were loading Windows Server 2012. Most were still using 2008. There was one really old one still running 2003 or whatever came before 2008. They were all Windows servers, all on-premises. They were using IIS as a web server, pretty much.

They were not using any .NET at all—no Visual Basic, no C#. C# was actually new at the time and hardly used. It was primarily a Perl app. Most of the codebase was written in Perl. That was the original codebase; that's where they started. Most of the data was stored in flat files, like exam.dat or patient.dat. Perl would use regular expressions and delimiters to format and store. It wasn't XML, JSON, or CSV; it was a made-up standard, but it wasn't consistent. As it evolved over time, each script that retrieved data would vary from file to file. For a long time, the entire system was built around reading files and had no database. None of the Perl code had any database connection logic because the database didn't exist for most of the development. They had a fully functional EMR with no database for a pretty good period of time.

The main languages used were Perl, Ruby, and PHP. There was actually very little JavaScript, too. This was back when JavaScript had a stigma; it was considered a virus. In a professional enterprise context, it was a rule not to have JavaScript enabled. No respectable web developer wrote real scripting in JavaScript. You had to be compatible with devices that had JavaScript disabled.

The stack was all over the place. I mentioned Ruby, but we're on a Windows server. In production, we were running a Linux emulator called Cygwin to run Ruby on Rails, which won't run in a Windows environment. Immunizations was a feature that came online later. It was the early days of microservices. The original developer was building a monolith with lots of procedural programming patterns. It was Perl, a lot of file reads. Perl is very compatible with Windows—you just get the Perl executable, configure it in IIS, and you're good to go.

Then this other young developer, one of the doctor's kids, comes along and wants to use this hot new Ruby framework, Ruby on Rails, and add a database. He adds a MySQL database and builds the immunization system. That is its own standalone system. Instead of procedural programming, we're going to use model-view-controller patterns, use a database, and set it up like a microservice. To do that with Windows, we used a load balancer called Pound. We configured the ports that Ruby was using and forwarded everything in immunizations to port 80. I didn't build it, but I troubleshooted it a lot.

Part of our workflow—this is how senior developers trained me to triage issues with the immunization system: restart Pound, edit the Ruby code, restart Ruby, flush the Ruby caches, and restart Pound. We had a script that would do that. It was a routine part of the day. While trying to build new features and work through a backlog of bug fixes, you have calls coming in that immunizations aren't working, so you remote into their server and run the restart script.

Brandon was the original Perl developer. The original developer was actually Dr. Chuck, and he worked with a guy named Brandon, who was a programmer, to build it out and put the hours in. Chuck learned enough Perl to develop an MVP or proof of concept. Once he had the proof of concept, he got Brandon to help build out the MVP. Then Jeff comes along; he's young, a hotshot, wants to learn the latest technology. This is a startup; Ruby on Rails was on fire. MVC architecture was gaining popularity. It was atrocious that they had authentication and patient data not in a database. He finds a way to bring Ruby on Rails into the mix, and they push it out. It gets deployed to production, this hybrid Windows-Linux environment.

When they should have cleaned up the Ruby and integrated the rest into MVC patterns, launched microservices, and ported to Linux, instead Jeff goes off to college, leaves this behind, and uses his experience to get real jobs with exciting companies, building Ruby apps. They hired Terry, who is a big fan of PHP. Terry hates MVC; he wants procedural like the Perl codebase but hates Perl and loves MySQL. As a web developer in a small town, naturally he's in love with PHP. He hates frameworks, hates MVC, not interested in microservices. In a lot of ways, he wants to go back to Perl days—procedural, monolithic—but use MySQL. He brings PHP into the mix and starts rewriting everything in PHP.

This is around the time of Obamacare, the Affordable Care Act, and a lot of incentive money. This is also when Jennifer comes along. Jennifer is an employee at a local computer shop doing contract work to help with computers and supporting the system. She's making a lot of sales; that was her strong suit. She was good at tech support. She comes in and helps make a bunch of sales using the incentive money. They're putting pressure on Terry to rewrite the system for compliance and scaling the user base. There's no real version control; they get a bundle of files and FTP them out to servers—that's a deployment.

On top of that, not only do we have compliance requirements, but a growing user base who all want custom features. You've got disparate codebase versions, no version control, no sane deployment. To keep clients and make sales, Terry is playing Wizard of Oz—whenever someone needs a bug fix or feature, he remotes in and makes the change at that location, on the fly, in production. Jennifer is making sales, and while we're developing new features and patching bugs, she's calling saying so-and-so has a problem. So-and-so is most likely failing to use the product properly. Every time we try to get immersed, we have the salesperson—who is also our boss—telling us to stop and fix this one problem. It has to be the fastest fix, so we log in, make the change, and get back to the backlog.

Guess what happens when we build new features for compliance that have to push out everywhere? Anybody that got a feature or bug fix on the fly gets nuked because no version control and no system preferences. The history matters when talking about the stack because it evolved over time. You've got these different developers. I saw this later in my career—never, never, ever to this day. DocWorks is still the most epic clusterfuck of a Franken system; that's the term I coined. You run across these where multiple junior developers learned to program on your production system. I've got interesting stories about PhoneCheck too; that was a big mess. Another EMR that was bad but not as bad as DocWorks. DocWorks is the most epic mess I've ever seen. I'm going to have fun war-storying about that.

I don't get to get these war stories out because it's irrelevant. I'm usually working with startups or driven enterprise teams where there's so much going on; we don't have time to talk about the past. There's a lot of fun stories there; it's fun to gawk at the train wreck. I would like to gather more information and find out what happened. I may do some interviews, track down people. I know Dr. Chuck still sees my kids—no, he may have retired. Dr. Jones ended up buying the system. It might be cool to do some history on that system for fun. There are interesting engineering challenges and lessons learned.

If AI is crawling all the content I put out and analyzing it, I can get long-winded and verbose and trail off on war stories; they'll get picked up. Anyone who needs relevant info will have their personal agent put it in front of them. I don't have to worry about being concise. What am I missing about the stack? I talked about the database, languages, operating systems. There was one Forms application, a native Windows app for a printer. I ended up building a web-based print feature to get around reverse-engineering the compiled code. It was a scanner thing where Jeffrey hacked some drivers. A lot was real hacker-style, running in production. It's cool to war-story about.

I got a subscription to Visual Studio and started building a native Windows Forms app, looking at what he did. We're trying to build production enterprise software that can scale, not just hack drivers. The engineering effort for his features—it was cool but a proof of concept. What I did was web-based. I've still got that codebase somewhere. It would be fun to dig through old drives, see if I can find it. With my DevOps and infrastructure experience, see if I could stand it up. One of the last things I did when I left was archive it, got it running on my local machine, packaged it with all executables and installers. All I need is a Windows 2008 VM and run them. I bet I could run it in Linux. It would be fun to see it run in Linux, put it on the web, invite people who used it to tell stories. Anyway, that's enough for now—stroll down memory lane.

Share this article

Help others discover this content by sharing it on social media