At a high level Ushahidi consumes messages from various channels (SMS, Email, Twitter, our own web interface), transforms these into posts. Ushahidi core stores and exposes this data in a REST API. The primary consumers of the REST API are our web client and mobile app.
The Platform is split into 3 layers: Presentation (Client / Web interface), Services (API), and Data.
[Presentation| %20%20%20%20[AngularJS] %20%20%20%20[Endpoints] ]
[Services| %20%20%20%20[API]o->[Kohana]%20 %20%20%20%20[API]o->[Ushahidi%20Core] %20%20%20%20[Kohana]-->[PHP] %20%20%20%20[Ushahidi%20Core]-->[PHP]%20%20%20 ]
[Data| %20%20%20%20[MySQL] ]
The REST API provides all data access. This provides for the main Ushahidi user interface, but also any external services and partners that need to access data.
The API layer consists of a core application (models, usecases, etc) and a delivery layer (routing and controllers). The core application is pure object-oriented PHP and the delivery mechanism is a PHP application built using the Kohana Framework.
In theory the Kohana application could handle frontend views and interactions too, but splitting the API out allows us far greater flexibility in the variety of applications that we can build. Mobile apps, 3rd party integrations, etc are not 2nd class citizens: they can consume the same API as our primary frontend. The API has to be able to do everything to our data.
Containing the core business logic within a core application that is separate from the Kohana delivery layer allows us to test the core application, independent of the database (or any other implementation details) while also enforcing the internal API by which the rest of the system operates. This allows us to modify internal details, such as the database structure, without breaking the external API, as well as ensuring that the entire system remains in a stable, tested state.
Within the API there are two layers: the delivery and the business logic (core application). The delivery layer follows a Model View Controller (MVC) pattern, with the View consisting of JSON output. The Controllers use a Service Locator to load and execute various tools, taking the API request inputs and returning the requested resources.
Within the core application, we use generally follow the Clean Architecture. The central part of the business logic is defined as use cases and entities. All dependencies flow inwards towards the entities, which have no dependencies.
In order to bring user input to the use cases, we pass simple data structures from the delivery layer into the use case. The request structure is a simple array and contains all of the inputs for that specific use case. Once the usecase is complete it returns another simple data structure (response) back to the delivery layer for conversion via a Formatter. Data flow within the platform can be visualized as:
[app]->[Kohana] [Kohana]->[Controller] [Controller]->[request] [request]->[Usecase] [Usecase]->[response] [response]->[OutputFormatter] [OutputFormatter]->[json]
[request| payload%3B identifier%3B filters]
[Dependencies| %20Repository%3B %20Validator%3B %20Authorizer%3B %20etc... ]o->[Usecase]
See Use Case Internals for more detail