Skip to content
Commits on Source (5)
......@@ -7,22 +7,26 @@ title: Backend
The source code can be found [here](https://gitlab.com/minds/engine).
## Structure
# Structure
The backend is split into two main areas, **Core** and **Controllers**.
**Core** is where all the heavy lifting modules and internal apis exist.
**Core** is where all the heavy lifting modules and internal apis exist.
**Controllers** support both *CLI* and *REST* api's. These are publically exposed as are the pulbic interfaces for the **Core** modules/managers.
**Controllers** support both *CLI* and *REST* api's. These are publically exposed as are the public interfaces for the **Core** modules/managers.
>TODO Other areas include:
* Common, TODO
* Traits, TODO
```
engine
└───Core
└───[Core](#core)
│ │
└───Controllers
│ └───Cli
└───[Controllers](#controllers)
│ └───[Cli](#cli)
│ │ └───
│ └───api
│ └───[api](#api)
│ │ └───v1
│ │ └───v2
......@@ -31,15 +35,69 @@ engine
└───Traits
```
# Core
## Abstraction design
Minds follows an abstraction design pattern - by separating complex processes into standalone chunks with singular responsibilities, it's easier to conduct tests and update infrastructure.
## Modules
Modules reside under the `Core` folder and must be registered in `Core\Minds.php`.
Modules reside under the `Core` folder and must be registered in `Core\Minds.php`
> TODO explain: we're going to use video chat as an example, define video chat [#creating-a-module]
> TODO add diagram here
![Module diagram](/assets/engine-module-diagram.png "Diagram of an example VideoChat module")
### Module building blocks
#### Essential building blocks:
__**The Model**__ (e.g. `VideoChat.php`)
* the characteristics that define a single unit of whatever content your module is going to handle (e.g. a single video chat)
* you'll want to `use Minds\Traits\MagicAttributes` so you can automatically use get/set/is methods on each of your model's properties
* if you'll be using an api endpoint to interact with the front end, include a `public function export() {...}` here so it can be picked up by your controller's `Factory::exportable()` function, (which transforms arrays into an exportable format)
* might include methods for calculating fields based on the repository response
>TO DO: example calculated field
__**The Manager**__ (`Manager.php`)
* interfaces with the repository
* hydrate the entities returned in the response here (if needed)
* >TODO include example?
__**The Repository**__ (`Repository.php`)
* interfaces with the database. Should **only ever** be referenced by its Manager
* `use Minds\Common\Repository\Response`
__**The Provider**__ (`Provider.php`)
* defines a function that registers your Manager to make it available for dependency
injection
__**The Module**__ (`Module.php`)
* creates an instance of your Provider and calls its `register()` function. Register your module in `Core\Minds.php`.
#### Optional building blocks:
__**Delegates**__
* small, stateless functions that are executed by Managers when something happens that has repurcussions elsewhere in the engine. e.g.:
- `NotificationsDelegate.php`
- `EventsDelegate.php`
### Creating your modules
#### Test first:
Managers, Repositories and Delegates should have 100% [spec test](#spec-tests) coverage.
For this example, we will create a module call VideoChat that makes use of Dependency Injection Proviers.
#### Core/VideoChat/Modules.php
### Creating a module
For this example, we will create a module called VideoChat that makes use of Dependency Injection Providers.
#### Core/VideoChat/Module.php
```php
<?php
namespace Minds\Core\VideoChat;
......@@ -81,7 +139,7 @@ namespace Minds\Core\VideoChat;
class Manager
{
}
```
......@@ -94,13 +152,7 @@ private $modules = [
```
## Manager / Repository / Delegates
Minds follows an abstraction design pattern. Managers should be interface with Repositories. Repositories should **only ever** be referenced by their respective managers.
Delegates are small, stateless functions that are executed by Managers.
Managers, Repositories and Delegates should have 100% test coverage.
### Manager.php
```php
......@@ -130,7 +182,7 @@ class Manager
$this->notificationDelegate->onAdd($model);
}
```
Note how we are able to switch out repositories here without impacting the wider codebase to could be interacting with our Manager. During migrations, a double writing pattern could be added with a few lines.
Note how we are able to switch out repositories here without impacting the wider codebase by interacting with our Manager. During migrations, a double writing pattern could be added with a few lines.
### Repository.php
......@@ -153,7 +205,7 @@ class Repository
...
```
### Delegates/NotificationDelegate.php
(You can give your delegate any name you wish, we are using NotificationDelegate as an example).
(You can give your delegate any name you wish, we are using NotificationDelegate as an example). (TODO Describe other common types of responsibilities that are delegated)
```php
<?php
......@@ -165,9 +217,46 @@ class NotificationDelegate
}
...
```
## Internal apis
### Events
### Entities
### Runners
To start all runners:
* `docker-compose up runners`
Runners are resource intensive, so you may wish to run just one, depending on what you're working on. For example:
* `docker-compose exec php-fpm php /var/www/Minds/engine/cli.php QueueRunner run --runner=NotificationDispatcher`.
## Spec tests
Minds uses [phpspec](https://www.phpspec.net/en/stable/) and encourages test-first development.
Specs are highly abstracted alter-egos of your Manager, Repository and Delegate files that allow you to focus on the bare-bones concepts of what those files will eventually do when they reach their final form (so you can plan effectively before tackling practical technicalities and specifics).
Make sure you include `@package Minds\Core\<<VideoChat>>` in `<<VideoChat>>.php` so it can be picked up by phpspec in `<<VideoChatSpec>>.php`.
### Executing
`bin/phpspec run`
\ No newline at end of file
To run all tests:
* `bin/phpspec run`
To run a specific spec file (or folder), add its name:
* `bin/phpspec run Spec/Core/VideoChats/Repository.php`
To run a specific test inside of that spec file, add its starting line number:
* `bin/phpspec run Spec/Core/VideoChats/Repository.php:42`
# Controllers
> TODO
## Cli
> TODO
## api
> TODO
* `pages[0]` refers to the parameters that are sometimes added to the end of an api call
......@@ -49,6 +49,50 @@ helm upgrade \
./helm-charts/minds
```
### Managing settings on the Review Apps
When a pod gets deployed, it runs the installer which creates the default settings.php from the settings.example.php. However, the helm charts override those values with the template that is in our [Helm charts](https://gitlab.com/minds/helm-charts)
To have your values persist across builds, you must extend the settings.php script in the (configMap.yml) (https://gitlab.com/minds/helm-charts/blob/master/minds/templates/configMap.yaml)
Do not hard code the values in the configMap, reference them via *.Values.key.subkey*:
```
// Twillio configuration
$CONFIG->set('twilio', [
'account_sid' => '{{ .Values.twilio.sid }}',
'auth_token' => '{{ .Values.twilio.token }}',
'from' => '{{ .Values.twilio.from }}'
]);
```
And add the values to the correponding yaml files
[Staging environment defaults](https://gitlab.com/minds/helm-charts/blob/master/minds/values.yaml)
[Production values](https://gitlab.com/minds/helm-charts/blob/master/minds/values-production.yaml)
### Why so many values and templating?
Because it enables us to do something really cool, like dynamically override configuration values for your staging environment - useful for turning on your feature flags.
You can test your *local changes* and manipulate the staging environments by using the helm-charts repo. Create your branch, make your changes and then, inside your helm-charts repository branch, run:
```
helm upgrade --reuse-values --wait
{your.staging.site.subdomain} ./minds
```
This will apply your template to the staging pod's configuration using your local changes.
Then you must restart the pod by finding its name and deleting it.
```
kubectl get pods | grep {your.staging.site.subdomain}
kubectl delete pod/{your.staging.site.subdomain}-minds-runners-{generated.suffix.returned.by.grep}
kubectl detete pod/{your.staging.site.subdomain}-minds-php-fpm-{generated.suffix.returned.by.grep}
```
## Production
The Minds production environment is deployed directly from the CI flow found [here](https://gitlab.com/minds/engine/blob/master/.gitlab-ci.yml#L97). Minds currently uses Docker/ECS, but plans to move to Kubernetes as soon as possible.
\ No newline at end of file
The Minds production environment is deployed directly from the CI flow found [here](https://gitlab.com/minds/engine/blob/master/.gitlab-ci.yml#L97). Minds currently uses Docker/ECS, but plans to move to Kubernetes as soon as possible.
......@@ -14,6 +14,8 @@ The source code can be found [here](https://gitlab.com/minds/front).
### Development
`npm run build-dev`
Keep this running while you are editing so your changes will automatically be reflected when you refresh your browser. Note that this doesn't work for stylesheets - when working with .scss files, you'll need to run `gulp build.sass` in minds/front before you can see those changes.
### Production
> Production build can take up 30 minutes to complete
......
......@@ -9,7 +9,7 @@ title: Git / Gitlab
**Branches** are preferred over forks, as they integrate with the **Review/Sandbox** environments.
Branch names should be no more that **20 characters** long and include the following prefixes:
Branch names should be no more that **20 characters** long and include one of the following prefixes:
- **fix/** *(also include the issue number)*
- **chore/** *(also include the issue number)*
......