6.0 KiB
Codebase Strucuture and Guidelines
Starting the app
The app is bundled and run in a Nix environment. Information regarding how to run it locally can be found here.
Business Logic Modules
Each business logic module is managed in a module directory.
Only the core and db namespace of a module can be required outside of the module directory. Other namespaces must never be required outside of the module directory
There is no rigid structure on how to organize code inside modules outside of core and db namespaces
- events.cljs
- subs.cljs
- notifications
- core.cljs
- init
- core.cljs
- accounts
- core.cljs
- db.cljs
- node
- core.cljs
- db.cljs
- config.cljs
- ui
- screens
- login
- views.cljs
Rationale and how to get there:
Currently a lot of business logic is lost in utils and screens namespaces and should be moved to dedicated top level directories. This should make core logic of the app more accessible and organized
core.cljs
Core namespace must only contain functions that can be called outside of the module (i.e. in events or other modules):
-
fx producing functions called by events and other modules
(def get-current-account module.db/get-current-account) (defn set-current-account [{db :db :as cofx}] {:db (module.db/set-current-account db)})
db.cljs
- must contain specs for the app-db subpart the module modifies
- must contain getter and setter functions used by fx producing functions and subscriptions
- db logic called by other modules
Rationale:
These guidelines make db.cljs namespaces the place to go when making changes to the db layout and minimize breaking changes when adding/refactoring features
re-frame
Subscriptions
- all subscriptions must be defined in the single
status-im.subs
namespace - subscriptions must subscribe only on other subscriptions, and never on app-db itself
reg-root-key-sub
should be used for the root keys subscriptions
Events
-
all events must be defined in the single
status-im.events
namespace which can be considered as an index of everything going on in the app -
events must always be declared with
register-handler-fx
, noregister-handler-db
-
events must never use the
trim-v
interceptor -
events must only contain a function call defined in a module
(handlers/register-handler-fx :notifications/handle-push-notification-open (fn [cofx [_ event]] (notifications/handle-push-notification-open event cofx)))
-
events must use synthetic namespaces:
:module.ui/
for user triggered events:module.callback/
for callback events, which are events bringing back the result of an fx to the event loop, the name of the event should end with-success
or-error
most of the time. Other possibilities can be-granted
,-denied
for instance.:module/
for internal events, examples are time based events marked-timed-out
, external changes marked-changed
or reception of external events marked-received
.
Testing flow
- All PRs automatically go to "REVIEW" column on Pipeline for QA project on Github. This is our main board for QA / devs interaction
- After the PR gets at least 1 approval, it should be moved to "E2E Tests" column. Some PRs may need approvals from more than one person.
- Critical path tests are automatically run for all PRs in "E2E Tests" column.
- If E2E tests pass:
-
If PR doesn't need manual QA (it is small change or change doesn't relate to app) - after passing e2e tests it can be merged (don't use the Github UI to merge, check section on merging PRs).
-
If manual QA needed - add label 'request manual qa'. The QA team will process it (make sure the summary and test instructions are clear). QA team will review results and test PR on different platforms and assign one of the three labels:
- No issues - label 'TESTED-OK' and then you can merge it.
- If issues - label 'TESTED-ISSUES' and comment from QA with bugs.
- After fix and/or discussion the process is repeated.
-
If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
-
Enabling debug logs
Calls to log/debug
will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
Translations
The app relies on system locale to select a language from the list of supported languages. It falls back to English in cash the system locale is not supported.
We use Lokalise App to manage translations. In case you need to add/remove a key to translations, you only need to change en.json
. Missing keys fallback to en.json
. The actual translations will be added by Lokalise.
re-frisk
re-frisk is a state visualization tool written by our very own Andrey (@flexsurfer). To start re-frisk, execute the following command:
$ yarn shadow-cljs run re-frisk-remote.core/start
or you can also use make:
$ make run-re-frisk
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
Merging approved PRs
We don't Github's UI to merge. Instead ./scripts/merge-pr.sh
is used to sign and merge PR to develop
. You first need to enable GPG signing on you commits.
Once your commits are verfied and PR approved, you can run the script like so:
$ git checkout develop
$ git fetch
$ git reset --hard origin/develop
$ ./scripts/merge-pr.sh 11370
Replace 11370 with your PR id.
Release process
TODO(shivekkhurana): Compile release notes