# Implementační dokumentace modulu *shared-bikes (Sdílená kola)*

## Záměr

Modul slouží k ukládání a poskytování informací o sdílených kolech v Praze.

**Dostupní poskytovatelé**:
- Rekola
- Next Bike
- HoppyGo
- Car4Way (Český carsharing)
- AJO (Český carsharing)
- Anytime (Český carsharing)
- Autonapůl (Český carsharing)

**Výstupní formáty**:
- GeoJSON
- GBFS


## Vstupní data

### Data nám jsou posílána

Nejsou.


### Data aktivně stahujeme

Data stahujeme pravidelně od HoppyGo, Rekola, z Next Bike api a od Asociace českého carsharingu.
Při transformacích stahujeme zdroj MobilityOperator, ze kterého bereme rental_apps pro system information.

#### Datový zdroj *Next Bike*
 - Next Bike zdroj:
   - [nextbike_tg](https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_tg/gbfs.json)
   - [nextbike_tq](https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_tq/gbfs.json)
   - [nextbike_tk](https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_tk/gbfs.json)
   - [nextbike_td](https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_td/gbfs.json)
 - [validační schéma Next Bike](../src/schema-definitions/datasources/Nextbike/*)
 - rabbitmq fronta: `dataplatform.nextbikesharedbikes.refreshNextbikeData`
 - frekvence stahování: `0 * * * * *`, tzn. každou minutu

#### Datový zdroj *Rekola - trackable data*

- zdroj dat
  - [Rekola trackables](https://www.rekola.cz/api/mobile/regions/1/trackables)
  - [IE config](https://gitlab.com/operator-ict/golemio/code/integration-engine/-/blob/development/config/datasources.default.json#L52)
  - parametry v security
- formát dat
  - HTTP GET
  - json
  - [validační schéma](../src/schema-definitions/datasources/RekolaTrackables.ts#L37)
  - ukázka dat
```json
{
    "isDiff": false,
    "isVehicleBorrowed": false,
    "racks": [
        {
            "id": 5,
            "isVisible": true,
            "name": "Podolí",
            "position": {
                "lat": 50.0516212413,
                "lng": 14.4167971936
            },
            "pin": {
                "width": 42,
                "height": 34,
                "sizes": {
                    "x1": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-ffffff-ff0090-0--bike-gears-x1.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-f2f2f2-ff0090-0--bike-gears-x1.png"
                    },
                    "x2": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-ffffff-ff0090-0--bike-gears-x2.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-f2f2f2-ff0090-0--bike-gears-x2.png"
                    },
                    "x3": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-ffffff-ff0090-0--bike-gears-x3.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-f2f2f2-ff0090-0--bike-gears-x3.png"
                    },
                    "x4": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-ffffff-ff0090-0--bike-gears-x4.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/r-1-f2f2f2-ff0090-0--bike-gears-x4.png"
                    }
                }
            },
            "vehicles": [
                {
                    "id": 5853,
                    "type": "bike",
                    "isVisible": true,
                    "isBorrowed": false,
                    "isBorrowedByMe": false,
                    "name": "Kriminálka Miami",
                    "label": "",
                    "position": {
                        "lat": 50.0516212413,
                        "lng": 14.4167971936
                    },
                    "positionNote": "Podolí",
                    "pin": {
                        "width": 42,
                        "height": 34,
                        "sizes": {
                            "x1": {
                                "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x1.png",
                                "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x1.png"
                            },
                            "x2": {
                                "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x2.png",
                                "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x2.png"
                            },
                            "x3": {
                                "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x3.png",
                                "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x3.png"
                            },
                            "x4": {
                                "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x4.png",
                                "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x4.png"
                            }
                        }
                    }
                }
            ]
        }
    ],
    "vehicles": [
        {
            "id": 1011,
            "type": "bike",
            "isVisible": true,
            "isBorrowed": false,
            "isBorrowedByMe": false,
            "name": "Smíchov",
            "label": "",
            "position": {
                "lat": 50.0947822222,
                "lng": 14.4640422222
            },
            "positionNote": null,
            "pin": {
                "width": 42,
                "height": 34,
                "sizes": {
                    "x1": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x1.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x1.png"
                    },
                    "x2": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x2.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x2.png"
                    },
                    "x3": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x3.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x3.png"
                    },
                    "x4": {
                        "normal": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-ffffff-ff0090-x-0-x4.png",
                        "selected": "https://s3.eu-central-1.amazonaws.com/data2.rekola.cz/pins/v020/v-bike-gears-f2f2f2-ff0090-x-0-x4.png"
                    }
                }
            }
        }
    ]
}
```
- frekvence stahování
  - [dev](https://gitlab.com/operator-ict/golemio/devops/infrastructure/-/blob/master/cluster_development/golemio_golemio-values.yaml#L387)
    - `0 */2 * * * *`, tzn. každé 2 minuty
  - [prod](https://gitlab.com/operator-ict/golemio/devops/infrastructure/-/blob/master/cluster_production/golemio_golemio-values.yaml#L385)
    - `0 */2 * * * *`, tzn. každé 2 minuty
- název rabbitmq fronty
  - `dataplatform.rekolasharedbikes.refreshRekolaTrackableData`
  - bez parametrů

#### Datový zdroj *Rekola - geofencing data*

- zdroj dat
  - [Rekola zones](https://www.rekola.cz/api/mobile/regions/1/zones)
  - [IE config](https://gitlab.com/operator-ict/golemio/code/integration-engine/-/blob/development/config/datasources.default.json#L52)
  - parametry v security
- formát dat
  - HTTP GET
  - json
  - [validační schéma](../src/schema-definitions/datasources/RekolaGeofencingZones.ts#L3)
  - ukázka dat
```json
[
    {
        "vehicleType": {
            "type": "bike",
            "name": "kolo",
            "description": "Klasické městské či sportovní kolo",
            "icon": "https://mobile.rekola.cz/static/icons/vehicles/png/bike.png",
            "color": "#ff0090"
        },
        "boundingBox": [
            {
                "lat": 49.9844314403,
                "lng": 14.3591213607
            },
            {
                "lat": 50.1262941842,
                "lng": 14.5812935137
            }
        ],
        "zones": [
            {
                "id": 1000004,
                "boundingBox": [
                    {
                        "lat": 50.1087266492,
                        "lng": 14.4608598632
                    },
                    {
                        "lat": 50.1089810158,
                        "lng": 14.4612564861
                    }
                ],
                "points": [
                    [
                        50.1089810158,
                        14.4612564861
                    ],
                    [
                        50.1087266492,
                        14.4612564861
                    ],
                    [
                        50.1087266492,
                        14.4608598632
                    ],
                    [
                        50.1089810158,
                        14.4608598632
                    ],
                    [
                        50.1089810158,
                        14.4612564861
                    ]
                ]
            }
        ]
    }
]
```
- frekvence stahování
  - [dev](https://gitlab.com/operator-ict/golemio/devops/infrastructure/-/blob/master/cluster_development/golemio_golemio-values.yaml#L381)
    - `0 25 7,13,19,1 * * *`, tzn. vždy v 7:25, 13:25, 19:25 a 1:25
  - [prod](https://gitlab.com/operator-ict/golemio/devops/infrastructure/-/blob/master/cluster_production/golemio_golemio-values.yaml#L379)
    - `0 25 7,13,19,1 * * *`, tzn. vždy v 7:25, 13:25, 19:25 a 1:25
- název rabbitmq fronty
  - `dataplatform.rekolasharedbikes.refreshRekolaGeofencingData`
  - bez parametrů

#### Datový zdroj *HoppyGo*

- zdroj dat
    - [HoppyGo](https://0csrj8wr3j.execute-api.eu-west-1.amazonaws.com/api/v3/external/my-prague/fdh98742ljfsd9fsd89H238nvuq)
    - parametry nejsou
- formát dat
    - HTTP GET
    - json
    - [validační schéma](../src/schema-definitions/datasources/HoppyGoVehiclesJsonSchema.ts)
    - [ukázka dat](../test/integration-engine/data/hoppygo-datasource.json)

- název rabbitmq fronty
    - `dataplatform.hoppygosharedbikes.refreshHoppyGoSharedCarsData`
    - bez parametrů
    - msg ttl 2 minuty

#### Datový zdroj *Český Carsharing*

- zdroj dat: 2 endpointy
    - [vozidla](https://api.ceskycarsharing.cz/iis_cs_api/IIS_API.svc/help/operations/getAllCarsIct)
    - [polygony](https://api.ceskycarsharing.cz/iis_cs_api_demo/IIS_API.svc/getPolygonsIct)
    - přístupné pouze z vybraných IP adres
    - hlavička: `Content-Type: application/json`
    - request body obsahuje JSON objekt s atributy `guid` a `password`:
```
{
    guid: "asdf-1234",
    password: "loremIpsum"
}
```
- formát dat:
    - HTTP POST
    - JSON
    - [validační schéma vozidel](../src/schema-definitions/datasources/CeskyCarsharingVehiclesJsonSchema.ts)
    - [validační schéma polygonů](../src/schema-definitions/datasources/CeskyCarsharingGeofencingJsonSchema.ts)
    - [ukázka dat vozidel](../test/integration-engine/data/cesky-carsharing-cars-datasource.json)
    - [ukázka dat polygonů](../test/integration-engine/data/cesky-carsharing-cars-datasource.json)

- rabbitmq fronty:
    - vozidla: `dataplatform.ceskycarsharingsharedbikes.refreshCeskyCarsharingVehiclesData`
    - polygony: `dataplatform.ceskycarsharingsharedbikes.refreshCeskyCarsharingGeofencingData`
    - bez parametrů
    - msg ttl 2 minuty
    - frekvence stahování: `0 */2 * * * *`, tzn. každé 2 minuty

#### Datový zdroj *MobilityOperator*
Stahuje se při transformaci operátorů. Není samostatný operátor, jen se jím obohacují data.

- formát dat:
    - HTTP GET
    - json
    - [validační schéma](../src/schema-definitions/datasources/MobilityOperator.ts)
    - [ukázka dat](../test/integration-engine/data/MobilityOperator.json)

## Zpracování dat / transformace
Transformace mapují data na GBFS formát. Data se obohacují ze zdroje MobilityOperator. Z něj se nahrazuje rental_apps
v system_information daného poskytovatele, pokud ve zdroji MobilityOperator existuje.

* Rekola: 2 workery, jeden pro Rekola a jeden na promazávání starých dat.
* Nextbike: 1 worker, stahuje a transformuje
* HoppyGo: 1 worker, stahuje a transformuje
* Český carsharing: 2 workery, jeden na vozidla, jeden na zóny (polygony)

### Worker *RekolaSharedBikesWorker*

[Odkaz](../src/integration-engine/RekolaSharedBikesWorker.ts). Obsahuje dvě metody, která transformuje a ukládá data psql. Stará data maže.

#### Metoda *refreshRekolaTrackableData*

- vstupní rabbitmq fronta
  - `dataplatform.rekolasharedbikes.refreshRekolaTrackableData`
  - bez parametrů
- datové zdroje
  - `Rekola - trackable data` (viz výše)
- transformace
  - [`RekolaBikeStatusTransformation`](../src/integration-engine/transformations/Rekola/RekolaBikeStatusTransformation.ts)
  - [`RekolaStationInformationTransformation`](../src/integration-engine/transformations/Rekola/RekolaStationInformationTransformation.ts)
  - [`RekolaStationStatusTransformation`](../src/integration-engine/transformations/Rekola/RekolaStationStatusTransformation.ts)
  - [`RekolaStationStatusVehicleTypeTransformation`](../src/integration-engine/transformations/Rekola/RekolaStationStatusVehicleTypeTransformation.ts)
  - [`RekolaVehicleTypeTransformation`](../src/integration-engine/transformations/Rekola/RekolaVehicleTypeTransformation.ts)
  - transformace pro uložení dynamických dat do GBFS formátu
- data modely
  - [VehicleTypesModel](../src/integration-engine/models/VehicleTypesModel.ts)
  - [StationInformationHistoryModel](../src/integration-engine/models/StationInformationHistoryModel.ts)
  - [StationStatusVehicleTypesModel](../src/integration-engine/models/StationStatusVehicleTypeModel.ts)
  - [BikeStatusModel](../src/integration-engine/models/BikeStatusModel.ts)
  - (viz níže)

#### Metoda *refreshRekolaGeofencingData*

- vstupní rabbitmq fronta
  - `dataplatform.rekolasharedbikes.refreshRekolaGeofencingData`
  - bez parametrů
- datové zdroje
  - `Rekola - geofencing data` (viz výše)
- transformace
  - [`RekolaGeofencingTransformation`](../src/integration-engine/transformations/RekolaGeofencingTransformation.ts)
  - transformace pro uložení statických dat do GBFS formátu
- data modely
  - [GeofencingZonesModel](../src/integration-engine/models/GeofencingZonesModel.ts)
  - (viz níže)

### Worker *NextbikeSharedBikesWorker*

[Odkaz](../src/integration-engine/NextbikeSharedBikesWorker.ts)
Obsahuje jednu public metodu, která stáhne data ze všech zdrojů, zavolá transformery všech tabulek a uloží data a smaže stará.

### Worker HoppyGo: *HoppyGoSharedCarsWorker*
* V jedné public metodě Stahuje, transformuje, ukládá data o vozidlech HoppyGo a maže stará data.
* Předpokládá všechny ceny ve feedu v CZK a všechna auta dostupná k zapůjčení v ČR.
* Statická data se ukládají jen když v db chybí.
* Žádná data nejsou v SQL migracích, vše je v jednotlivých transformerech.

## Uložení dat

Před uložením odfiltrujeme data mimo ČR pro bike status a station status. K tomu se používá nejdříve jednoduchý polygon uvnitř ČR složený z pár bodů a poté [polygon pro ČR](../staticData/geojson/czechia-border10km.geojson).
Data se ukládají do postgresql. Struktura databáze by měla vycházet ze standardu GBFS.

### Obecné

- typ databáze
  - PSQL
- datábázové schéma
  - [diagram](./db_diagram.md)
  - PSQL
    - schéma `bikesharing`
    - tabulky:
        - bike_status
        - geofencing_zones
        - pricing_plan_payment
        - pricing_plans
        - pricings
        - rental_apps
        - station_information
        - station_status
        - station_status_vehicle_type
        - system_information
        - vehicle_types
    - migrační skripty [složka](../db/migrations/)
    - example data [složka](../db/example/) (slouží i pro testy)
- retence dat
  - dynamická data se promazávají při každém běhu workeru providera

### *PSQL* model

- tabulka `bikesharing.bike_status`
    - struktura [BikeStatus](../src/schema-definitions/definitions/BikeStatus.ts)
- tabulka `bikesharing.geofencing_zones`
    - struktura [GeofencingZones](../src/schema-definitions/definitions/GeofencingZones.ts)
- tabulka `bikesharing.pricing_plan_payment`
    - pouze statická data naplněná migračním skriptem
- tabulka `bikesharing.pricing_plans`
    - struktura [PricingPlans](../src/schema-definitions/definitions/PricingPlans.ts)
    - statická data naplněná migračním skriptem
- tabulka `bikesharing.pricings`
    - struktura [Pricings](../src/schema-definitions/definitions/Pricings.ts)
    - statická data naplněná migračním skriptem
- tabulka `bikesharing.rental_apps`
    - struktura [RentalApps](../src/schema-definitions/definitions/RentalApps.ts)
    - statická data naplněná migračním skriptem
- tabulka `bikesharing.station_information`
    - struktura [StationInformation](../src/schema-definitions/definitions/StationInformation.ts)
- tabulka `bikesharing.station_status`
    - struktura [StationStatus](../src/schema-definitions/definitions/StationStatus.ts)
- tabulka `bikesharing.station_status_vehicle_type`
    - struktura [StationStatusVehicleType](../src/schema-definitions/definitions/StationStatusVehicleType.ts)
- tabulka `bikesharing.system_information`
    - struktura [SystemInformation](../src/schema-definitions/definitions/SystemInformation.ts)
    - statická data naplněná migračním skriptem
- tabulka `bikesharing.vehicle_types`
    - struktura [VehicleTypes](../src/schema-definitions/definitions/VehicleTypes.ts)




## Output API

K dispozici je standardní output geojson api a GBFS api.

**U výsledných GBFS objektů probíhá odmazávání prázdných nebo nullový atributů.**

### Obecné

- Zdroj pro api
  - PSQL databáze viz výše
- API Blueprint / OpenAPI dokumentace
  - [OpenAPI](./openapi.yaml)
- veřejné / neveřejné endpointy
  - částečně veřejná na úrovni filtrování podle poskytovatele dat
- postman kolekce
  - TBD

#### */sharedbikes*

- zdrojové tabulky
  - bike_status
  - system_information
  - vehicle_type
- nestandardní dodatečná transformace
  - transformace z GBFS struktury na GeoJSON
- query parametry
  - latlng
  - range
  - limit
  - offset
  - companyName = `system_information.name`
  - updatedSince
- filtr dat
  - filtrovány pouze data typu `bicycle` a `shared_moped` (z tabulky vehicle_type)

#### */sharedbikes/{id}*

- zdrojové tabulky
  - bike_status
  - system_information
  - vehicle_type
- nestandardní dodatečná transformace
  - transformace z GBFS struktury na GeoJSON
- url parametr
  - id = `bike_status.id`


#### */sharedbikes/gbfs/systems_list*

- zdrojové tabulky
  - system_information

#### */sharedbikes/gbfs/:system_id/gbfs*

- zdrojové tabulky
  - system_information
- url parametr
  - system_id = `system_information.system_id`
- **data jsou staticky v kódu**

#### */sharedbikes/gbfs/:system_id/gbfs_versions*

- zdrojové tabulky
  - system_information
- url parametr
  - system_id = `system_information.system_id`
- **data jsou staticky v kódu**

#### */sharedbikes/gbfs/:system_id/system_information*

- zdrojové tabulky
  - system_information
  - rental_apps
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/free_bike_status*

- zdrojové tabulky
  - bike_status
  - system_information
  - rental_apps
  - vehicle_types
  - pricing_plans
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/vehicle_types*

- zdrojové tabulky
  - bike_status
  - vehicle_types
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/station_information*

- zdrojové tabulky
  - station_information
  - rental_apps
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/station_status*

- zdrojové tabulky
  - station_status
  - station_status_vehicle_type
  - bike_status
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/system_pricing_plans*

- zdrojové tabulky
  - pricing_plans
  - pricings
- url parametr
  - system_id = `system_information.system_id`

#### */sharedbikes/gbfs/:system_id/geofencing_zones*

- zdrojové tabulky
  - geofencing_zones
- url parametr
  - system_id = `system_information.system_id`

#### */sharedcars*

- **náhrada modulu SharedCars**
- zdrojové tabulky
  - bike_status
  - system_information
  - vehicle_type
- nestandardní dodatečná transformace
  - transformace z GBFS struktury na GeoJSON
- query parametry
  - latlng
  - range
  - limit
  - offset
  - companyNames = `system_information.name`
  - updatedSince
- filtr dat
  - filtrovány pouze data typu `car` (z tabulky vehicle_type)

#### */sharedcars/{id}*

- **náhrada modulu SharedCars**
- zdrojové tabulky
  - bike_status
  - system_information
  - vehicle_type
- nestandardní dodatečná transformace
  - transformace z GBFS struktury na GeoJSON
- url parametr
  - id = `bike_status.id`
