Featured Project: Zeggio

Technologies: PHP, CodeIgniter, Zend, MySQL, Angular, jQuery, jQuery UI

Services: Chargify, RackSpace CloudServers and CloudFiles, Google Apps

A good application is more than just the sum of its technology. Zeggio is no exception. Contact management, deal and project management, task organizer, and time tracking all in one convenient package, Zeggio has proved to a be challenging and rewarding project. Each piece individually is straight forward. Add in the ability to cross-link all that data, keep it organized and secure inside a multi-user, multi-account system that allows individual users to belong to multiple accounts and those individual parts become a potent and flexible tool.

Security, security, security. It is not a feature that often appears in the marketing material. Security is expected. A single breach can undermine years of hard-won customer trust, tarnish an otherwise pristine reputation. That is why when I started building Zeggio my first programming project was to build a flexible and tight security layer. I took inspiration from Unix, modified a little to suit the needs of the project. Each piece of data is given an id, groups of data given id\''s, even entire sections, so that, within an account, user groups could be assigned specific authorization to act on that data. Authorizations are granted by selecting authorization nodes, programmer created flags, that could be checked in code to validate access. User groups within other groups inherit permissions from their parent if their permissions are not explicitly set. By creating a permission mask of all groups a user belongs to combined with the other characteristics of the security system, the whole becomes very flexible and very configurable to just about any need while remaining rigid enough in the execution logic to be stable, predictable, and effective.

The second challenge was figuring out how link all the data together without getting bogged down in complicated, hard to maintain SQL joins. In a system like Zeggio that allows the user to import contacts, create projects, link contacts to projects, add notes, tasks, time, and invoicing data to a project, then see the aggregated data for all projects associated with a contact through that contacts record and the code can quickly become unwieldy and overly complex.

My goal on this project was to keep the code as modular and as simple as possible, making it not only easier to test but also to maintain. This is where CodeIgniter\''s (CI) MVC model came in very handy. Deviating a little from CI\''s recommended guidelines, the controllers became sentries into the data, a frontline defense checking a user\''s permission to access a particular piece of data, before immediately passing the request off to a model function. The models were given the task of putting together the data sent back to the browser, making any security checks that the controller might not have, and requesting data from the libraries. Perhaps the most significant deviation I made from CI\''s MVC model was moving all the database interaction from inside the models and into libraries. This necessity became evident very early when one model might need to access data normally handled by another model, something not allowed in CI. With so many models doing similar things, it made more sense to push all the queries into specialized libraries that all the models could share. The models request data from the libraries then assemble it into the structures. Doing this solved the problem of code redundancy and broke up responsibility cleanly between the controllers, models, and libraries. Each layer has a very specific function. By writing short and simple queries in the libraries and letting the models put the data together the number of complex joins needed dropped to only a handful. The modeled data was then sent back to the controller, combined with a view template, which could be passed the users authorization mask and areas of the template could be selectively shown or removed before being sent back to the browser, reducing the chance of bad actors manipulating the rendered templates in the browser.

Javascript frameworks are a more difficult problem. Not because there are so many good ones, but because there are so few. I knew I wanted a framework designed around MVC, that would be easy to write tests for and would work easily with jQuery. After wading through several poorly written and/or poorly maintained options I came across Angular, a fairly young framework with some very intriguing features, the biggest of which for me was its two-way data binding, a system of binding data entered in form elements to a data structure held in an Angular controller. The data from the backend is passed to an angular controller, stored as a data model, and combined with the template for that data, which contains Angular directives for how to display the model. Angular\''s ability to define widgets, data filters, iterators, and other niceties allowed me to minimize the amount of formatting needed on the backend, while creating many reusable templates on the frontend.

Having been involved on the Zeggio project from the start, choosing the technologies used, organizing the code architecture, and watching all the pieces fit together by actually writing the application has proved an incredible opportunity and an immensely gratifying experience.