Customizability in SaaS Software - An Experience Report Part 1

by Alexander Huber

It has now been over 15 years since we made time cockpit available. To be precise, it launched on January 1, 2010. Since then, we have been active in the market with our product. Time cockpit had several unique selling points back then. For example, there weren’t many time-tracking tools featuring a graphical calendar, and the Activity Tracker was a novelty. Today, many time-tracking systems include calendars, and activity trackers have become more common. However, as far as we know, what remains unique is the customizability of time cockpit.

In this first blog post of the series, I want to explain why customizability was so important to us at the time and why it might also be relevant to you, especially if you are considering developing a new SaaS application. We’ll take a closer look at the core aspects of customizability – particularly the metamodel and the dynamic data layer.

The Core Concept: Customizability

The foundation of time cockpit has a name: the so-called COFX (Cockpit Framework). To be honest, time cockpit is just one of several applications developed using COFX. Other products, such as TFM and Emir-ate, are also based on the framework. All of these are data-driven SaaS applications. That is precisely what COFX is – a framework for data-driven applications.

Time cockpit is our flagship product, and COFX was specifically developed for it. Why was customizability so important to us? The founders of Software Architects and time cockpit poured their extensive experience as executives of a service company into the product. One thing was clear: if time tracking was the goal, it had to be customizable. Why? Because every company is different.

Take IT service companies as an example. While they may operate similarly, they are not the same. They differ in their structures, processes, and requirements. Companies evolve – they grow, shrink, and their processes change. From our experience, standard products are insufficient for many use cases. Successful software must adapt to the specific needs of a company.

Technical Implementation: Stable Core and Flexible Customizations

We designed time cockpit to include a stable core along with domain-specific business logic out-of-the-box. This covers complex calculations such as overtime tracking, vacation and leave management, and detecting violations of work-time regulations. Customer-specific requirements can be implemented through configuration and light coding. Furthermore, enhancements to the core are made easier with this architecture.

From a business perspective, customizability offers many advantages. Time cockpit generates revenue through both monthly subscription fees and professional services to tailor the product to customers’ needs. Another crucial aspect is that customizability allows us to increase the Customer Lifetime Value (CLV). Since time cockpit is flexible and can adapt to the evolving requirements of a customer, there is no need for them to switch to a new product when their business demands change. Instead, they stay within a familiar environment and continue working with a provider they already know and trust. This also eliminates the need for costly migration projects and extensive employee training. Customers can maintain their established workflows, saving both time and resources.

The Pillars of Customizability

The customizability of time cockpit is built on several pillars:

  1. Metamodel and Model
  2. Dynamic/Adaptive Data Layer
  3. String Templates
  4. Dynamic Query Language
  5. UI Engine
  6. Scripting Language Based on IronPython

In this article, I will focus on the first two pillars – the metamodel and the dynamic data layer.

Metamodel and Model

COFX, and thus time cockpit, is a model-driven application. It includes a metamodel that defines the structure of an application built on COFX. The metamodel of time cockpit consists of central elements such as:

  • SYS_ENTITY
  • SYS_PROPERTY
  • SYS_RELATION
  • SYS_PERMISSION
  • SYS_MODELACTION
  • SYS_ENTITYVIEW

These metamodel elements are stored in so-called SYS tables in the database. These tables are integral to every customer database and are interpreted by the data layer. For instance, the table SYS_ENTITY contains entries like APP_Timesheet, APP_Project, or APP_Task, which are specific to the domain of time tracking. The table SYS_PROPERTY describes the properties of these tables.

SYS tables form the metamodel and store information about the application’s data model. This data model consists of two main components: APP tables and USR tables. APP tables are included as part of the standard product and represent core functions, while USR tables are created specifically for customers’ unique requirements.

In our approach, we separate standard features from user customizations using namespaces (e.g., SYS, APP, USR). This method has proven successful in simplifying updates and ensuring continuous development of the standard product.

Another key advantage of our approach is that all entities exist as tables in the database. APP_Timesheet, APP_Project, and their properties (columns) and relationships (foreign keys) are part of a well-structured database schema. This schema is readable and understandable by both humans and machines. Data is stored relationally rather than in XML or JSON columns, resulting in several advantages. For example, we can directly access the data with SQL tools like SQL Management Studio, Azure Data Studio, or SSIS. This allows large-scale data imports to be performed directly via the database without requiring the time cockpit Web API.

Direct access to the relational database schema opens additional integration possibilities. Tools like Power BI or Tableau can connect directly to the data, greatly simplifying reporting and analysis. Many of our customers already have expertise in these tools, enabling them to perform analytics in their preferred environments (Power BI, Tableau). This approach has proven effective for us and might be worth considering for your projects.

Dynamic Data Layer

While a metamodel is essential, it does not offer practical value for applications like time cockpit or COFX on its own. The dynamic data layer of COFX plays a central role and is responsible for:

  • Reading and interpreting the metamodel to analyze and dynamically adapt the model at runtime
  • CRUD operations (Create, Read, Update, Delete) on data, enabling flexible manipulation without hardcoding
  • Flexible data queries based on the metamodel (a topic for a future blog post)
  • CRUD operations on the metamodel, allowing runtime modifications of the data model

In the object model (e.g., in C#), only the SYS tables are implemented as POCOs. APP and USR tables do not exist in the source code; they are dynamically generated and compiled at runtime. For instance, if the metamodel defines a TextProperty for APP_Timesheet, a string property is generated in C# using reflection. The same applies to other data types like DateProperty and NumericProperty.

A significant advantage of our dynamic data layer is that changes to the data model can be implemented on-the-fly and rolled out without requiring a recompilation or redeployment of the software. This was a key reason why we avoided frameworks like Entity Framework during the initial implementation, as such frameworks (at the time of development) required recompilation for such changes.

The dynamic generation of objects has helped us meet varying requirements within a single version. This has reduced complexity in release management. A similar approach might be beneficial for your architecture.

Another advantage of the dynamic data layer is its ability to efficiently manage customer-specific extensions. Customers often have unique requirements, and we address this through dynamically generated objects. This reduces the need for multiple versions and streamlines release management.

For us, an architecture that supports adjustments without redeployment has increased agility and minimized operational interruptions. We can implement changes quickly and efficiently, saving time and reducing costs. This approach might also benefit your projects.

The manipulation of data is handled dynamically. Instead of using direct code like timesheet.Description = "foo", we use dynamic methods such as timesheet.SetMember("Description", "foo") for setting values or timesheet.Get("Description") for retrieving them.

But it’s not just application data that can be created, modified, and deleted via the data layer – the data model itself can also be changed. Tables, properties, relationships, business logic, forms, and lists can all be added and modified at runtime. This often allows time cockpit to be adapted to customer needs through scripting and configuration alone, without requiring a new version to be deployed.

The ability to leverage metadata and runtime adjustments has enabled us to respond to customer requirements more quickly and efficiently. This flexibility has proven to be a significant advantage in delivering solutions tailored to customer needs.

Conclusion

The combination of a metamodel and dynamic data layer makes COFX, and by extension time cockpit, a proven framework for data-driven SaaS applications. Customizability has not only been a technical advantage but also a strategic asset in enabling sustainable product development and meeting diverse customer needs.

In the next part of this series, we’ll explore time cockpit’s custom query language and string templates, offering further insights into the functionality and benefits of this approach.