Giter Club home page Giter Club logo

hpi-sam / digital-fuesim-manv Goto Github PK

View Code? Open in Web Editor NEW
16.0 16.0 8.0 13.57 MB

A German simulation system for training emergency medical services leadership personnel on how to manage Mass Casualty Incidents.

Home Page: https://fuesim-manv.de/

License: GNU Affero General Public License v3.0

JavaScript 1.08% TypeScript 86.56% HTML 11.88% SCSS 0.09% Shell 0.20% Dockerfile 0.19% Batchfile 0.01%
angular emergency-medical-services germany immerjs mci nodejs openlayers simulation training typescript

digital-fuesim-manv's Issues

Remove client from state on disconnect

The client should be removed from the state after its socket disconnects from the backend. This includes sending the appropriate action to all clients of the exercise.

State management and synchronisation library

Requirements

Synchronisation between server/clients

  • a client can subscribe to a part of the state (example: all vehicles and personnel in viewport1 (= calculated via coordinates))
  • state should be robustly stored (backups) and handled (= database)
  • the state change can be executed without conflicts (e.g. a client changing the position of a vehicle during the state-update)
  • state changes should be validated by a trusted entity
  • a client gets updates to the state in real-time (e.g. "push" like websockets, no polling)

(local) State management client

  • in the client one should be able to subscribe to a part of the state (async observer pattern) and get snapshotted values directly in a synchronous way
  • nicely encapsulated client-side optimistic updates for more responsive ux

both

  • a client can modify the data and send the change to the server/the other clients
  • very good typings and reusability across all codebases (client and server)

TODOs

  • API design websockets
  • senden des States über websocket verbindung
  • backend ordentlich machen (file structure, watch mode)
  • action validation (@ClFeSc)
  • setup test frameworks
    • backend
    • shared
    • frontend unit tests
    • e2e
  • optimistic updates
  • Add actionNr to performAction and getState to fix possible synchronisation issues
  • Resolve all TODOs in the current code base

libraries to investigate

realtime database

client-side state management (stores)

Vulnerabilities in npm packages

We currently have some vulnerabilities in the frontend (run npm audit in the frontend to see them). We should

  • mitigate them by updating the affected packages, and
  • add auditing to the CI

in order to not get any bigger problems from them.

Fix missing dependabot labels

As the title says, dependabot is currently set up to use labels that a) do not exist and b) are invalid label names.

Participant (Client) Overview

There should be an overview for all clients that is only visible to trainer. It should include a list of all clients, their roles and display names. Adding/removing a client to/from the waiting room should also be possible (if the waiting room already exists).

Jest starts backend unexpectedly

Jest starts the backend without us wanting it to. This required us to write some ugly singleton stuff in #47. We should look into preventing Jest from doing such things.

Route for joining an exercise

There should be a route, e.g. GET /join/:exerciseId that automatically (after asking for the display name) joins a client to the exercise provided by :exerciseId.

Immutability types

Introduce the strict use of readonly into our codebase.

  • add Immutable, Mutable helpers and use them for the actions and state types as well as function parameters like in the reducers and the optimisticActionHandler.

  • I'm not sure about their use as interfaces yet, but that's easy to try out.

  • Maybe we could/should also introduce a JSON or PlainObject type (no Map/functions ...).

Setup/improve CI

This is a collection for all issues/TODOs/discussions relating the CI.
After the heavy lifting is done this can be closed and remaining (longer standing/less important) TODOs get their own issue.

TODOs

  1. Reuse build artifacts
  2. Is it even necessary to lint on windows and macos in addition to linux?

Tests fail

The tests still fail. I can only imagine that this is due to invalid caches. Maybe caching shared doesn't work as expected.

Cache eslint on CI

Store the info about processed files in order to only operate on the changed ones. The cache is stored in .eslintcache by default. Enabling this option can dramatically improve ESLint's running time by ensuring that only changed files are linted.
https://eslint.org/docs/user-guide/command-line-interface#--cache

This would probably be done the same as with angular #32 - so the cache is updated after each run.

Map library

Features:

Must-have (creative alternatives as workarounds are ok):

  • zoom in and out (programmatically & mousewheel/pinch to zoom)
  • fixed viewport (maximum zoom, no panning outside the viewport), viewport has { latitude, longitude, width, height }
  • render elements (= vector graphics and raster graphics) on fixed geographical positions on the map
  • eventHandler for click or tap on an element
  • reposition an element on the map (click/tap & drag)
  • resize elements (click on a corner and drag)
  • drag an element on the map (click/tap & drag)
  • context-menus (right-click or long-press)
  • create edges between transferNodes
  • add inputs to these edges (e.g. input field for transferTime, ?viewport? name) - alternative: button that triggers a modal dialog
  • high quality satellite world map (able to zoom very far in)

Should-have:

  • grouping for svg elements (picture of a vehicle + status indicators + "button")

Nice-to-have:

  • calculate the time it takes to travel between two points
  • styling support (css like) for all library specific elements
  • eventHandler for hovering over elements
  • use a png instead of a map (or a custom map)

libraries to investigate (from openstreetmaps)

Ci fails on frontend tests

> [email protected] test
> jest --runInBand --coverage --verbose

PASS Frontend src/app/core/optimistic-action-handler.spec.ts
  OptimisticActionHandler
    ✓ should correctly apply not optimistic proposed actions when response is true (5 ms)
    ✓ should correctly apply not optimistic proposed actions when response is false (2 ms)
    ✓ should correctly perform actions (1 ms)
    ✓ should correctly apply optimistic actions (2 ms)
    ✓ should keep the right order when applying optimistic updates and performed updates (1 ms)
    ✓ should perform already proposed actions after the optimistic update is done (*** ms)

------------------------------|---------|----------|---------|---------|-------------------
File                          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------------------------|---------|----------|---------|---------|-------------------
All files                     |     100 |      100 |     100 |     100 |                   
 optimistic-action-handler.ts |     100 |      100 |     100 |     100 |                   
------------------------------|---------|----------|---------|---------|-------------------

=============================== Coverage summary ===============================
Statements   : 100% ( ***/*** )
Branches     : 100% ( 4/4 )
Functions    : 100% ( 5/5 )
Lines        : 100% ( ***1/***1 )
================================================================================
Test Suites: 1 passed, 1 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        4.71*** s
Ran all test suites.
node:internal/event_target:777
  process.nextTick(() => { throw err; });
                           ^

Error: Unknown worker message type message
This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

    at new NodeError (node:internal/errors:***71:5)
    at Function.fail (node:internal/assert:20:9)
    at Worker.[kOnMessage] (node:internal/worker:***17:12)
    at MessagePort.<anonymous> (node:internal/worker:201:57)
    at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invokeTask (/home/runner/work/digital-fuesim-manv/digital-fuesim-manv/frontend/node_modules/zone.js/bundles/zone-testing-bundle.umd.js:441:***5)
    at Zone.Object.<anonymous>.Zone.runTask (/home/runner/work/digital-fuesim-manv/digital-fuesim-manv/frontend/node_modules/zone.js/bundles/zone-testing-bundle.umd.js:212:51)
    at ZoneTask.Object.<anonymous>.ZoneTask.invokeTask [as invoke] (/home/runner/work/digital-fuesim-manv/digital-fuesim-manv/frontend/node_modules/zone.js/bundles/zone-testing-bundle.umd.js:52***:***8)
    at invokeTask (/home/runner/work/digital-fuesim-manv/digital-fuesim-manv/frontend/node_modules/zone.js/bundles/zone-testing-bundle.umd.js:166***:18)
    at MessagePort.globalZoneAwareCallback (/home/runner/work/digital-fuesim-manv/digital-fuesim-manv/frontend/node_modules/zone.js/bundles/zone-testing-bundle.umd.js:1689:21)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:562:20) {
  code: 'ERR_INTERNAL_ASSERTION'
}

Use Jest Monorepo features

As introduced in #47 the backend uses jest tests that currently fail due to our usage of ES modules for the shared library. We therefore had to set a node flag when running backend tests that resulted in the frontend tests failing. We then split up the test running into three separate calls to jest. These should be reunited, at least to allow a global coverage once again, and also better readability of the test output.

Stress test

To validate our assumptions about the performance of our system we should try to test it in a real scenario as fast as possible. I propose shortly after the end of the first milestone.

  • on an experimental branch: add a button that proposes every second a (real) action after one joined a session
  • make a button that adds multiple patients instead of just one
  • build and host a webserver with our application build from this branch
  • an automated client joins the exercise and proposes an action every second
  • a real client joins the exercise and move stuff manually around (with optimistic updates enabled) - he can check the latency by seeing opening the website on another tab (that doesn't propose actions but only display the current state on the map).
  • figure out the upper limits of the server and clients

Parameters

  • number of real clients
  • number of automated clients
  • number of different devices
  • number of different networks (what about VPNs?)
  • time between sending an action and receiving the proposal
  • subjective smoothness
  • any problems?

Add documentation about dependencies and devDependencies

The differentiation between devDependencies and normal dependencies is actually only relevant for libraries.
Non-library packages (like ours) can make arbitrary rules which go where.
I personally like to differentiate between runtime dependencies (dependencies) and those necessary for building, testing, etc. This convention is also recommended by angular as far as I know.
This makes it easier to spot whether e.g. a DOS vulnerability is affecting your runtime or only a package used for building/testing.

Originally posted by @Dassderdie in #47 (comment)

Run e2e tests in CI

We would have to:

  1. build the whole application
  2. start the frontend and backend
  3. run cypress
  4. after cypress is finished we have to kill the frontend and backend

Different ids for exercises

Exercises should have two ids, one for participants, one for trainer. These ids should be used to determine whether a joining client should be a participant or a trainer. Also, only the trainer id should be deletable by DELETE /api/exercise/:exerciseId.

Cannot find module `digital-fuesim-manv-shared` or its corresponding type declarations.

I followed the steps outlined in README.md to setup the project on a clean system.

When I want to run the Start all task or run some tests I get running tests, the shared folders compiles without problems, but backend and frontend each show a buch of errors of the following kind:

Error: src/app/<SOME_CODE_FILE>.ts:<XX>:<YY> - error TS2307: 
Cannot find module 'digital-fuesim-manv-shared' or its corresponding type declarations.

Trying to delete all local node_modules and installing again did not help.

Add client to state

We should add the client to the state of the exercise upon joining. This includes informing the other clients about the change, i.e. emit a performAction.

Add waiting room

A waiting room should be available where all joining participants first get to after joining. Trainer should not go there by default. The waiting room should contain a text informing the participants about the fact where they are.

Possible synchronisation issue when retrieving the state

  • Add actionNr to performAction and getState to fix possible synchronisation issues

@Dassderdie
I just noticed a problem with our current API design:
The current idea is to first get the state and then all apply all the actions that we receive via "performAction". But there is no way of knowing which state we get and which actions were already applied.

I would therefore propose the following:

getState and performAction have a timestamp (or some other kind of number that gives them an order) in the answer from the backend.
The frontend

subscribes to performAction and saves the actions it receives
gets the State
Forgets all actions whose timestamp is before the timestamp of the state
Applies all the other actions in order
We would have to check whether a timestamp (Date.now()) is somehow security relevant...

@ClFeSc

I think we could just count the actions and return the action number of the last applied action with the state.

Look here for the original discussion

No notifications of vulnerabilities in dev

As dependabot only looks at the main branch its alerts are mostly outdated as we probably already have fixed some of those problems in dev, I'd suggest, additionally to Dependabot, to include auditing in the CI, as an ok-to-fail-job.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.