Table of Contents
- Python 3.10 (or later)
- Git
- Pip
- Git clone the repository to your local machine.
- Navigate to the project folder in your terminal.
- Create a virtual environmnent and activate it:
python3 -m venv .venv
source .venv/bin/activate
- Install requirements:
pip install -r requirements/requirements.txt
- Add .env file in root with the following content:
PRODUCTION_ENV=False
# --- The production-database, used when 'PRODUCTION_ENV=True' ---
DB_ENGINE=django.db.backends.postgresql
# Name of PostgreSQL database, e.g. db_name
DB_NAME=db_name
# Name of user, e.g. john
DB_USER=john
# Password of user, e.g. johnpassword
DB_PASSWORD=johnpassword
# PostgreSQL database host, e.g. localhost (if locally hosted)
DB_HOST=localhost
# PostgreSQL database port, e.g. 5432
DB_PORT=5432
# --- The test-database, used when 'PRODUCTION_ENV=False' ---
DB_TEST_ENGINE=django.db.backends.sqlite3
DB_TEST_NAME=BASE_DIR / 'db.sqlite3'
- Setup local database:
python3 src/manage.py migrate
- Run tests to make sure it works correctly (no errors should occur):
python3 src/manage.py test api
- Create a super user, and make sure to follow the instructions in the command line (the email is not required):
python3 src/manage.py createsuperuser
- Git clone the repository to your local machine.
- Navigate to the project folder in your Windows terminal.
- Create a virtual environmnent:
python -m venv .venv
- If needed, add permissions to load scripts in PowerShell (tested on Windows 11):
Set-ExecutionPolicy -ExecutionPolicy AllSigned
- Activate the environment:
.venv\Scripts\activate
- Install requirements:
pip install -r requirements\requirements.txt
- Add .env file in root with the following content:
PRODUCTION_ENV=False
# --- The production-database, used when 'PRODUCTION_ENV=True' ---
DB_ENGINE=django.db.backends.postgresql
# Name of PostgreSQL database, e.g. db_name
DB_NAME=db_name
# Name of user, e.g. john
DB_USER=john
# Password of user, e.g. johnpassword
DB_PASSWORD=johnpassword
# PostgreSQL database host, e.g. localhost (if locally hosted)
DB_HOST=localhost
# PostgreSQL database port, e.g. 5432
DB_PORT=5432
# --- The test-database, used when 'PRODUCTION_ENV=False' ---
DB_TEST_ENGINE=django.db.backends.sqlite3
DB_TEST_NAME=BASE_DIR / 'db.sqlite3'
- Setup local database:
python src\manage.py migrate
- Run tests to make sure it works correctly (no errors should occur):
python src\manage.py test api
- Create a super user, and make sure to follow the instructions in the command line (the email is not required):
python src\manage.py createsuperuser
- If PRODUCT_ENV field in .env file is set to true you need to install PostgreSQL and create a database with it (see Django documentation regarding PostgreSQL for more information).
Note: This additionally requires that Node.js and npm are installed.
- Pull the main branch of both repositories.
- Build frontend:
npm run build
- Delete everything in
backend/src/static/
- Move/Copy the files from
frontend/frontend-friends/build
intobackend/src/static/
- Run the server:
python3 src/manage.py runserver
Logs in the user with the given credentials. The password field is not always required, since some users may not have a password. An empty password field will be treaded the same as if no password field was given.
Request:
POST /api/login/
{
"username": "<username>",
"password": "<password>"
}
Success response:
Status: 204 (No Content)
Set-Cookie: sessionid=...
The username was valid, but a password is also required and wasn't provided in the request (response):
Status: 403 (Forbidden)
Wrong username or password (response):
Status: 401 (Unauthorized)
Logs out the currently logged in user.
Request:
POST /api/logout/
Cookie: sessionid=...
Success response:
Status: 204 (No Content)
Checks if the user is logged in or not.
Request:
GET /api/check/
Cookie: sessionid=...
Response if logged in:
Status: 204 (No Content)
Response if not logged in:
Status: 401 (Unauthorized)
Returns a list with all cases sorted chronologically (latest at top) that match the given query parameters. A request without parameters returns the latest 100 cases.
Query parameters:
id: int
time-start: DateTime
time-end: DateTime
case-id: int
(case id from their system)category-id: int
medium: string
per-page: int (default 100, set to 0 to disable pages)
page: int (default 1)
Request:
GET /api/case
GET /api/case?<query>
Example:
GET /api/case?category-id=2&medium=phone&per-page=20&page=3
Success response:
Status: 200 (OK)
{
"result_count": 1,
"has_more": false,
"cases": [
{
"id": 1,
"case_id": 1,
"notes": "Example notes 1",
"medium": "phone",
"customer_time": "PdDThhHmmMssS",
"additional_time": "PdDThhHmmMssS",
"form_fill_time": "PdDThhHmmMssS",
"created_at": "yyyy-mm-ddThh:mm:ssZ",
"updated_at": "yyyy-mm-ddThh:mm:ssZ",
"category_id": 1,
"category_name": "Example category 1",
"parent_category_name": "Example parent category 1",
},
]
}
Creates a new case. All fields are optional and will be set to empty values if not specified.
Request:
POST /api/case/
{
"notes": "Example notes 1",
"medium": "phone",
"customer_time": 0,
"additional_time": 0,
"form_fill_time": 0,
"category_id": 1,
}
Success response:
Status: 201 (Created)
Updates the case with the given id. Fields that are not specified will not be updated. If a field is specified but with an empty value it will be set to an empty value.
Request:
PATCH /api/case/<id>/
{
"notes": "Example notes 1",
"medium": "phone",
"customer_time": 0,
"additional_time": 0,
"form_fill_time": 0,
"category_id": 1,
}
Success response:
Status: 204 (No Content)
Deletes the case with the given id.
Request:
DELETE /api/case/<id>/
Success response:
Status: 204 (No Content)
Returns all categories.
Request:
GET /api/case/categories/
Success response:
Status: 200 (OK)
[
{
"id": 1,
"name": "Konto",
"subcategories": [
{"id": 2, "name": "Skapa nytt konto"},
{"id": 3, "name": "Ta bort konto"}
]
},
{
"id": 4,
"name": "Annat",
"subcategories": []
}
]
Returns the number of cases for each medium in the given time period.
Query parameters:
start-time: datetime
end-time: datetime
Request:
GET /api/stats/medium?<query>
Example:
GET /api/stats/medium?start-time=2023-01-01T00:00:00%2B00:00&end-time=2023-12-31T23:59:59%2B00:00
Success response:
Status: 200 (OK)
{
"phone": int
"email": int
}
Returns data about each category in the given time period.
Query parameters:
start-time: datetime
end-time: datetime
Request:
GET /api/stats/category?<query>
Success response:
Status: 200 (OK)
[
{
"category_id": int,
"category_name": string,
"count": int,
"customer_time": int (seconds),
"additional_time": int (seconds),
"form_fill_time": int (seconds),
"subcategories": [
{
"category_id": int,
"category_name": string,
"count": int,
"customer_time": int (seconds),
"additional_time": int (seconds),
"form_fill_time": int (seconds)
},
]
},
]
Returns a list with the number of cases for each interval in the given time period. Positive values for delta
will result in intervals that begin at the given start-time
. Negative values for delta
will result in intervals that end at the given start-time
.
Query parameters:
start-time: DateTime
delta: int (seconds)
intervals: int (number of intervals to include)
Request:
GET /api/stats/periods?<query>
Example:
Returns the number of cases for each hour on january 1 2023:
GET /api/stats/periods?start-time=2023-01-01T00:00:00%2B00:00&delta=3600&intervals=24
Success response:
Status: 200 (OK)
[
{
"start": datetime,
"end": datetime,
"count": int
},
...
]