-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #61 from WomenPlusPlus/docs
change reposotory structure, add documentation and test scenarios
- Loading branch information
Showing
83 changed files
with
227 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,77 @@ | ||
# deploy-impact-23-kpi-1 | ||
# KPI Monitor | ||
|
||
## Objectives: | ||
|
||
The main goal of this application is to provide [Pro Juventute](https://www.projuventute.ch) members an easy and | ||
standardized way to collect and visualize KPIs. | ||
|
||
## Setup: | ||
|
||
### 1. Prerequisites: | ||
|
||
- [Docker](https://www.docker.com/get-started/) | ||
- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) | ||
|
||
### 2. Run locally: | ||
|
||
1. run [local Supabase instance](https://supabase.com/docs/guides/self-hosting/docker) | ||
|
||
```shell | ||
cd ~/dev # or another location where you want to store the Supabase repository | ||
git clone --depth 1 https://github.com/supabase/supabase | ||
cd supabase/docker | ||
cp .env.example .env | ||
docker compose pull | ||
docker compose up -d | ||
grep 'ANON_KEY=' .env | awk -F'=' '{print $2}' # this is the key required to connect the webapp to the backend | ||
``` | ||
|
||
- add a user who will be used for accessing the app: | ||
- go to http://localhost:8000/project/default/auth/users | ||
- click "Add user" > "Create user" | ||
- enter email and password (save them for later use) | ||
|
||
2. run database migrations: | ||
|
||
```shell | ||
docker run --rm --network supabase_default --volume $(pwd)/migrations:/flyway/sql:ro flyway/flyway:latest -url="jdbc:postgresql://supabase-db:5432/postgres" -user="postgres" -password="your-super-secret-a | ||
nd-long-postgres-password" migrate | ||
|
||
``` | ||
|
||
3. run webapp | ||
|
||
```shell | ||
cd KPI-team1-frontend | ||
touch .env.local | ||
echo "VITE_PUBLIC_SUPABASE_URL=http://localhost:8000" | tee -a .env.local | ||
echo "VITE_PUBLIC_SUPABASE_ANON_KEY=<<ANON_KEY_FROM_POINT_1>>" | tee -a .env.local | ||
npm run dev | ||
``` | ||
|
||
- open localhost:3000 in you browser | ||
- you should now be able to log in using the user created previously in the Supabase UI | ||
|
||
### 3. Considerations for production deployment | ||
|
||
The project heavily relies on Supabase. The deployment could be done using a self-hosted Supabase instance, which should | ||
be [secured](https://supabase.com/docs/guides/self-hosting/docker#securing-your-services). An alternative approach is to | ||
create a Supabase account. Current GitHub setup allows applying the database migrations automatically: | ||
- go to https://github.com/WomenPlusPlus/deploy-impact-23-kpi-1/settings/secrets/actions | ||
- setup two secrets: SUPABASE_DB_HOST and SUPABASE_PASS - those are the credentials to the Postgres database | ||
|
||
The frontend application uses [Vite](https://vitejs.dev/guide/build.html) which allows | ||
different [deployment](https://vitejs.dev/guide/static-deploy.html) options out of the box. | ||
|
||
### 4. Tools used: | ||
- [Supabase](https://supabase.com/) | ||
- [React](https://react.dev/) | ||
- [Flyway](https://flywaydb.org/) | ||
- [Flowbite](https://flowbite.com/) | ||
- [Material UI](https://mui.com/) | ||
- [Vite](https://vitejs.dev/) | ||
|
||
### 5. Documentation | ||
- the general architecture of the project is described [here](/docs/arch.md) | ||
- the database schema and instructions for management of the application by the Gatekeeper is [here](/docs/db.md) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<mxfile host="app.diagrams.net" modified="2023-10-29T16:13:20.948Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0" etag="cWDFXSOucl6UHoPB8p54" version="22.0.0" type="device"> | ||
<diagram name="Strona-1" id="oetVzceQHpRXCima8oXP"> | ||
<mxGraphModel dx="1434" dy="782" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> | ||
<root> | ||
<mxCell id="0" /> | ||
<mxCell id="1" parent="0" /> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-1" value="" style="rounded=0;whiteSpace=wrap;html=1;dashed=1;" vertex="1" parent="1"> | ||
<mxGeometry x="400" y="160" width="560" height="340" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-2" value="<font size="1"><b style="font-size: 15px;">Supabase</b></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="640" y="170" width="60" height="30" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-4" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
<mxGeometry x="420" y="270" width="150" height="150" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-5" value="<b>PostgREST Web Server</b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="457.5" y="320" width="75" height="60" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-6" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
<mxGeometry x="600" y="210" width="340" height="270" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-7" value="<b>PostgreSQL database</b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="680" y="220" width="160" height="30" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-8" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
<mxGeometry x="620" y="370" width="300" height="65" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-9" value="Tables" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="730" y="387.5" width="60" height="30" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-10" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
<mxGeometry x="620" y="267.5" width="300" height="75" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-11" value="Database functions and views " style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
<mxGeometry x="680" y="290" width="180" height="30" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-12" value="<b><font style="font-size: 14px;">React web application</font></b>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
<mxGeometry x="110" y="255" width="220" height="180" as="geometry" /> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-13" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="r8XdS0BeGojSjV3rh1AG-12" target="r8XdS0BeGojSjV3rh1AG-4"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="390" y="420" as="sourcePoint" /> | ||
<mxPoint x="440" y="370" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-14" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="r8XdS0BeGojSjV3rh1AG-4" target="r8XdS0BeGojSjV3rh1AG-10"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="390" y="420" as="sourcePoint" /> | ||
<mxPoint x="440" y="370" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
<mxCell id="r8XdS0BeGojSjV3rh1AG-17" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="r8XdS0BeGojSjV3rh1AG-4" target="r8XdS0BeGojSjV3rh1AG-8"> | ||
<mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
<mxPoint x="390" y="420" as="sourcePoint" /> | ||
<mxPoint x="440" y="370" as="targetPoint" /> | ||
</mxGeometry> | ||
</mxCell> | ||
</root> | ||
</mxGraphModel> | ||
</diagram> | ||
</mxfile> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
## Architecture | ||
|
||
This project consists of two major elements: a database schema and API provided by [Supabase](https://supabase.com/) and built on top of a [PostgreSQL](https://www.postgresql.org/) database and [PostgREST server](https://postgrest.org/en/stable/) and a web application built with [React](https://react.dev/). | ||
|
||
![Architecture diagram](arch.png) | ||
(this diagram was created and can be edited with [draw.io](https://app.diagrams.net/) - the xml version is [here](arch.drawio)) | ||
|
||
Authentication is handled by Supabase and is ready for integration with e.g. Azure AD. The data is secured using PostgreSQL [row level security policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). The database migrations are handled using Flyway, they are accessible [here](/migrations). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
## Database schema | ||
|
||
The table containing the KPI values is `public.kpi_values_history`. It is actually a historical log of changes made to a | ||
particular KPI and the latest (currently valid) values can be retrieved using | ||
the `public.kpi_definitions_with_latest_values` view. | ||
|
||
## Manual KPI and user management | ||
|
||
Adding new KPI definition requires adding a new entry in `public.kpi_definition` table. KPI definitions can be used by | ||
multiple circles, thus allowing a particular circle to start recording values for this KPI requires inserting a record | ||
to `public.circle_kpi_definition`. End users can also propose new KPIs from the UI - doing so will create the required entries but in | ||
order to be usable from the UI they need the flag `public.kpi_definition.is_approved` to be set to true. | ||
|
||
Onboarding a new user requires creating his account in the Supabase dashboard and creating an entry in `public.kpi_user` that references the newly created row in `auth.users`. Assigning a user to a circle is done by adding a row in `public.circle_user`. | ||
|
||
![Database schema](schema.png) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,5 @@ dist-ssr | |
*.njsproj | ||
*.sln | ||
*.sw? | ||
|
||
. DS_Store |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
## Test scenarios | ||
|
||
The project was tested using a set of manual tests scenarios which are provided here. The list is non-exhaustive, mostly used for regression testing. Exploratory testing was performed by the team members as well. | ||
|
||
1. **Existing user login** | ||
|
||
*Given* a user exists | ||
*When* I log using Log in with Email/Password on the login page | ||
*Then* I get redirected to the main page | ||
|
||
|
||
2. **Display KPI definitions** | ||
|
||
*Given* a user is logged in | ||
*And* there exist KPI definitions | ||
*When* I type in a KPI definition name fragment in the top search bar | ||
*Then* a list of matching KPI definitions is displayed | ||
|
||
|
||
3. **Display KPI values** | ||
|
||
*Given* a user is logged in and on the 'KPIs' page | ||
*And* there is a KPI definition with values inserted previously | ||
*When* I click on a KPI name | ||
*Then* a modal is opened | ||
*And* the values are displayed in the table "Previous values" | ||
|
||
|
||
4. **Insert new KPI value** | ||
|
||
*Given* a user is logged in and has the KPI modal open | ||
*And* no values exist for the selected KPI | ||
*When* I fill in the date field with a past date | ||
*And* I fill in the value with a valid numeric value | ||
*And* I click "Save" | ||
*Then* the "Previous values" table is reloaded | ||
*And* the new value is displayed for the matching period | ||
|
||
|
||
5. **Update of a KPI value** | ||
|
||
*Given* a user is logged in and has the KPI modal open | ||
*And* a value exists for the selected KPI | ||
*When* I fill in the date field with a date matching the period | ||
*And* I fill in the value with a valid numeric value, different from the existing one | ||
*And* I click "Save" | ||
*Then* the "Previous values" table is reloaded | ||
*And* the new value is displayed for the matching period | ||
|
||
|
||
6. **Switch default circle** | ||
|
||
*Given* a user is logged in | ||
*And* I open the "Settings" screen | ||
*When* I change the default circle | ||
*And* I click "Save" | ||
*Then* I should be redirected to the new default circle page | ||
|
||
|
||
|