
Builder Cloud
September 11, 2017
Opportunity
Create a maintainable and updatable CMS leveraging seven years of collected domain knowledge in the new home marketing vertical.
Existing Technology
An existing CMS written in procedural PHP had been expanded upon over seven years based on client feedback. The existing product was feature-rich but difficult to maintain. Lack of documentation and the haphazard way new features had been added made the product risky to update or expand. A change or fix in one part of the system often had unforeseen consequences and an under-reliance on automated testing meant clients were often first to notice.
Custom vs. Off-the-shelf
I love to code but I’m also a strong believer that you should use off-the-shelf components whenever possible. There are countless off-the-shelf content management systems and although none will be a perfect fit, neither will the one you create from scratch. Projects like WordPress, ExpressionEngine, and Drupal have communities supported by thousands of developers. Attempting to compete feature-to-feature with these thousands of developers, testers and third party integrations is almost a guarantee of falling behind. On the other hand, cooperating with an existing project effectively adds those thousands to your team. Any time a bug is fixed or a new integration added updating to the latest version is much faster than reinventing the wheel.
In this particular instance there were two factors requiring a custom solution. One, the organization and staff of the company had grown alongside the existing application. Rather than using best-practices and industry norms to make architecture decisions, the application was formed to conform to the strengths and weaknesses of longstanding team members. In short, Conway’s Law was in full effect. Adapting the company to any off-the-shelf solution would require retraining and reorganizing of staff. A solution was needed that would take advantage of current staff and existing process.
Two, new home marketing data has opportunities to handle one-to-many relationships in unique, domain specific ways. For example, a design or ‘plan’ for a new home may be available in several different communities or even on several specific lots within communities. Following the database principle of reducing redundant data, we store this data only once but we present the data to the user both when managing the plan or when managing the community. We also store variations, or overrides to the base plan data. A plan in a specific community may have a different base price or elevation photo because of different licensing requirements, materials costs, community association rules, etc.
Solution
A year in advance we began recording analytics of clients use of their admin interface. A base schema was arrived upon by comparing our analytics with a compatibility matrix of supported third party features. Any data within the top 90% of admin edits or required for compatibility with any third party was included in the base schema. We also found that the vast majority of day-to-day use was handled by just a few core functions and decided to focus the majority of our optimization effort there.
Though a custom solution was chosen, off-the-shelf components were used whenever possible. A MongoDB instance with a complete data set already existed from a previous project. The built-in replication features of MongoDB made that database almost infinitely scaleable. A open-source API project, Python Eve, was selected due to its compliance to RESTful principles and its ability to expose complex geo-spatial queries and data projections to front-end developers. Eve made it efficient to create new front-end components with little or no back-end changes to the API.
Custom UI components were added to display data like latitude and longitude that had previously been difficult to visualize. Using a Google API to calculate latitude and longitude based on an address meant that clients could stay within the Builder Cloud application and did not have to rely on third party geocoding. Displaying latitude and longitude on a map allowed end users to quickly check that the correct location was selected. When an address was incorrect or too new to be properly geocoded, the user could simply drag and drop the map pin to make a correction. A process that previously required taking time to train clients, multiple browser windows, and generated a significant number of support tickets was made into a selling point for Builder Cloud.
School names needed to be exact to sync with third parties and the Great Schools API was integrated to provide local school and district names as well as a myriad of additional school data. Simply selecting a school from a drop-down list of nearby schools enabled the school website, ranking data, parent reviews, and district information all to be displayed with no additional data entry required by the client. Allowing marketers control over how schools were selected and featured reduced support tickets when compared to fully-automated school feeds while still keeping information accurate.
The remaining 10% of schema data was handled graphically within the CMS by creating custom ‘widgets’ or by adding multidimensional properties to existing models. The simplest example is a custom field added to all homes to allow the builder to record something specific like lake access, roof type, or a sales brochure or PDF. A more complex example would be creating a completely new data type of ‘Community Series,’ then adding properties to the Community Series describing features, photography, amenities, upgrades and extended warranties. The Community Series could then be added as a custom selection on each Community, allowing anyone with HTML and AngularJS templating knowledge to display communities marketed by ‘Series’ on the front-end.
Additional functionality such as interactive features and third party feeds were added to Builder Cloud as ‘products.’ Each Builder Cloud product is a stand-alone feature that can be implemented independently of any other products. Each product uses a sensible list of defaults and fallbacks, enabling products to be enabled or disabled for a client with just a click of a checkbox. What used to require hours of developer time and testing in the older system became a few clicks in the new.