Die Schnittstelle von QuickPool (QP) basiert komplett auf REST. Zur Kommunikation mit dem Server muss stets ein Token (JWT) mitgeschickt werden, welche den Benutzer eindeutig identifiziert. Es bestehen keine App-Tokens, der Login muss mit den Credentials von existierenden und freigeschalteten Benutzern passieren. Wie bei JWT üblich, wird ebenfalls einmalig ein Reset-Token mitgeliefert, welches nach Ablauf der Gültigkeit des Tokens verwendet wird um ein neues Tokenpaar zu erhalten.
Für die Production Umgebung von QuickPool wird stets die folgende Base URL vorgehängt: https://api.quickpool.ch/api/v1
Fast alle Models haben zumindest die folgenden REST Endpunkte:
Methode | Pfad | Beschreibung |
---|---|---|
GET | /<model> | Gibt einen Index zurück, welcher gefiltert, sortiert, eingegrenzt und paginated ist |
GET | /<model>/:id | Gibt genau einen Eintrag zurück, sofern man berechtigt ist |
POST | /<model> | Erstellt einen neuen Eintrag, sofern die Parameter korrekt sind und gibt den kompletten Datensatz zurück |
PUT | /<model>/:id | Führt einen Update auf den Eintrag durch, sofern dieser existiert. Nur Felder, welche übergeben wurden, werden geändert. Gibt den kompletten, aktualisierten Datensatz zurück |
DELETE | /<model>/:id | Führt einen Softdelete (inactive -> true) aus, sofern der Datensatz existiert. Mehrere Deletes auf dem gleichen Datensatz haben keinen negativen Effekt. Gibt den kompletten Datensatz zurück |
Wie oben erwähnt wird die Sichtbarkeit durch das Token ermittelt und auch parameterlose Aufrufe auf den Index werden Informationen zurückgeben.
Jede Index Abfrage kann mit einem optionalen Query-Parameter q
versehen werden, welche es erlaubt auf fast allen Feldern zu filtern.
Hier ein Beispiel wie man Schichten filtern kann:
{
"clients": { "id": [1] },
"status": ["unassigned", "assigned"],
"tags": { "id": [319] },
"people": { "id": [5] },
"inactive": false
}
Zusätzlich können folgende Query Parameter mitgegeben werden
Parameter | Beispiel | Funktion |
---|---|---|
sort | {"start_date":"asc"} | Gibt an, nach welcher Spalte sortiert werden soll |
limit | 10 | Gibt an, wie viele Einträge pro Seite angezeigt werden sollen |
page | 1 | Gibt an, welche Seite geladen wird, wobei das Limit berücksichtigt wird |
Bei Schichten und Verfügbarkeiten kann zusätzlich zu den anderen Queries noch ein Zeitraum angegeben werden, welcher ebenfalls berücksichtigt wird. Zu beachten ist, dass die Zeiten in UTC übergeben werden.
Parameter | Beispiel |
---|---|
from | 2022-10-16T22:00:00.000Z |
until | 2022-10-23T21:59:59.999Z |
Das Matching funktioniert so, dass alle Einträge geliefert werden, welche auch nur teilweise vom Zeitraum überlappt werden. Das Startdatum muss ausserdem vor dem Enddatum liegen.
Um Informationen, über angehängte Entitäten zu erhalten, kann ein Join ausgeführt werden. Das wird die entsprechende Entität in der Antwort
anhängen.
In der Regel ist es so, dass jedes Feld, welches mit _id
aufhört (z.B. client_id
) verwendet werden kann um zu joinen. Dabei muss der
Teil OHNE _id
in das joins
Array mitgegeben und als Queryparameter angehängt werden.
Beispiel:
joins: ["client","people","tags","location","template", "fileupload"]
Sofern eine Entität mit anderen angereichert werden kann, müssen diese nicht nur über ID mitgegeben werden. Es wird ein Objekt erwartet, welches im Optimalfall das ganze Objekt, welches angehängt werden soll enthaltet, oder zumindest die ID drin beinhaltet. Das Object muss JSON encoded sein.
{
...
tags: "[{\"id\":17,\"name\":\"Design\",\"description\":null,\"inactive\":false,\"account_id\":1,\"created_at\":\"2020-11-11T13:21:54.985Z\",\"updated_at\":\"2021-01-02T20:42:22.296Z\",\"color\":\"#d55858\",\"icon\":\"gamepad\",\"settings\":{\"show_on_scheduler\":false},\"minutes_per_week\":null},{\"id\":319,\"name\":\"40%\",\"description\":\"\",\"inactive\":false,\"account_id\":1,\"created_at\":\"2022-09-07T11:54:30.148Z\",\"updated_at\":\"2022-09-07T11:54:38.701Z\",\"color\":\"#e62565\",\"icon\":\"percent\",\"settings\":{\"show_on_scheduler\":false},\"minutes_per_week\":800},{\"id\":15,\"name\":\"FT\",\"description\":\"\",\"inactive\":false,\"account_id\":1,\"created_at\":\"2020-10-20T17:19:22.514Z\",\"updated_at\":\"2021-01-02T20:38:34.620Z\",\"color\":\"#3de1a2\",\"icon\":\"linux\",\"settings\":{\"show_on_scheduler\":false},\"minutes_per_week\":null}]"
...
}
Wie oben erwähnt funktioniert das Login mit Username und Passwort. Daraufhin werden die wichtigen Informationen, wie Tokenpaar und genauere Angaben zur Person zurückgeschickt.
curl -XPOST 'https://api.quickpool.ch/api/v1/auth/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=<[email protected]>' \
--data-urlencode 'password=<yourPW>'
Das Resultat wird in etwa so aussehen:
{
"id": 1,
"email": "<[email protected]",
"role": "admin",
"avatar": "",
"first_name": "Alex",
"last_name": "Mihov",
"client_name": null,
"color": "#FF0000",
"token": "eyJhbGciOiJIUzI1NiJ9.asdas......",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.e234....",
"account": {
"id": 1,
"name": "Quickshift",
"logo": "https://api.quickpool.ch/api/v1/s3/show/quickshift/public/logos/c040c358-c838-4443-ae40-a6fcd9b44c0b-Ardeo-Logo-Symbol.png",
"email": "[email protected]",
"contact_name": "Ardeo GmbH",
"phone": "079 612 02 84",
"channel": "aaaaaaaa-bbbb-bbbb-cccc-f7550b7a1105"
},
"person_id": 1,
"client_id": null,
"config": {
"i18n": {
"de": {
"app": {},
"web": {},
"general": "{}"
},
"en": {
"app": {},
"web": {},
"general": {}
}
},
"features": {
"tags": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 7
}
},
"user": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 0
}
},
"groups": {
"app": {},
"web": {},
"general": {
"enabled": false,
"navigation": "hidden",
"navigation_index": 8
}
},
"people": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 4
}
},
"shifts": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 2
}
},
"account": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 10
}
},
"clients": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 5
}
},
"reports": {
"app": {},
"web": {},
"general": {
"enabled": false,
"navigation": "hidden",
"navigation_index": 2
}
},
"projects": {
"app": {},
"web": {},
"general": {
"enabled": false,
"navigation": "hidden",
"navigation_index": 6
}
},
"skribble": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "hidden",
"navigation_index": 0
}
},
"dashboard": {
"app": {},
"web": {},
"general": {
"enabled": true,
"first_view": true,
"navigation": "visible",
"navigation_index": 1
}
},
"documents": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 9
}
},
"templates": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 3
}
},
"availabilities": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 6
}
},
"export_outlook": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "hidden",
"navigation_index": 20
}
},
"import_outlook": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "hidden",
"navigation_index": 20
}
},
"weekly-templates": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "visible",
"navigation_index": 3
}
},
"digital_signature": {
"app": {},
"web": {},
"general": {
"enabled": true,
"navigation": "hidden",
"navigation_index": 20
}
},
"automatic_assignment": {
"app": {},
"web": {},
"general": {
"config": {
"max_computation_seconds": 120
},
"enabled": true,
"navigation": "hidden",
"navigation_index": 20
}
}
},
"public_config": {
"default_language": "de",
"availability_mode": "presence",
"worktime_signature": "optional",
"automatically_confirm_shifts": false
}
}
}
Sobald das Token abgelaufen ist (default ist 60min) wird die Schnittstelle einen Error werfen, dass man nicht authentifiziert werden kann.
In diesem Fall muss das Token erneuert werden. Das passiert einmal mit dem refresh_token
welches man beim Login erhaltet.
Dieses wird an den Endpunkt geschickt als payload refresh_token
.
Die Antwort vom Server wird dann wieder ein Tokenpaar enthalten, welches genau gleich wie das ursprüngliche verwendet werden kann.
Das Refresh-Token ist einen Monat gültig.
Eine Person beinhaltet die wichtigen Infos von Personen, welche in QP verwendet werden. Die E-Mail-Adresse der Person ist meistens dieselbe wie diejenige des Users, welcher stets der Person angeknüpft ist, das ist allerdings nicht ein muss. Personen werden erstellt, damit man die Mitarbeiter der Firma darstellen kann. Dabei wird für jeden Mitarbeiter, egal ob Administrator oder nicht, ein neuer Eintrag erstellt.
{
"id": 1,
"avatar": "",
"first_name": "Martin",
"last_name": "Pfister",
"email": "[email protected]",
"date_of_birth": "1941-01-17",
"gender": "male",
"mobile": "+41 79 111 22 33",
"street_name": "Zürcherstrasse",
"house_number": "87",
"address_details": "",
"postal_code": "8000",
"city": "Zürich",
"country": "CH",
"nationality": "CH",
"residence_permit": null,
"type_of_salary": "hourly",
"hourly_rate": 1000.0,
"salary": null,
"color": "#FF0000",
"admin": false,
"IBAN": "GB33BUKB20201555555555",
"account_id": 1,
"user_id": 1,
"notes": "Martin is a great employee",
"created_at": "2020-08-31T12:16:59.016Z",
"updated_at": "2022-09-16T10:34:10.842Z",
"inactive": false,
"marital_status": "single",
"nr_of_kids": 0,
"religion": "atheist",
"entrance_date": "2020-08-07",
"ahv_number": "756.1234.5678.90",
"bank_name": "Zürcher Kantonal Bank",
"budget_id": 1,
"custom_values": {
"ma_kategorie": "Höhere Berufsbildung (HF)"
},
"short_name": "Tinu"
}
Den Personen kann folgendes angehängt werden:
Model | Beschreibung |
---|---|
Tag | Tags werden verwendet um Qualifikationen und ähnliches anzuhängen. Diese werden ebenfalls an Kunden und Schichten angehängt damit das Matching stattfinden kann. |
Client | Clients stellen die Kunden oder generell die Arbeitsbereiche dar, an denen Schichten zugeteilt werden können. Diese werden ebenfalls für das Matching verwendet |
Budget | Budgets stellen die Arbeitszeit pro Monat/Woche/Tag welche der Person zugeteilt werden soll dar |
Fileuploads | Es können mehrere Files einer Person angehängt werden, welche einerseits von QP verwendet werden (Anzeigebild, Vertrag etc.) oder nur zur Datenablage dienen |
Ein Client stellt einen Arbeitsort dar. Es kann eine Privatperson, Firma, eine Abteilung oder eine Maschine im Betrieb sein. Ein Client kann mehrere Standorte haben. Diese werden unten aufgeführt. Jeder Einsatz braucht einen Client und eine Standort, ohne diese kann die Schicht nicht erstellt werden.
{
"id": 1,
"name": "Medical Carers",
"email": "[email protected]",
"logo": "https://i2.wp.com/files.123freevectors.com/wp-content/uploads/new/signs-symbols/021_medical-symbol-free-vector-l.png?w=800&q=95",
"vat_id": "CHE-123.456.789",
"color": "#673fb4",
"notes": "Medical Care Notes",
"inactive": false,
"account_id": 1,
"user_id": 7,
"created_at": "2020-08-31T12:16:59.243Z",
"updated_at": "2022-05-25T21:16:00.814Z",
"properties": {
"bonus_night": "20%",
"bonus_expenses": "KM-Entschädigung von 0.70 CHF/km",
"bonus_sunday_holiday": "",
"bonus_weekend_holiday": ""
},
"short_name": "MC"
}
Den Clients kann folgendes angehängt werden:
Model | Beschreibung |
---|---|
Tag | Tags werden verwendet um Qualifikationen und ähnliches anzuhängen. Diese werden ebenfalls an Personen und Schichten angehängt damit das Matching stattfinden kann. |
People | People stellen Personen dar, denen Schichten zugeteilt werden können. Diese werden ebenfalls für das Matching verwendet |
Fileuploads | Es können mehrere Files einer Person angehängt werden, welche einerseits von QP verwendet werden (Anzeigebild, Vertrag etc.) oder nur zur Datenablage dienen |
Locations | Ein Client kann mehrere Standorte haben, dabei kann einer als Hauptstandort ausgewiesen werden (siehe unten) |
Eine Schicht (oft auch Einsatz) bringt alle vorherig erfassten Stammdaten zusammen und stellt eine Arbeitsperiode dar. Schichten können durch verschiedene Stati progressieren:
Status | Beschreibung |
---|---|
unassigned | Die Schicht hat keine zugewiesene Person, oder die zugewiesene Person wurde wieder entfernt |
assigned | Die Schicht ist zugewiesen aber noch nicht von der Person bestätigt |
confirmed | Die Schicht wurde von der Person bestätigt. Accounts können so eingestellt werden, dass die Schichten automatisch bestätigt werden. |
rejected | Die Schicht wurde von der Person in der App abgelehnt und muss neu zugewiesen werden. |
submitted | Die Schicht wurde von der Person abgearbeitet und zur Kontrolle markiert |
approved | Die Schicht wurde vom Admin bearbeitet und wird so gespeichert. Sie kann per GUI nicht mehr verändert werden. |
declined | Die Schicht wurde vom Admin abgelehnt |
{
"id": 325,
"start_date": "2021-01-13T20:00:00.000Z",
"end_date": "2021-01-14T06:00:00.000Z",
"notes": "",
"inactive": false,
"nr_of_required_people": 1,
"file_url": null,
"public": false,
"status": "open",
"account_id": 3,
"client_id": 9,
"location_id": 20,
"user_id": 55,
"created_at": "2021-01-13T13:58:00.457Z",
"updated_at": "2021-06-16T10:15:21.399Z",
"name": "Morgenschicht",
"is_template": true,
"properties": null,
"silent": false,
"weekly_template_id": null,
"project_id": null,
"fileupload_id": null,
"custom_values": {
},
"visible": "visible",
"people": [
{
"id": 53,
"avatar": "https://api.quickpool.ch/api/v1/s3/show/powerpeople/public/avatars/171be919-3bdd-4d10-a1ea-bf20e02e2249-Rectangle-Copy-3.png",
"first_name": "Olivia",
"last_name": "Brown",
"email": "[email protected]",
"date_of_birth": null,
"gender": "female",
"mobile": "+41 79 123 45 72",
"street_name": null,
"house_number": null,
"address_details": null,
"postal_code": null,
"city": null,
"country": null,
"nationality": null,
"residence_permit": null,
"type_of_salary": null,
"hourly_rate": null,
"salary": null,
"color": "#ff2eee",
"admin": false,
"IBAN": null,
"account_id": 3,
"user_id": 60,
"notes": "",
"created_at": "2020-11-26T13:08:08.632Z",
"updated_at": "2021-07-28T14:16:15.446Z",
"inactive": false,
"marital_status": null,
"nr_of_kids": null,
"religion": null,
"entrance_date": null,
"ahv_number": null,
"bank_name": null,
"budget_id": null,
"custom_values": {
},
"short_name": ""
}
],
"client": {
"id": 9,
"name": "Kunde C",
"email": "[email protected]",
"logo": "https://api.quickpool.ch/api/v1/s3/show/powerpeople/public/logos/99c48df0-88f6-4fee-9d12-cc507af26a2b-customer_c.png",
"vat_id": "",
"color": "#ed0c72",
"notes": "",
"inactive": false,
"account_id": 3,
"user_id": 66,
"created_at": "2020-11-26T13:23:29.149Z",
"updated_at": "2021-09-07T14:00:30.422Z",
"properties": {
"bonus_night": "",
"bonus_expenses": "",
"bonus_sunday_holiday": "",
"bonus_weekend_holiday": ""
},
"short_name": ""
},
"tags": []
}