-
-
Notifications
You must be signed in to change notification settings - Fork 724
Code, the way we do things (2018)
Note: This page is out of date and pending further discussion, please raise in #dev if not sure.
As in all code bases with some years we have different approaches to solve similar problems. Usually developers find better ways of doing things and go for it as they are implementing new features. This page lists and clarifies, for some topics, what are the existing ways of doing something in OFN and what is the recommended way of doing it.
In many backoffice pages, OFN frontend code sends requests to the server with bulk actions: list of entities to be actioned, for example, a list of products with a list of prices to be updated on those products. This technique makes the code unnecessarily complex. We have agreed that we want to stop using this technique. The better solution is to force the frontend code to make one request to the server for each of the entities changed by the user. So, if the user changes the price of 10 products in the backoffice, the frontend code will make 10 calls to the api to update those 10 prices.
If we want to get closer to having an API based application, we need to stop building screens using rails views accessing data from the rails models. We need to make use of the API for every part of the app. Spree pages are not built in this way BUT this logic can be used for all the spree screens that we replace/rebuild to adapt to our needs. This topic is being discussed here: https://community.openfoodnetwork.org/t/how-we-build-web-pages-rails-views-vs-angular-templates/1378
Also to support the development of an API, we need to stop using AMS to inject json into the dom and start using the API. Also applicable to spree screens that are rebuilt.
We should create an Angular DataLayer. Even if data is getting to Angular through AMS and angular modules with data (see availableCountries for example), we need to create a data layer where ALL access to data and server APIs are placed. No angular controller should make HTTP calls to the server. If a angular controller needs to access the server to post some data for example, that should not be done in the controller, it should always be done through the data layer or service.
To support the development of the API we need to define really well how to implement new endpoints on the API. Below are a few decisions related to that:
- we dont use serializers with RABL as in app/views/json. We prefer app/serializers/api
- all rabl files in views/api should be in controllers/api and/or serializers/api
- we need to move controllers that produce json into the api space, for example, controllers/ShopController should be in controllers/api
Folders with RABL files in the OFN code base: ./app/views/api ./app/views/open_food_network ./app/views/json ./app/views/admin/json ./app/views/spree/api (spree API overrides) This topic is being discussed here: https://community.openfoodnetwork.org/t/road-map-for-ofns-api/931/5
Spree Class extension is better than using class eval as with it we end up with an OFN class that extends the Spree class: we can test this OFN class and our code doesn't directly depend on a spree class.
When we want to change a Spree view, we used Deface to get our custom behaviour in the view. This has been painful to maintain and we now decided that all Spree views that are changed should be copied into our repository and changed as necessary without using Deface. This way we have a OFN view that depends on Spree code but does not depend on the Spree view.
Both rails and angular views should not contain any business logic. OFN's business logic should be contained in rails services and/or angular services. This is also valid for angular controllers that should not contain business logic but rather depend on angular services.
The ActiveRecord layer should not include any business logic. Instead of having the controllers and views depend directly on the data layer directly, a services layer is created to contain all the business logic. Another pattern we use when data layer is complex is to decouple ActiveRecord complexity in separate components still inside the data layer.
TODO: document database issues and approaches, and plan for refactoring
Development environment setup
- Pipeline development process
- Bug severity
- Feature template (epic)
- Internationalisation (i18n)
- Dependency updates
Development
- Developer Guidelines
- The process of review, test, merge and deploy
- Making a great commit
- Making a great pull request
- Code Conventions
- Database migrations
- Testing and Rspec Tips
- Automated Testing Gotchas
- Rubocop
- Angular and OFN
- Feature toggles
- Stimulus and Turbo
Testing
- Testing process
- OFN Testing Documentation (Handbooks)
- Continuous Integration
- Parallelized test suite with knapsack
- Karma
Releasing
Specific features
Data and APIs
Instance-specific configuration
External services
Design