User App Architecture
The documentation is compatible with UserApp v1.3.9 and will be updated and added to gradually.
How to run the App
The version of Flutter used for development: 3.10.2
(Make sure that the version installed on your PC is compatible with the one specified in the document)
The version of Dart used for development: 3.0.2
(Make sure that the version installed on your PC is compatible with the one specified in the document)
The project is compatible with the Back End version 1.2.12
If changes were made to the GraphQL scheme on the Back End side, you need:
Delete the scheme (lib/infrastructure/scheme.graphql).
Get a new one (get-graphql-schema ENDPOINT_URL > lib/infrastructure/schema.graphql). WARNING! The link must be in full format. Example: https://${ENDPOINT_URL}/graphql
Run the build_runner (flutter pub run build_runner build).
App Structure
The application is built according to the principles of DDD architecture. We have a good separation into layers which brings beautiful features ease of navigation and testing. The diagram below shows the division into layers and their purpose.
State management in the project is implemented by Riverpod + Flutter Hooks This allows us to easily access data even in such a large project, and with the help of hooks we have almost abandoned the Stateful widget.
Application
At the Application level, we store providers and actions. Since web, mobile and tablet applications are managed in one project, all events are unified and stored in the actions folder. This allows you to minimize efforts to support the project and guarantees the same execution on devices of different types and OS.
Domain
Entities, DTOs, etc. are stored at the Domain level.
Infrastructure
Infrastructure layer includes repository, GraphQL. Repository layer is responsible for implementation for repository interface (* Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the database access code and to minimize scattering and duplication of query code.). The layer is divided into feature oriented services in which interfaces are implemented. GraphQL is a very important part of the project. Since the application interacts with the graphic Back End, the application uses ferry. You can learn more about this library on the official ferry page, but in short, the developer downloads the schema (schema.graphql), creates a request file (*.graphql file) and runs build_runner to generate additional files.
Presentation
This layer is all about Flutter, it contains widgets. Since the project is quite large and contains layouts for different platforms, the following scheme was chosen for convenience:
Below is an example of a widget division structure. Example for authorization: Auth
components (Elements common to all auth, but used only in auth, if they are used elsewhere in the project, should be moved to a higher level)
tablet (UI kit for Tablet layout)
web ((UI kit for Web layout)
mobile (UI kit for mobile layout)
components auth_button.dart element.dart another_element.dart
sign in
components sign_in.dart
sign up
components sign_up.dart
This is how the entire project is distributed. Initially, Presentation is divided into several main modules App, Auth, Exchange and Components (contains elements that are used throughout the project, that is, common to all). Auxiliary elements are also marked in Presentation: constants (contains a list of paths to assets, colors), helpers (various loaders, errors, validation forms, and other auxiliary elements are stored here). And also Controller. The task of the controller is to check whether the user must be authorized, as well as global navigation of the application.
Local Storage
The project uses Hive to store various data on the user's device. Primarily, the local database is used in the project to save critical data (see config.json) Also, the boxes store the date, which can be lost due to the loss of the state (not very pleasant features of Flutter web). The list of all boxes is indicated in the main.dart when registering hive adapters.
Assets
Fonts The application uses local fonts stored in assets/fonts WARNING: When changing fonts, replace/add to pubspec.yaml -> fonts
Icons/Images All graphic assets (*.png, *.jpg, *.svg etc.) are stored in assets/icons. The path to each asset is stored in constant variables in lib/presentation/constants/assets_path.dart WARNING: When removing/adding a new asset, add a new line to assets_path.dart, and do not write the full path to the asset in the widget.
Localization
For localization, the application uses the easy_localization library. Localization json is stored in assets/lang. To add a new locale, you need to create a new json and add the locale to the list of supported locales (lib/presentation/helpers/capitalize.dart -> List supportedLocales).
Config.json
This file is created to set project settings and activate/deactivate certain project modules. Below is a list of variables and an explanation of their use. url - link to the Back End (indicate only in an incomplete format, an incomplete link is sent to the service, because the link format is indicated there) terms_and_conditions_url - Link to Privacy Policy (must be specified in full format. http://link_to_your_policy) ramp_config - enable/disable Ramp support, ramp base config google_auth - enable/disable google authentication, base config header_config - enable/disable different app modules trading_enabled - enable/disable advanced trading module custodial_exchange_enabled - enable/disable Swap module non_custodial_exchange_enabled - enable/disable Non custodial exchange module pro_swap_enabled - enable/disable PRO Swap module non_custodial_wallet_connect - enable/disable WalletConnect in project (Only Web support)
The settings are set by default for development. When publishing to the server, DevOps must specify the value in the config file. Thanks to this solution, you can change the config without rebuilding the application.
Customisation.md
All customisations and changes that differentiate the custom version of the product from the master branch are listed here.
build.yaml
This configuration file so that build_runner knows which generators to run and where to find our GraphQL schema (watch ferry_generator).
analysis_options.yaml
Configuration file for linter. We are constantly working on the quality of the code, so we are constantly adding new rules to make the code more qualitative and productive.
.gitlab-ci.yml
Setting up CI/CD for Gitlab.
Dockerfile
Configuration file for building a docker image. IMPORTANT! If a different version of flutter will be used for development, you need to replace it here as well, so that there are no problems during deployment.
.gitignore
A list of files that should not be stored in the repository.