In trying to suss out how best to implement a SaaS application using CB, I started to address multiple domain use. Using the multiple domain ses interceptor from forgebox and some modifications, I can now easily “know” how the user is coming into the system with a little creative introspection and a table of valid domains / hosts. Once I have this of course, a database can easily provide configuration options unique to that “client”.
Now there is the problem of host customization. Typically in a SaaS application, much of what a user can do is clearly defined by what is available to the application and the particular host in question…in other words, here’s the SaaS application, take it or leave it. I might give you some creative color and layout control, but customizing the clients experience from a development point of view is only done through pre-determined programmable solutions. For example, client “x” wants a custom form they can provide to their users via a link on their home page. If the SaaS provides a form creation tool and a basic CMS for the front end…done.
However, let’s look at another situation, like storefronts accepting payments. The client can create store items and can apply them to a store front cms by which their users can select materials, apply them to a “cart” and check out. However, SaaS client “x” uses crypt pay and client “y” uses payflow.
So again, the SaaS application and provide the “base” interaction with any number of payment gateways but of course every client will have unique settings which a database can provide for…but now it gets more interesting.
Say one client uses a receipt system whereby a physical file must be dropped in an ftp directory that some other process is going to pick up. So far, no other client needs this. In an of itself, the code needed to do this is pretty simple but since only one client needs it, we want to be able to customize their solution but not impact core code and function in anyway.
Here it comes…
Modules.
It seems that being able to create a module, one per hosted client (unique domain url) would give me the ability to tie core code to a unique module so that initially the experience is the same for everyone…but then to customize the experience, module code can be messed with entirely and not impact core code or other client experiences with the software as a whole. This can be implemented in a simple way, say unique CSS skins for client “x” to the problem I’m outlining…core payment gateway code will have a setting that allows for a custom function call so that when a payment is processed, if the client has a defined custom post processing function, the gateway can check for it and call that code…in this case taking the payment results and information and writing it to a file in a specific location for their FTP use.
However, while this brings up all sorts of great ideas of custom interception points and interceptors and smart data registration of call back functions…my initial investigations yielded two problems I’m not sure I can get over.
-1-
Dynamic module creation and activation.
If I have some installation process that creates new clients (like my administration feature only) and I were to dynamically create a new module based on some settings, that module would not be included as usable until a reinit or the app restarted for some other reason. I don’t want to be reinit’ing the environment every time I need to create a new client. Furthermore, at the session level on down, I really don’t want to “activate” all the modules since only one would be relevant at the time…so when someone first hits the site, the only module (other than public or cross-host modules) loaded is the one relative to that domain. Remember, this cannot be an application wide accessible module, it has to be unique to the request / session.
Can this be done? Does it make sense? The goal here, in case I’ve successfully obfuscated it, is to provide a means for custom development and future unique client solutions without having to adjust “core” code shared by all clients.
-2-
Let’s presume #1 is resolved…the next concern I have is the url. In order to actively approach module code via the url, there is an entry point that clearly identifies in a unique way how to access module code.
uwoshkosh.mike.com/index.cfm/uwoskosh
that url provides me with the unique domain which my interceptor can grab, but then in order to uniquely access the clients module (see above item for details), there has to be a module subdirectory somewhere, in a sea of subdirectories, that uniquely identifies it in the url. We can eventually get rid of the index.cfm part…but you can see it almost appears redundant:
Is there anyway to change the nature of how we access the entry point by setting the module reference in some code-based way so that the session can explain which module directory is being used based on the domain…
would solve the problem…but without the url telling CB which module is being referenced…that won’t work in this format.
Thoughts?
Mike