Greenie.app is an online "Greenie Board" for carrier-based virtual squadrons, especially squadrons that operate in Digital Combat Simulator: World. Squadrons can add passes manually or by uploading dcs.log files, and track the performance of their pilots.
Greenie.app consists of an API back-end, written in Ruby on Rails (this repository) and a tightly-coupled front-end, written in TypeScript and Vue.js. Along with these two processes, the website also uses a Sidekiq process to execute background tasks, and a separate instance of the Rails server to send and receive data via WebSockets (Action Cable).
For more general information, see the backend repository. This README covers the frontend repository only.
Greenie.app requires a modern version of Node.js and Yarn. Run yarn install
to
install all NPM dependencies.
Run the local development server by running yarn serve
, and build the
production assets by running yarn build
. See the backend repository to learn
how to boot the entire stack and test the whole website.
Comprehensive documentation can be generated by running yarn docs:generate
.
HTML documentation is generated into the doc/
directory.
Unit tests are written in Mocha using Chai, and can be run with
yarn test:unit
. Unit tests are not comprehensive; they are only written for
methods and classes with notably complex logic.
End-to-end testing is powered by Cypress. Run yarn test:e2e
to launch the
Cypress test framework. The backend and many other processes will have to also
be running for end-to-end tests to work. See the Backend repository for more
information. End-to-end tests do not function in isolation; each test depends
on the successful completion of every test before it. They should only be run
as an entire suite, in order.
This application is deployed using Fly.io. The deploy.yml
GitHub Actions
workflow runs automatically after CI completes.
The frontend website is built using TypeScript and Vue.js. The root view is
{Layout}, which uses Vue-Router to render the appropriate subviews. Shared
functionality is kept under components/
and individual views under views/
.
Components include {MustBeAuthenticated} and {MustBeUnauthenticated}, which act
as guards; {Error} and {Spinner} which are full-page views for global error and
loading states; {FieldWithErrors} and {Datetime} which are used to render forms;
and other utility views.
String assets are managed by Vue-I18n and localized (to English only, currently).
State information is managed by Vuex. The main Vuex store is split into a number
of different modules. The squadron
module manages state for the squadron whose
greenie board the logged-in user is viewing; the mySquadron
module manages
state for the squadron the logged-in user is logged in as (if any). The other
modules are more or less self-explanatory. The coding.ts
file contains bridges
between the JSON representation of these modules sent by the backend, and the
TypeScript classes used by the frontend.