We went to production with our B2B e-commerce product going on three months ago. I've waited this long to write anything about it because I wanted to include in my documentation the process we used to address bugs we found after we went to the field as well as all of the interesting nooks and crannies of the architecture, what worked, what didn't, what I will do again, what I will be changing through careful refactoring, etc. Over the next few weeks look for posts covering in some detail the topics outlined here.
Setting the Stage
This is a small application written by myself and one other dev over the course of three months. This is not a COTS product nor is it written for a single client. Our application provides a hosted set of core "out of the box" functionality that can facility B2B e-commerce as is, but all of our customers require some amount of customization. When I said small, I meant small. We average six (6) requests per second during business hours and spike to about forty (40) requests per second during peak times (moving the mouse on the server causes more CPU utilization than than the app itself :) The core application is only forty-three (43) models, six (6) controllers, forty-two (42) actions (including overloads), nineteen (19) views, and twenty-seven (27) services. We integrate with five (5) third parties for things like credit card authorization and capture, real time shipping quotes, inventory availability, customer profile management, and order fulfillment. We use a private build of MonoRail RC3 with Windsor integration and Helen Keller's view engine of choice. We use NHibernate 2 wrapped with Rhino Commons for persistence and log4net for all our logging needs. This was a legacy application that has been in production for approximately four (4) years that originated as a classic ASP application, was ported to ASP.Net 2.0 Web Forms, then was refactored to a home grown ASP.Net 2.0 MVP framework, and is now in its current incarnation.
High Level Overview
I will be talking in volumes about the ability to customize nearly every aspect of our small application. The reason is because all of our customers need the ability to receive an order from an end user, perform some sort of validation on the order information, then feed that order into their order fulfillment system. The problem is that every customer has a slightly different take on end user, validation, and fulfillment system :) Rather than write separate products for each customer or make a branch of the code for each customer we sign, our goal was to provide a core application that can be kept current, with new core features added as time goes on, and still allow any level of customization a specific customer requires. This could be anything from re-arranging user interface elements on one or more screens, to making email address an optional field, to authorizing a credit card, but not capturing it, to feeding an order into SAP or into a legacy AS/400 order system via custom web services. Some customizations become configuration options in the next release of the core product. Others are so far out there they they will always remain customizations. We also have the rare customer that happily uses the core product as is. This model allows us to provide a tiered customization path: configuration changes can be made by operations monkey, view customizations can by made by any html monkey, and service customizations can be made by any code monkey (that's me). So rather than giving our customer the brush off of "we will look at incorporating that in our next version", they flash us the cash and we do the deed, without affecting or breaking the core product or any other hosted customers.
The Highlights
Here are the topics I plan to touch on in no particular order. Some will be brief others might span a few posts. As I write the posts I will come back here and update the links and I might add other topics as I think of them.
- Managing Configuration - Me: "Check out this new feature in v5", Marketing: "That's configurable right?"
- Managing Customization - Marketing: "Customer wants to sell stuff without displaying prices", Me: "Ha ha, good one. No...you're serious?...seriously?...are you kidding me?...are your f***king kidding me!"
- Post Production - Patching, hot fixing, and tracking down bugs
- NHibernate Tricks - Poor Man's Shards
- Windsor Tricks - My Golden Swiss Army Knife
- Layout Tricks - Handling Popup Windows, Sidebars, and Error Notification
- jQuery Tricks - How do I love thee? Let me count the ways.
- Brail Tricks - I have an Orange Belt in Quack Fu
posted @ Wednesday, May 28, 2008 12:04 PM