New Architecture Approach
1: Base Architecture Goals
The new architecture is designed to solve the following problems with the current codebase:
A) Maintenance difficulty. The current codebase is quite unstructured and difficult to maintain. 1.2.x has already been a bit of a mess due to the issues of fixing something one place and having it break something else.
B) Interoperability difficulty. In 1.2.x interoperating with the codebase requires very brittle and opaque interfaces. We need to change this to allow for add-ons in different languages using a number of stable methods.
C) Ease of customization. Many vertical solutions require customizations to work effectively. The current software is not easy to customize. 1.3.x makes some progress in this area but more work is needed.
2: Current Approach
We are refactoring the code along the lines of an MVC architecture. This architecture, however, is slightly different than other MVC implementations and hence we have decided not to use any framework and simply refactor code as appropriate.
A) Model: Unlike most MVC implementations, the model will be defined as much as possible in the database and methods will be implemented in stored procedures. A lightweight Perl wrapper will exist to allow us to dynamically discover these methods. Essentially, the ORM will be defined in the db.
Currently we require an explicit mapping between object methods and database stored procedures. We may replace this with something like Module::Compile down the road.
The in-db ORM will allow the entire data model of the application to be accessible to other components possibly written in other languages. Other implementations of the entire web software could easily be written in arbitrary languages (Java and Python have both been discussed), as well as add-on components.
B) View: The current approach to the is to support a non-default subset of Template Toolkit which is in line with XML, SGML, and HTML standards. This should allow for easier access to the templates in other languages due to our use of PI tags. More mature areas may be moved over to XSLT-based templates based on XML representation.
The second point of interoperability will also be through a view component: those of RESTful web services. Many or all objects in the system will have XML representations and these can be accessed using standard HTTP operations (GET, PUT, POST, etc).
C) Controller: The controller components will be light-weight workflow scripts automating the interaction of the user with the view and model components.
3: Stored Procedure Conventions
Stored procedures will be named according to the following convention of class_method (all lower case).
Stored procedures may use named arguments corresponding to object properties. Because PostgreSQL does not allow for arguments to have the same names as columns used, all named IN variables will be prefaced with in_. The model wrapper will discover these names, strip the prefix, and match with appropriate properties.
4: Why not use a framework like Catalyst?
Most MVC frameworks assume that the MVC components are broken down along specific lines which are not condusive to our goals. In particular the ORM layers do not work well with our approach.
In general, the consensus has been that these frameworks are the wrong tool for the job, that they add needless complexity, and that using them would create pressure to abandon our architecutral goals in favor of a single-language solution. In short, we have yet to be convinced that the added complexity would be worth it.