├── .gitignore
├── README.md
├── backend_development.md
├── code_quality.md
├── documentation.md
├── frontend_development.md
├── github_flow.md
├── images
├── HLA.png
├── LA.png
└── SLA.png
└── react_native_development.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
106 | .idea/*
107 |
108 | # OS Generated Files
109 | .DS_Store
110 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Project Architecture Guidelines Index
2 |
3 | - [How to properly document the project](documentation.md)
4 | - [What git flow should be used](github_flow.md)
5 | - [What best practices should be followed while developing the backend](backend_development.md)
6 | - [How to improve the overall quality of the code base](code_quality.md)
7 | - [Frontend development guidelines](frontend_development.md)
8 | - [React Native development guidelines](react_native_development.md)
9 |
--------------------------------------------------------------------------------
/backend_development.md:
--------------------------------------------------------------------------------
1 | # Backend Development Guidelines
2 |
3 | ## 1. Choose a Proper Framework for Backend
4 |
5 | It is important to choose a proper backend framework that meets the requirements of the project. There are different python web frameworks (or microframework) available like Django, Flask, Pyramid, web2py etc.
6 |
7 | While in general different frameworks have different pros and cons ( this [link](https://hackernoon.com/top-10-python-web-frameworks-to-learn-in-2018-b2ebab969d1a) provides a good overview), Django along with Django Rest Framework seems to be a good choice in majority of the scenarios.
8 |
9 | ### Recommended Framework
10 |
11 | [Django](https://www.djangoproject.com/) with [Django Rest Framework](https://www.django-rest-framework.org/)
12 |
13 | #### Why DRF ?
14 |
15 | - Simplicity, flexibility, quality, and test coverage of source code.
16 | - Powerful serialization engine compatible with both ORM and non-ORM data sources.
17 | - Pluggable and easy to customize emitters, parsers, validators and authenticators.
18 | - Generic classes for CRUD operations.
19 | - Clean, simple, views for Resources, using Django's class based views.
20 | - Support for ModelResources with out-of-the-box default implementations and input validation (optional support for forms as input validation).
21 | - HTTP response handling, content type negotiation using HTTP Accept headers.
22 | - Pagination simplifies the process of returning paginated data in a way that can then be rendered to arbitrary media types.
23 | - Publishing of metadata along with querysets.
24 | - Permission classes and throttling management (API may feature a RESTrictive throttle for unauthenticated requests, a less RESTrictive throttle for authenticated requests, etc.).
25 |
26 | ## 2. Handling Credentials and Secrets
27 |
28 | - Never store secrets (passwords, keys, etc.) in the sources in version control! It is very easy to forget they are there and the project source tends to end up in many places (developer machines, development test servers, etc) which unnecessarily increases the risk of an important secret being compromised
29 | - They should be set and read from the environment
30 | - [Django Environ](https://django-environ.readthedocs.io/en/latest/) supports upto 12 ways of safely managing the critical credentials
31 |
32 | ## 3. API Versioning (Optional)
33 |
34 | - It is a good practice to have your API support versioning
35 | - While the importance of versioning may not be too clear in purely web based apps (since we have control of client update in our hands), versioning is super critical, when the API is consumed by Mobile applications
36 | - DRF provides different schemes to apply versioning, we can choose one that suits your scenario the best
37 | - [https://www.django-rest-framework.org/api-guide/versioning/](https://www.django-rest-framework.org/api-guide/versioning/)
38 |
39 | ## 4. Separate Settings File for Each Environment
40 |
41 | - There should be a separate settings file for each environment
42 | - This reduces the chances of wrong configurations, that were updated for testing purposes, being pushed to the production environment
43 | - Each developer should have a local\_settings file while, where the settings can be modified and this file should be added to [gitignore](https://git-scm.com/docs/gitignore)
44 |
45 | ## 5. Use Celery for Asynchronous Tasks
46 |
47 | - We often have to perform tasks like sending emails, processing images, creating reports, updating internal usage stats, that are not required to be done in the request-response cycle.
48 | - We can improve the user experience by doing these tasks in an asynchronous manner through task queues
49 | - Celery's integration with django is pretty straight-forward [https://docs.celeryproject.org/en/latest/django/first-steps-with-django.html](https://docs.celeryproject.org/en/latest/django/first-steps-with-django.html)
50 | - Celery provide following functionalities:
51 | - Execute tasks asynchronously.
52 | - Distributed execution of expensive processes.
53 | - Periodic/scheduled tasks.
54 | - Retrying tasks.
55 |
56 | ## 6. Error Logging and Alerts
57 |
58 | - As applications become more complex, having good logs can be very useful, not only when debugging but also to provide insights for application issues and performance.
59 | - Django provides a clear documentation, on how to add logging to your project
60 | [https://docs.djangoproject.com/en/2.2/topics/logging/](https://docs.djangoproject.com/en/2.2/topics/logging/)
61 | - It's always a good practice to set up alerts in case of any error/exceptions. So that rapid actions can be taken to reduce the effects of the outages
62 | - Django provides the option to inform the admins by email in case of exceptions (configuration is present in the link above)
63 | - It is always a nice idea to integrate third party services that provide more detailed and comprehensive alerting mechanism like [sentry.io](https://sentry.io/welcome/) , elastic.io, etc
64 |
65 | ## 7. Performance Monitoring Tools
66 |
67 | - As the user base grows, performance becomes more and more crucial
68 | - It is a good practice to have tools that monitor the performance of the app and provide insights regarding the areas of improvements.
69 | - These tools can provide helpful stats like
70 | - Number of requests
71 | - Average response time
72 | - Error rate
73 | - Revenue generated
74 | - Total Activity
75 | - Transactions time
76 |
77 | - Some of these tools are
78 | - [New Relic](https://newrelic.com/)
79 | - [Datadog](https://www.datadoghq.com/)
80 |
81 | ## 8. Caching
82 |
83 | - Caching plays a vital role in improving the performance of the app significantly
84 | - Django supports different backends for caching, like
85 | - Memcache
86 | - Redis
87 | - Database
88 | - FileStorage
89 | - Memcache and Redis are the most efficient ones among these options
90 | - Caching can be implemented on different levels
91 | - [Per View Cache](https://docs.djangoproject.com/en/2.2/topics/cache/#the-per-view-cache)
92 | - [Template Fragment Caching](https://docs.djangoproject.com/en/2.2/topics/cache/#template-fragment-caching)
93 | - [Low Level Cache API](https://docs.djangoproject.com/en/2.2/topics/cache/#the-low-level-cache-api)
94 |
95 | - Which form of caching has to be used, varies from scenario to scenario
96 | - Low level cache API can be used to cache resource intensive queries
97 | - Caching can backfire severely, if a proper cache busting mechanism is not in place. In addition to time based expiration, cache must be expired in case the underlying data updates.
98 | - One example of cache busting is to listen for a Model's post\_save signals, and delete the cache associated with it
99 |
100 | ## 9. Test Coverage (Optional)
101 |
102 | - Adding unit tests provide several advantages, some of them are
103 | - Make code updates easier and less prone to errors
104 | - Improves the quality of the code, helps in dividing the code into proper testable units
105 | - Provides a documentation of the system
106 | - DRF provides some pre-builts methods to ease unit test writing process
107 |
108 | [https://www.django-rest-framework.org/api-guide/testing/](https://www.django-rest-framework.org/api-guide/testing/)
109 |
110 | - Ideally, we should have more than _ **90%** _ of our codebase covered by unit tests
111 | - We can calculate the test coverage of our app by following this [documentation](https://docs.djangoproject.com/en/2.2/topics/testing/advanced/#integration-with-coverage-py)
112 |
113 | ## 10. Performance Improvements
114 |
115 | Not the complete list\*
116 |
117 | - Make sure to use [Django Debug Toolbar](https://django-debug-toolbar.readthedocs.io/en/latest/). It provides some very useful insights into the app performance. Most importantly it can provide a detailed analysis of the Database queries, that can help in highlighting the queries that are taking more time and bringing down the performance
118 | - Use [select\_related](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#select-related) and [prefetch\_related](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#prefetch-related) to optimize the queries. They significantly reduce the number of queries that are made to the database and provide a performance boost.
119 | - Implement caching (as mentioned above) to improve performance
120 | - Use Raw SQL queries, when super complex and performance critical queries are to be performed
121 | - If we're going to create more than one object at a time, use [bulk\_create](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#bulk-create) instead of creating objects in a loop
122 | - Similarly, perform the updates in [batches](https://docs.djangoproject.com/en/2.2/topics/db/queries/#updating-multiple-objects-at-once) too
123 | - Use [values](https://docs.djangoproject.com/en/2.1/topics/db/aggregation/#values) and [values\_list](https://docs.djangoproject.com/en/2.1/ref/models/querysets/#values-list), when only certain fields are to be fetched
--------------------------------------------------------------------------------
/code_quality.md:
--------------------------------------------------------------------------------
1 | # Code Quality
2 |
3 | ### Linting
4 |
5 | A code linter is a program that performs static analysis of your source code for potential errors. The kinds of errors a linter can detect include:
6 |
7 | - syntax errors
8 | - structural problems like the use of undefined variables
9 | - best practices or code style guideline violations
10 |
11 | A linter could help you develop faster, keep your code organized, and do less syntax mistakes that potentially could cause errors and break your code.
12 |
13 | Ideally, linting should be a part of our workflow. Before committing the code, linters should inspect the code and raise errors in case of any discrepancies.
14 |
15 | #### Python Linters
16 |
17 | Python has several good options for code linters. Following two are mostly used for linting:
18 |
19 | ##### [Flake8](https://pypi.org/project/flake8/)
20 |
21 | It's fast and has a low rate of false positives. Flake8 is actually a combination of several other tools, mainly the Pyflakes static analysis tool and the Pycodestyle (former pep8) code style checker.
22 |
23 | Checkout this documentation to integrate Flake8 with git hooks [https://flake8.pycqa.org/en/latest/user/using-hooks.html](https://flake8.pycqa.org/en/latest/user/using-hooks.html)
24 |
25 | ##### [Pylint](https://pypi.org/project/pylint/)
26 |
27 | Pylint is another good choice. It takes a little more effort to set up than Flake8 and also triggers more false positives. On the other hand, it provides a more comprehensive analysis.
28 |
29 | To integrate pylint with github flow, please refer to this link
30 |
31 | [https://git-pylint-commit-hook.readthedocs.io/en/latest/usage.html](https://git-pylint-commit-hook.readthedocs.io/en/latest/usage.html)
32 |
33 | #### JS Linters
34 |
35 | ##### [ESlint](https://eslint.org/)
36 |
37 | ESlint helps a team to follow unified rules increasing readability and purity of code. ESlint is highly flexible and allows customizing rules for errors, best practices, variable declarations, ES6 etc.
38 |
39 | ESlint works with a set of rules that you define. The most commonly used linting rules are [Airbnb](https://github.com/airbnb/javascript), which bills itself as "a mostly reasonable approach to JavaScript." And their linting rules are popular because they are simple, sensible, and beautifully consistent.
40 |
41 | A good guide to integrate ESlint as part of your workflow is:
42 |
43 | [https://medium.com/quick-code/how-to-integrate-eslint-prettier-in-react-6efbd206d5c4](https://medium.com/quick-code/how-to-integrate-eslint-prettier-in-react-6efbd206d5c4)
--------------------------------------------------------------------------------
/documentation.md:
--------------------------------------------------------------------------------
1 | # Documentation
2 |
3 | ### On Boarding Document
4 |
5 | An onboarding document should be created that gives an in detail view of the whole project. That includes
6 |
7 | - Introduction of the project
8 | - Technology stack of the project
9 | - Different components of the project
10 | - Engineering practices being used
11 | - Link to setup guides
12 | - Development workflow
13 | - Project management tools/methodology being used
14 |
15 | A good example of how an onboarding document should look like is:
16 |
17 | [https://github.com/artsy/README/tree/master/onboarding](https://github.com/artsy/README/tree/master/onboarding)
18 |
19 | ### Setup Guide
20 |
21 | Each repository must have a setup guide, that basically contains the steps in detail to have the project running locally.
22 |
23 | Few guidelines to write a good setup guide are
24 |
25 | - Setup guide should be written down considering a fresh OS, so make sure to include the OS level installations too in the documentation
26 | - Consider that the person using the setup guide has no prior knowledge about the project, and he/she should be able to setup the project without requiring any help
27 | - Add a section of _"FAQ"._ This should include the issues and their solutions that developers come across while setting up the project
28 | - Once the document is complete, ask the QA engineer or request someone from another team, to setup the project using these guidelines. If they still face any issue while setup, that means the guidelines are not complete
29 | - Make sure that the setup guide is updated as the project progresses
30 |
31 | Docker is now-a-days is trending very rapidly. So if possible, try to setup your project through [docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/). Through Docker, project can be set up using only a couple of commands and removes the errors that occur due to OS and machine differences.
32 |
33 | ### Readme
34 |
35 | A README is a text file that introduces and explains a project. It contains information that is commonly required to understand what the project is about.
36 |
37 | There are different templates available that can be used to write a good readme file.
38 | For example:
39 |
40 | [https://gist.github.com/PurpleBooth/109311bb0361f32d87a2](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2)
41 |
42 | Like other documents, we must make sure that readme file is up to date with the progress. Ideally, it should be part of the issues/stories of the project that the related documents should be updated.
--------------------------------------------------------------------------------
/frontend_development.md:
--------------------------------------------------------------------------------
1 | # Frontend Development Guidelines
2 |
3 | This document aims to serve as a baseline for the majority of medium to large-scale front-end / JavaScript-based projects in Arbisoft. We've curated the best practices in one place in order to ensure adherence to the quality level, performance, and extensibility of the products we deliver. Beyond all of the guidelines mentioned here, the most important thing to make an effort for is developing a culture of creating quality among ourselves; the rest will follow automatically.
4 |
5 | _Note: The recommendations of tools and libraries present in this document are suggested based on their long-standing past experiences and great track record in the industry for their performance and maintainability. Nonetheless, we know that the JS world is continuously evolving with innovation. Therefore if there is any library/tool superior to the suggested ones in this document, please discuss with the committee and we shall incorporate it in our guidelines._
6 |
7 | **Definitions**
8 |
9 | | **Marker** | **Title** | **Definition** |
10 | | --- | --- | --- |
11 | | 
12 | | Highest Priority | _Must be_ implemented or followed. This can not be compromised in any case. |
13 | | 
14 | | Medium Priority | _Should_ be implemented or followed. This can only be left over with a fairly justifiable rationale and a future plan to handle later on. |
15 | | 
16 | | Low Priority | _Good to Have_but can be ignored in the interest of available resources and project priorities. |
17 |
18 | ## 1. Choice of Framework for Frontend
19 |
20 | Choose a framework for a frontend that can build applications that are able to be used by thousands and millions of users. Keep performance, extensibility, and community support in mind when choosing a framework. Our recommendations of the framework(s) are:
21 |
22 | ### 1.1 Recommended Framework 
23 |
24 | [React.JS](https://reactjs.org/) with [Redux](https://redux.js.org/)
25 |
26 | ### 1.2 Scaffolding 
27 |
28 | - [create-react-app (CRA)](https://github.com/facebook/create-react-app) / [react-boilerplate](https://github.com/react-boilerplate/react-boilerplate)
29 | - [react-slingshot](https://github.com/coryhouse/react-slingshot)
30 |
31 | ### 1.3 UI Development 
32 |
33 | - UI Library for the project should be implemented using [storybooks](https://storybook.js.org/)
34 | - Kick-start UI Libraries: [rebass.js](http://rebass.js/) | [blueprint](https://github.com/palantir/blueprint) | [ant-design](https://github.com/ant-design/ant-design) | [material v4](https://material-ui.com/blog/material-ui-v4-is-out/)
35 |
36 | ### 1.4 Optimizing Ubiquitous Feature Aspects  
37 |
38 | - Folder Structure Which [folder structure is ideal](https://marmelab.com/blog/2015/12/17/react-directory-structure.html) is a long-running discussion with varying subjective opinions. It is an important aspect to discuss nonetheless and the experience of working with large-scale applications tells that _Component Folder Pattern_[[1]](https://medium.com/styled-components/component-folder-pattern-ee42df37ec68)[[2]](https://nikitajajodia.com/2018/05/04/component-folder-pattern-in-react-js/) is the best one in terms of scaling for growing codebases.
39 | - Forms A common pitfall is to implement custom form-handling because it is so easy to do it in React.JS - instead choose a mature & stable library like [formik](https://github.com/jaredpalmer/formik) or [react-final-form](https://github.com/final-form/react-final-form) to handle all forms and their respective validations in a consistent, performant manner. ([DO NOT use](https://github.com/redux-form/redux-form/issues/4171)[redux-form](https://youtu.be/WoSzy-4mviQ) as its deprecated; [react-final-form](https://github.com/final-form/react-final-form) is the newest library from the same author) 
40 | - Date and Time Handling Usually the de-facto choice for handling date and time (w.r.t. to time-zones) in JS apps is moment.js, but it has a [huge footprint](https://bundlephobia.com/result?p=moment-timezone@0.5.28) on the bundle size of the app and is now in maintenance mode. Therefore it is recommended to use new light-weight alternatives like [luxon](https://moment.github.io/luxon/#/) or [date-fns](https://date-fns.org/) instead. 
41 | - Utility Functions [Lodash](https://github.com/lodash/lodash) is a great utility for working with reference data-types (objects, arrays, strings, nested structures) in order to manipulate or search them. However, it also has a [large footprint](https://github.com/lodash/lodash) on the bundle size of the app. Therefore it is advised to use [individual lodash functions](https://www.npmjs.com/~jdalton) as packages. This way you can avoid installing the whole library. 
42 | - Immutability With the increasing demands of data-driven front-end apps, it is more than ever important to achieve immutability while working with JS reference types to achieve a predictable behavior of the language and avoid hard-to-debug errors. Therefore we recommend using [immer](https://github.com/immerjs/immer). 
43 |
44 | ### 1.5 CSS Framework 
45 |
46 | - [CSS in JS](https://github.com/MicheleBertoli/css-in-js)frameworks like [styled-components](https://styled-components.com/)
47 |
48 | ### 1.6 Language for Development  
49 |
50 | - [JavaScript](http://javascript.info/) (Duh!) - [ES2015+ aka ES6](https://github.com/lukehoban/es6features) 
51 | - [TypeScript](https://github.com/basarat/typescript-book)
52 |
53 | ### 1.7 Lint Your Code  
54 |
55 | - JavaScript / TypeScript / JSX / Node.js: [ESLint](https://eslint.org/) with thorough [Linting Rules](https://www.npmjs.com/package/jslint-configs) 
56 | - CSS / SCSS / CSS in JS: [StyleLint](https://stylelint.io/) 
57 | - Setup Linting as pre-commit Hook: [Husky and Lint-Staged](https://codeburst.io/continuous-integration-lint-staged-husky-pre-commit-hook-test-setup-47f8172924fc)
58 |
59 | ## 2. Optimize React Apps for Speed & Extensibility
60 |
61 | ### 2.1 React.JS 
62 |
63 | - Use React.JS as **V** iew of MVC Although React.JS provides built-in APIs (State, Context) to work with the data, it is still better to treat React as a View technology, i.e., React part of the codebase should only be responsible for rendering dumb UI. This translates into React code mainly using Presentational (Functional) Components instead of Class Components and being free from any kind of data manipulation. Use _selectors_ (explained later) to perform data manipulation and inject it as props to the respective Presentational Component and dispatch actions to perform any async operations. The biggest benefit of _not using_ React's State for data manipulation is that one won't need to implement the lifecycle hook of React like shouldComponentUpdate to do performance because React will only be rendering dumb UI. [[3]](https://spin.atomicobject.com/2017/06/07/react-state-vs-redux-state/)[[4]](https://github.com/krasimir/react-in-patterns/blob/master/book/chapter-13/README.md) 
64 | - Prefer React Hooks over React Class Components For using React's Lifecycle hooks, use the [new](https://youtu.be/dpw9EHDh2bM?t=706) API of [React Hooks](https://reactjs.org/docs/hooks-intro.html) instead of React's Class components. 
65 | - Create as many components as possible Even for the smallest UI elements 
66 | - Never use [Indexes as Keys](https://github.com/vasanthk/react-bits/blob/master/anti-patterns/06.using-indexes-as-key.md) 
67 | - Define [PropTypes](https://www.andreasreiterer.at/react-proptypes/) of Components 
68 | - Lifting UI state in Global Store The pattern of using React.JS also advocates lifting the state of application's UI elements from React's state into a global state like Redux (with the only exception being Forms), such that there is a single state-tree for the whole application. This also strengthens the deterministic nature of the application. [Reference](https://gist.github.com/InamTaj/eef0d629736bb9b96d2597ab35f5c94a) 
69 |
70 | ### 2.2 Redux 
71 |
72 | - Decompose Reducers Split up Reducers into maintainable, extensible chunks.[[5]](https://redux.js.org/recipes/structuring-reducers/splitting-reducer-logic/) 
73 | - Managing Side Effects [with redux-saga](https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html) Sagas is hands-down the best option to manage async processes (aka side-effects) for large-scale applications because they can handle async-chaining of side-effects by completely avoiding callback hell (redux-thunks cannot do this without a messy, buggy code). Sagas encourage clean and reusable code with minimum boilerplate and encourage explicitly, yet consistent error-handling of async actions. Sagas provide a very clean way of accessing stores _(sorry thunks)_ and are capable of handling parallel processes, forking, spawning, canceling, and a lot more. [[6]](https://survivejs.com/blog/redux-saga-interview/)[[7]](https://medium.com/netscape/when-should-i-use-a-saga-708cb3c75e9a)[[8]](https://medium.com/@js_tut/the-great-escape-from-callback-hell-3006fa2c82e)[[9]](https://shift.infinite.red/using-redux-saga-to-simplify-your-growing-react-native-codebase-2b8036f650de)[[10]](https://neal.codes/blog/common-redux-saga-scenarios) 
74 | - Use Selectors (with Memoization) Most of the components will need some dynamic data to be injected as props. For that purpose, an anti-pattern is to subscribe to the store (with connect() binding) and manipulate the props inside the component. This is completely wrong and any local manipulation of the data should be performed in selector functions. One should also use selectors for getting static data into the components, instead of hard-coding the static data in components. [[11]](https://www.nan-labs.com/blog/selector-pattern-in-react-redux-apps/)[[12]](https://read.reduxbook.com/markdown/part1/07-selectors.html)[[13]](https://blog.brainsandbeards.com/advanced-redux-patterns-selectors-cb9f88381d74) 
75 | - Data Normalization Implementing DRY in Redux means that one should also manage data duplication in the global store. This means that for large-scale apps, one should treat the application's global storage as a database. [[14]](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape)[[15]](https://blog.brainsandbeards.com/advanced-redux-patterns-normalisation-6b9a5aa46e1f) 
76 | - Reduce Boilerplate with Ducks Ever tried scaffolding your types/actions/reducers code? Use [Ducks Pattern](https://github.com/erikras/ducks-modular-redux) to minimize the repetitive codebase and ensure naming consistency in the redux entities. 
77 |
78 | ## 3. Performance Optimization
79 |
80 | ### 3.1 JavaScript 
81 |
82 | - Eliminate unused code with Tree-shaking Use ES6 Modules to import only required components in your code files, instead of importing default modules as a whole. When using destructured imports Webpack performs tree-shaking and eliminates dead-code in the production build. [[16]](https://developers.google.com/web/fundamentals/performance/optimizing-javascript/tree-shaking)[[17]](https://webpack.js.org/guides/tree-shaking/)
83 | - Remove render-blocking JavaScript JavaScript blocks the normal parsing lifecycle of HTML documents, so when the parser reaches a \<script\> tag inside the \<head\>, it stops to fetch and run it. Adding async or defer is highly recommended if your scripts are placed at the \<header\> of the page. [[18]](https://developers.google.com/speed/docs/insights/BlockingJS)[[19]](https://varvy.com/pagespeed/defer-loading-javascript.html)
84 | - Reduce JavaScript Payloads with Code Splitting A common anti-pattern is to load the whole bundle when a user lands on the website, even though the landing page doesn't need JS of all 30 other pages. In order to optimize the downloading times and bundle size of the application, use Code Splitting for your application.[[20]](https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting)[[21]](https://reactjs.org/docs/code-splitting.html)
85 |
86 | ### 3.2 CSS 
87 |
88 | - Divide CSS per-component basis Component level CSS helps keep the main CSS bundle lightweight which can also help at the time of code-splitting.
89 | - Maximize Reusability Using frameworks like [styled-components](https://styled-components.com/), you can easily achieve maximum reusability of CSS by making as many generic styles as possible.
90 | - Remove Render Blocking CSS CSS files need to be non-blocking to prevent the DOM from taking time to load.
91 | - Eliminate unused CSS CSS files that need to be non-blocking to prevent the DOM from taking time to load. Make sure your bundler can handle this.
92 |
93 | ### 3.3 HTML 
94 |
95 | - Use HTML5 Elements with Correct Semantics [[22]](https://htmlreference.io/)
96 | - Have Error Pages Configured (for 400, 500 errors with Inline CSS)
97 | - Minify HTML for Production
98 | - Place CSS tags before JS To avoid render-blocking in CSS Having your CSS tags before any JavaScript enables better, a parallel download which speeds up browser rendering time. [[23]](https://varvy.com/pagespeed/style-script-order.html)
99 |
100 | ### 3.4 Bundler Performance Optimization 
101 |
102 | ### Modern web applications often use bundling tools like Webpack or Parcel. Whatever bundler you use, there are certain aspects to take care of.
103 |
104 | - Decrease Bundle Size By minification of code, optimizing images, breaking to vendor vs. app bundles, lazy loading on routing level, etc.
105 | - Use long-term Caching Effective use of caching can save client's time on re-fetching bundles, hence ensuring low bandwidth usage and greater speed of application.
106 | - Guide To Webpack's Optimization [[24]](https://developers.google.com/web/fundamentals/performance/webpack/)
107 |
108 | ### 3.5 Wholistic App Optimization Principles
109 |
110 | - [Page Load Time](https://www.thinkwithgoogle.com/marketing-resources/data-measurement/mobile-page-speed-new-industry-benchmarks/) \< 3 seconds | [Page Weight](https://www.thinkwithgoogle.com/marketing-resources/data-measurement/mobile-page-speed-new-industry-benchmarks/) \< 500 KB (before gzipped)  
111 | - TTFB (Time To First Byte) [[25]](https://scaleyourcode.com/blog/article/27) \< 1.3 seconds | Time To Interact \< 5 sec [[26]](https://tools.pingdom.com/) 
112 | - Continuously Monitor app bundle for smaller size [[27]](https://evilmartians.com/chronicles/size-limit-make-the-web-lighter)[[28]](https://github.com/ai/size-limit) 
113 | - Continuously Profile app's rendering performance [[29]](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)[[30]](https://developers.google.com/web/tools/chrome-devtools/rendering-tools/js-execution)
114 |
115 | ## 4. Configuration, Deployment, Release, Monitor
116 |
117 | ### 4.1 Mange Secrets and App Constants as Configurations 
118 |
119 | - Secrets and App-level Constants as Configurations Hardcoding of secrets, 3rd-party URLs is a major security risk, therefore moving such constants out of the codebase to environment variables is highly recommended. This also lets you separate out secrets for multiple environments.[[31]](https://serverless-stack.com/chapters/environments-in-create-react-app.html)[[32]](https://levelup.gitconnected.com/how-create-react-app-fakes-environment-variables-a08a9cb6e581)
120 |
121 | ### 4.2 Reproducibility with Containerization 
122 |
123 | - Containerize the Application _"It works on my machine"_ syndrome should be handled early on in the development lifecycle to ensure reproducibility of the application's artifacts. This can save a lot of time later on at the time of deployment to test and production environments. Docker is the de-facto standard for achieving containerization.[[33]](https://mherman.org/blog/dockerizing-a-react-app/)[[34]](https://medium.com/greedygame-engineering/so-you-want-to-dockerize-your-react-app-64fbbb74c217) For mono-repos, it is best to use [docker-compose](https://www.baeldung.com/docker-compose).
124 |
125 | ### 4.3 Dev/Prod Separation
126 |
127 | - Separate out build-configuration per Environment 
128 | - Separate out docker-builds per Environment 
129 | - Track Configurations (not Secrets) under app/confs (or separate org/configs repo) 
130 |
131 | ### 4.4 Setup CI 
132 |
133 | - Integrate CI to continuously Lint and Test codebase against each PR in your Platform such as CircleCI, GitHub Actions, GitLab CI, etc. [[35]](https://www.freecodecamp.org/news/how-to-set-up-continuous-integration-and-deployment-for-your-react-app-d09ae4525250/)
134 |
135 | ### 4.5 Monitor for Events in Production 
136 |
137 | - Monitor for app's crashes or unexpected behaviors with services such as [Sentry](https://sentry.io/for/react/) or [Rollbar](https://rollbar.com/)
138 |
139 | ## 5. Test Your Code
140 |
141 | ## Testing is an essential part of the application lifecycle and it increases the maturity of the codebase with increasing feature-set. [Jest](https://github.com/facebook/jest) provides the most advanced test-runner with a lot of built-in assertions. [react-testing-library](https://github.com/testing-library/react-testing-library)
142 |
143 | ### 5.1 Snapshot Testing 
144 |
145 | This is a low-friction, low-return type of testing using which with a few lines of code, one can persist the Markup of UI components and track accidental changes.
146 |
147 | ### 5.2 Integration Testing 
148 |
149 | ### You should write e2e integration tests that can fire up some actions, trigger sagas to execute processes of application, and then finally test the expected state of reducers. This is the most crucial part of testing and if the project uses redux-sagas, the testing experience is really intuitive and meaningful. This is another reason to ditch redux-thunks in favor of sagas.
150 |
151 | ### 5.3 Setup Unit Testing of Utilities 
152 |
153 | ### With simple test assertions of Jest, one should write unit tests for all utility functions/helpers present in the codebase to ensure correct behavior.
154 |
155 | ### 5.4 Monitor and Achieve a Higher Code Coverage 
156 |
157 | - Using Jest's built-in code-coverage reports, keep an eye on the code coverage and always aim for higher code coverage. Use tools like [codecov](https://codecov.io/) to integrate into your development workflow and test code coverage against each PR in your CI pipeline.
158 |
159 | ### 5.5 Automation of Acceptance Testing 
160 |
161 | - Automate the Acceptance / Black Box Testing of the application with [Cypress.io](https://www.cypress.io/) and integrate it in your CI pipeline to ensure that the new feature-set does not break the application.
162 |
163 | ### 5.6 Setup Code Contribution Insights 
164 |
165 | - Using tools like [codeclimate](https://codeclimate.com/) you can set up engineering analytics and help Engineering Managers understand the productivity of developers and detect bottlenecks in the delivery of features by extracting information from code commits and pull requests.
--------------------------------------------------------------------------------
/github_flow.md:
--------------------------------------------------------------------------------
1 | # Github Flow
2 |
3 | These are some suggestions that can be followed to implement a really useful Github Flow in daily development:
4 |
5 | ### Separate Branch for Each Deployment Environment
6 |
7 | **Master** - Code in this branch should be fully tested and ready to be deployed to production. No code should be
8 | directly pushed into master branch.
9 |
10 | **Staging** - Staging branch should be used for testing by the QA engineers. Ideally this branch/environment should be
11 | an exact replica of the production
12 |
13 | **Develop** - This branch contains pre-production code. Code is merged in develop once a feature is completed by a
14 | developer
15 |
16 | ### Development Branches Naming Conventions
17 |
18 | There are different types of naming conventions that are used. Anyone of them can be used, that suits the team best. But
19 | one thing has to be made sure that the whole always use the same naming convention.
20 |
21 | Some naming conventions are:
22 |
23 | _[Developer Initials]-[Issue Id in Management Board]-[Very Brief title]_
24 |
25 | _[Developer Initials]-[Type of Work (feature, hotfix, bug)]-[Very Brief title]_
26 |
27 | _[Developer Initials]-[Date]-[Very Brief title]_
28 |
29 | There is no right or wrong in these conventions. However, consistency is the key, that there should not be any variation
30 | in the naming conventions used by the team
31 |
32 | ### Workflow
33 |
34 | There can be three types of workflows, depending upon the situation:
35 |
36 | 1. Feature/Bug Fix
37 | 2. Hot Fix
38 |
39 | **Feature/Bug Fix**
40 |
41 | - Create a new branch from develop
42 | - Once the development is complete, create a PR against the develop branch.
43 | - PR must be reviewed by developers and should have at least two thumbs up for it to be able to be merged
44 | - Squash and Merge the branch into develop
45 | - Delete the branch
46 | - After testing, develop branch is merged into staging
47 | - Staging branch is tested in staging environment
48 | - Once passed by QA, staging branch should be merged into master
49 |
50 | **Hot Fix**
51 |
52 | - Create a new branch from master.
53 | - Once the development is complete, create a PRs against Master and Develop branch.
54 | - PR should have at least two thumbs up for it to be able to be merged
55 | - After doing initial testing on the hotfix branch Squash and Merge the branch into Master and Develop
56 | - Delete the branch
57 | - Perform regression testing on the master branch
58 |
59 | ### Creating Release
60 |
61 | Please make sure that all of the production releases are documented and tagged on github
62 |
63 | [https://help.github.com/en/articles/creating-releases](https://help.github.com/en/articles/creating-releases)
64 |
--------------------------------------------------------------------------------
/images/HLA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arbisoft/architecture-guidelines/29c36794f3bb1e25293184e7784f6b849ca07a1d/images/HLA.png
--------------------------------------------------------------------------------
/images/LA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arbisoft/architecture-guidelines/29c36794f3bb1e25293184e7784f6b849ca07a1d/images/LA.png
--------------------------------------------------------------------------------
/images/SLA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arbisoft/architecture-guidelines/29c36794f3bb1e25293184e7784f6b849ca07a1d/images/SLA.png
--------------------------------------------------------------------------------
/react_native_development.md:
--------------------------------------------------------------------------------
1 | # React Native Development Guidelines
2 |
3 |
4 | ## What is React Native
5 | React Native basically builds apps for both android and IOS platforms using a single code base, i.e. JavaScript.
6 | Open source framework that helps you create real and exciting mobile apps
7 | Developed by Facebook in 2015
8 | Build cross-platform apps using JavaScript
9 | Just learn once and code once, and then React Native apps are available for both iOS and Android platforms
10 |
11 | ## When to choose React Native
12 | - When your App needs a native look and feels depending on the specific platforms.
13 | - More scalable and complex app.
14 | - Large number of community support packages are available for faster development.
15 | ## When not to choose React Native
16 | - Large scale project having heavy calculations and animations involved.
17 | - Apps with complex user interfaces
18 | - Apps that are designed for a single OS
19 | - Games and apps that require Native APIs
20 |
21 | ## Project Setup Architecture
22 |
23 | For large scale projects we should create 2 different repositories,
24 | - Components library containing Reuseable components (UI library for all the common resusable components that can be used across the app)
25 | - Main App Repo that will be consuming the above UI library to build scalabele and consistent screens.
26 | - Ideally we should ensure encapsulation of screens and components.
27 |
28 | Each root level folder exposes respective index.js file that helps us shorten the imports.
29 | Everything inside a folder is exported from the index file of that respective directory
30 |
31 | File names are in kebab-case which is hyphenated-like-this
32 | index.js files must be used in each directory for shorter imports
33 | If a file / concern spans on multiple files, create a separate directory for it
34 |
35 |
36 |
37 | ### High Level Architecture
38 | 
39 | ### Screen Level Architecture
40 | 
41 | ### Logical Architecture
42 | 
43 |
44 |
45 | ## Setup a Theming Guidelines:
46 | Without consistent styling, it's hard to get the best possible results. A Design System is a set of rules and principles that set the foundation for how the application should look and feel. You need 3 things to keep in mind while working with your design system.
47 | - `Spacing`: While working with a cross-platform application, the screen sizes might vary between different components present on a screen, but make sure to provide consistent spacing between them for a coherent look.
48 | - `Color`: Choosing the right colors is not only the most important thing but also how you use them. A great solution is to use Color Palettes, where you can name your colors according to the preferred naming conventions, which increases your overall workflow.
49 | - `Typography`: We often forget about how the fonts change the way our application look in the results. It’s best to stick to a limited set of font families, weights, and sizes to achieve a pleasant coherent look.
50 |
51 |
52 | ## Dynamic Styling with JS
53 | `Styled-components` is a CSS-in-JS styling framework that uses tagged template literals in JavaScript and the power of CSS to provide a platform that allows you to write actual CSS to style React components.
54 | Styled components are easy-to-make React components that you write with the styled-components library, where you can style your components with plain CSS inside your JavaScript code
55 | ## Responsive Style Properties
56 | Define some scalable functions that can help to handle UI on different device dimensions. Refer to the `react-native-normalize` for reference
57 |
58 |
59 | ## React Native Best Coding Practices
60 |
61 | - Organize imports such that all library imports are grouped together on top of the file, and rest imports will follow later.
62 | - Exception Handling in React Native Apps.
63 | - Sort all object properties.
64 | - Always terminate properties with semicolons.
65 | - Use stateless components as much as you can.
66 | - Avoid default exports and use named exports for better IDE support.
67 | - No Implicit returns.
68 | - Empty states should be implemented implicitly.
69 | - To use any package, the priority should be given to the react-native community.
70 | - Add comments in the code to clear ambiguity.
71 | - Stories to be placed under the storybook/stories folder.
72 | - Use Platform Specific Styles.
73 | - Always Assign Unique Key to Each Element.
74 | - Remove deprecated & unnecessary commented code.
75 | - Remove consoles.
76 | - Shouldn’t pass inline functions in JSX.
77 | - Props and Styles should be in a separate file.
78 | - Avoid Inline Styling.
79 | - Should remove repeated code and follow the DRY principle.
80 | -If the file/component is too large, then it should be separated into multiple files/components.
81 | - Should follow the style guides for styled files.
82 | - Code has appropriate unit tests and should achieve coverage more than 80%.
83 | -Tests are well-designed.
84 | - Lock Dependencies.
85 |
86 |
87 |
88 | ## Code Quality
89 |
90 |
91 | ### Configure Absolute Relative Paths in Codebase
92 |
93 | Using absolute imports to better organize your React project is a great way. Relative imports are hard to follow and break during refactoring. Absolute imports manage your project easier as it grows.
94 |
95 | Absolute imports have some advantages.
96 |
97 | - There is no ../../../../hell. Therefore easier to type out the imports.
98 | - Easily copy-paste the code with imports into another file in the project and not have to tinker with import paths.
99 | - It is short and sweet
100 |
101 |
102 | ### Linting:
103 | Use a linter to make your code easier to review.
104 | Follow strict linting rules. This in turn helps you write clean, consistent code.
105 | Rules recommendation: [ESlint Community Rules](https://www.npmjs.com/package/@react-native-community/eslint-config)
106 |
107 |
108 | ## Some Recommended Libraries to use:
109 |
110 | - `Redux` (If performance is a concern, the best way to improve performance is to skip unnecessary re-renders, so that components only re-render when their data has actually changed. React Redux implements many performance optimizations internally, so that your own component only re-renders when it actually needs to.)
111 | - `Styled Components` ( Styled components are easy-to-make React components that you write with the styled-components library, where you can style your components with plain CSS inside your JavaScript code)
112 | - `React Navigation` (It is one of the most widely used and actively developed libraries out there on the scene. It is also one of the solutions recommended by the React Native team. It’s the community solution being most pushed by Facebook.)
113 | - `Reanimated` (It’s a library that replaces RN’s Animated API, providing JS-based animation APIs that are easy to use and run on the native thread (which entails performance out of the box )
114 | - `Community Hooks` (React Native APIs turned into React Hooks allowing you to access asynchronous APIs directly in your functional components and provides you many handy hooks to use)
115 | - `Formik` (It is a small group of React components and hooks for building forms in React and React Native. It helps with the three most annoying parts: Getting values in and out of form state. Validation and error messages.)
116 | - `React Native Fast Image` (Its really a cool library to load the image at a very fast speed. FastImage component from react-native-fast-image is a wrapper around SDWebImage (iOS) and Glide (Android) which are very powerful image loaders in the native development)
117 | - `Axios` (Axios provides a simple-to-use library in a small package with a very extensible interface )
118 | - `React Native Firebase Crashlytics` ( Firebase Crashlytics tracks, prioritizes, & fixes stability issues that erode app quality. Quickly pinpoint the root causes of crashes with powerful, real-time crash reporting)
119 |
120 |
121 |
122 |
123 | ## Performance Optimization
124 |
125 |
126 | - `Avoid Use of ScrollView to Render Huge Lists`
127 | To handle large amounts of data in the list format, React Native provides FlatList. The items in FlatList are lazy loaded. Hence, the app does use an excessive or inconsistent amount of memory
128 | - `Avoid Passing Inline Functions as Props`
129 | This isn’t recommended because any time the parent re-renders a new reference, the function is created again. This means that the child component re-renders even when the props didn’t change at all. The solution is to declare the function as a class method or as a function inside a functional component so that the references remove any possibility of across re-renders.
130 | - `Make Use of Hermes`
131 | Hermes is an open-source JavaScript engine optimized specifically for mobile applications. It is available for the Android platform for React Native version 0.60.4 and above. It is also available for iOS from version 0.64-rc.0 and above. Hermes helps reduce the download size of the APK, the memory footprint and consumption, and the time needed for the app to become interactive (TTI - Time to Interact).
132 | - `Memoization using memo`
133 | Memoization is an optimization feature in React which, when used in the right place, increases the performance of the program. React gives us PureComponent and memo to implement memoization. PureComponent is used with the class component and memo is used with the function component. Memoization increases performance by storing results for functions when the same prop is passed, hence reducing the number of re-renderings. But, overuse of memoization in places where there are no performance issues can result in reduction of performance.
134 |
135 |
136 |
137 |
138 | ## Security
139 | One of the main concerns when developing a mobile app is data security.
140 | Especially when it comes to the data which are very sensitive and any security breach can lead to irreversible damage. Almost all the app contains critical information of the users, so app security is the optimum element, especially while dealing with passcodes, touch ids, account names, credit card information and more
141 | - Storing Sensitive Information
142 | Use Encrypted Storage just to make sure our app is secure. Async Storage is great but it lacks security. This is less than ideal when storing sensitive data such as access tokens, payment information and so on.
143 | - [Encrypted Storage Package](https://github.com/emeraldsanto/react-native-encrypted-storage) aims to solve this problem by providing a wrapper around Android's EncryptedSharedPreferences and iOS' Keychain to keep your information in
144 | encrypted format so that it won't be readable by an attacker.
145 | - [Security Aspects to consider](https://medium.com/simform-engineering/security-aspects-to-consider-for-a-react-native-application-95556f0e4244)
146 |
147 | ## Over the air Updates (OTA)
148 |
149 | Over-the-air (OTA) updates are crucial as they enable developers to rapidly deploy changes to their applications without requiring users to download new versions from app stores. This capability significantly accelerates the bug-fixing process, allows for swift implementation of minor feature updates, and enhances the overall user experience by ensuring that users always have access to the latest improvements.
150 |
151 | ### For Expo Apps
152 | Expo's eas provides [eas-updates](https://docs.expo.dev/eas-update/introduction/) with `expo-updates` library to update non-native code e.g. JS, styling and images.
153 |
154 | ### For Bare react-native apps.
155 | - [react-native-code-push](https://github.com/microsoft/react-native-code-push) for react-native version 0.76 and below with the new architecture disabled.
156 | - [@code-push-next/react-native-code-push](https://github.com/CodePushNext/react-native-code-push) for react-native 0.77 and above.
157 |
158 | As the appcenter (Microsoft's service hosting code push) is retiring on March 31, 2025 a self hosted code push server or a hosted code push service like [deploypulse](deploypulse.io) can be used for continued support.
159 |
160 | > Starting from react native 0.76, expo is the recommended framework to start a new react-native app and expo-updates is the recommended way for OTAs.
161 |
162 | ## Testing
163 |
164 | ### Unit & Snapshot Testing (Jest)
165 | According to the React-native Doc, React components are responsible for rendering your app, and users will directly interact with their output. Even if your app's business logic has high testing coverage and is correct, without component tests you may still deliver a broken UI to your users.
166 | For testing React components, there are two things you may want to test:
167 |
168 | - `Interaction`: to ensure the component behaves correctly when interacted with by a user (eg. when the user presses a button)
169 | - `Rendering`: to ensure the component render output used by React is correct (eg. the button's appearance and placement in the UI)
170 |
171 |
172 | For example, if you have a button that has an onPress listener, you want to test that the button both appears correctly and that tapping the button is correctly handled by the component.
173 | For the interaction we’re performing component testing to verify the behavior, like pressing events, pressing on the icons in the specific component. And for the rendering, we’re writing a snapshot test to verify the appearance and placement of the component UI.
174 |
175 | ### E2E testing (Detox/Appium)
176 | End-to-end testing is a technique that tests the entire software product from beginning to end to ensure the application flow behaves as expected. It defines the product’s system dependencies and ensures all integrated pieces work together as expected.
177 | The main purpose of End-to-end (E2E) testing is to test from the end user’s experience by simulating the real user scenario and validating the system under test and its components for integration and data integrity.
178 | We recommend using [Detox](https://github.com/wix/Detox) for end to end testing. The most difficult part of automated testing on mobile is the tip of the testing pyramid - E2E. The core problem with E2E tests is flakiness - tests are usually not deterministic. Detox tackles flakiness head on by moving from black box testing to gray box testing.
179 |
--------------------------------------------------------------------------------