From 9c0bf7ad82ee7b6769c01bb5df9978dc93440f0f Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 13 Mar 2024 05:21:28 +0100 Subject: [PATCH 1/7] docs: traindelays.http contains production GET request --- docs/traindelays.http | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/traindelays.http b/docs/traindelays.http index af97e85..34e0d92 100644 --- a/docs/traindelays.http +++ b/docs/traindelays.http @@ -1,2 +1,5 @@ -### +### GET next departure from local system GET http://localhost:8080/nextdeparture + +### GET next departure from production system +GET https://train-delays-lvnrwcqd7q-ew.a.run.app/nextdeparture From 22a62baf6bc4716cada91ed674fe3df90fce4554 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Wed, 13 Mar 2024 05:29:45 +0100 Subject: [PATCH 2/7] docs: User Guide and README contains improved instructions for docker --- README.md | 10 ++++++---- docs/user-guide.md | 7 ++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 44a960c..b83749b 100644 --- a/README.md +++ b/README.md @@ -46,14 +46,16 @@ Build the Docker image: docker build -t boos/train-delays . ``` -Pass the environment variable `DB_API_KEY` and `CLIENT_ID` to the Docker container when running it: +Pass the environment variables `API_KEY` and `CLIENT_ID` to the Docker container when running it: ```sh -export DB_API_KEY=your-api-key -export CLIENT_ID=your-client-id -docker run -p 8080:8080 --env DB_API_KEY=$DB_API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays +export API_KEY= +export CLIENT_ID= +docker run -p 8080:8080 --env API_KEY=$API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays ``` +See [User Guide](docs/user-guide.md) for more details. + ## Before Creating a Pull Request ### Check Code Metrics diff --git a/docs/user-guide.md b/docs/user-guide.md index 411cde9..024c76f 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -24,9 +24,14 @@ Note: The API Key will not be revealed. Please save the key to a password safe w Document](architecture.adoc#721-prerequisites)). ```sh -docker run -p 8080:8080 --env CLIENT_ID= --env API_KEY= --name train-delays-app --rm boos/train-delays +export API_KEY= +export CLIENT_ID= +docker run -p 8080:8080 --env API_KEY=$API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays ``` +To test the local Docker container, fire an HTTP GET request to http://localhost:8080/nextdeparture +See [traindelays.http](./traindelays.http) for a sample request. + ### Run the Application Using a Local Java Installation ```sh From 342b9f81ddb3f6e4a405ada99d4d93841d9a7703 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Thu, 14 Mar 2024 05:42:01 +0100 Subject: [PATCH 3/7] feat: ChatGPT plugin manifest is hosted at /ai-plugin.json --- .gitignore | 4 ++++ .../static/.well-known/ai-plugin.json | 17 +++++++++++++++++ src/main/resources/static/logo.drawio.png | Bin 0 -> 3385 bytes src/main/resources/static/logo.png | Bin 0 -> 11427 bytes 4 files changed, 21 insertions(+) create mode 100644 src/main/resources/static/.well-known/ai-plugin.json create mode 100644 src/main/resources/static/logo.drawio.png create mode 100644 src/main/resources/static/logo.png diff --git a/.gitignore b/.gitignore index 9f19579..b6405e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +### Draw.io / diagrams.net temporary files ### +.$*.bkp +.$*.dtmp + ### private secret configuration for the http-client ### http-client.private.env.json diff --git a/src/main/resources/static/.well-known/ai-plugin.json b/src/main/resources/static/.well-known/ai-plugin.json new file mode 100644 index 0000000..62ac39f --- /dev/null +++ b/src/main/resources/static/.well-known/ai-plugin.json @@ -0,0 +1,17 @@ +{ + "schema_version": "v1", + "name_for_human": "Train Delays", + "name_for_model": "train-delays", + "description_for_human": "Query train delays. The API shows when the next train leaves the train station Rösrath-Stümpen.", + "description_for_model": "Tell the user when the next train leaves the train station Rösrath Stümpen.", + "auth": { + "type": "none" + }, + "api": { + "type": "openapi", + "url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/openapi.yaml" + }, + "logo_url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/logo.png", + "contact_email": "kontakt@boos.systems", + "legal_info_url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/legal" +} diff --git a/src/main/resources/static/logo.drawio.png b/src/main/resources/static/logo.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..d746345cf16acd531b087ee61adc3b183758a516 GIT binary patch literal 3385 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 LnL|22$Sn95ZbWNn literal 0 HcmV?d00001 diff --git a/src/main/resources/static/logo.png b/src/main/resources/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f13af98575d569c390518d4a7c54473e0b1afc GIT binary patch literal 11427 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 G^#1|`4pMUf literal 0 HcmV?d00001 From 39c0607ee6eedec5bf201149ddfdd6df2cd952a6 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Sat, 16 Mar 2024 19:53:07 +0100 Subject: [PATCH 4/7] feat: host Swagger UI and OpenAPI json specification --- build.gradle | 1 + src/main/resources/static/.well-known/ai-plugin.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f5db6ea..244417c 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0' // adding the Jackson reference automatically allows processing application/xml response bodies implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.4' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2' diff --git a/src/main/resources/static/.well-known/ai-plugin.json b/src/main/resources/static/.well-known/ai-plugin.json index 62ac39f..e1f4d27 100644 --- a/src/main/resources/static/.well-known/ai-plugin.json +++ b/src/main/resources/static/.well-known/ai-plugin.json @@ -9,7 +9,7 @@ }, "api": { "type": "openapi", - "url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/openapi.yaml" + "url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/v3/api-docs" }, "logo_url": "https://train-delays-lvnrwcqd7q-ew.a.run.app/logo.png", "contact_email": "kontakt@boos.systems", From fa62132cdddf66ce3a69186acb958aa63df125e1 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Sat, 16 Mar 2024 21:06:40 +0100 Subject: [PATCH 5/7] feat: improve OpenAPI documentation --- build.gradle | 5 +++++ .../systems/boos/traindelays/TrainDelaysController.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/build.gradle b/build.gradle index 244417c..7fc86f8 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,12 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + + // Generate OpenAPI documentation from Javadoc, see https://springdoc.org/#javadoc-support + annotationProcessor 'com.github.therapi:therapi-runtime-javadoc-scribe:0.13.0' + implementation 'com.github.therapi:therapi-runtime-javadoc:0.13.0' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0' + // adding the Jackson reference automatically allows processing application/xml response bodies implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.4' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2' diff --git a/src/main/java/systems/boos/traindelays/TrainDelaysController.java b/src/main/java/systems/boos/traindelays/TrainDelaysController.java index 16bb53a..13c10a6 100644 --- a/src/main/java/systems/boos/traindelays/TrainDelaysController.java +++ b/src/main/java/systems/boos/traindelays/TrainDelaysController.java @@ -1,5 +1,8 @@ package systems.boos.traindelays; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; @@ -20,6 +23,11 @@ public TrainDelaysController(TimetablesService timetablesService) { this.timetablesService = timetablesService; } + @Operation(summary = "Time of next train leaving Rösrath Stümpen", description = "Get the time when the next train leaves the station Rösrath-Stümpen") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Time of next departure"), + @ApiResponse(responseCode = "204", description = "No trains received from DB Timetables API"), + }) @GetMapping("/nextdeparture") public ExpectedDepartureResponse getNextDeparture(HttpServletResponse response) { Timetable timetable = timetablesService.fetchChanges(); From 79c1c955b111dda992dd99aea9a839f2974ff403 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Sat, 16 Mar 2024 21:07:34 +0100 Subject: [PATCH 6/7] docs: user guide is now separate from developer guide --- README.md | 85 +--------------------------- docs/developer-guide.md | 119 ++++++++++++++++++++++++++++++++++++++++ docs/traindelays.http | 6 ++ docs/user-guide.md | 44 --------------- 4 files changed, 127 insertions(+), 127 deletions(-) create mode 100644 docs/developer-guide.md diff --git a/README.md b/README.md index b83749b..b08a17f 100644 --- a/README.md +++ b/README.md @@ -21,90 +21,9 @@ an [Open Source License](https://www.jetbrains.com/community/opensource/) for th ## Documentation Overview - [User Guide](docs/user-guide.md) +- [Developer Guide](docs/developer-guide.md) - [Architecture](docs/architecture.adoc) -## Build, Test, Run - -### Prerequisites - -The build is tested with the following versions: - -- [Java 21.0.2](https://adoptopenjdk.net/) -- [Gradle](https://gradle.org/) is configured by the [gradle-wrapper.properties](gradle/wrapper/gradle-wrapper.properties) - -### Build the Solution and Run the Tests - -```sh -./gradlew clean build test --warning-mode all -``` - -### Build and Run the Docker Image - -Build the Docker image: - -```sh -docker build -t boos/train-delays . -``` - -Pass the environment variables `API_KEY` and `CLIENT_ID` to the Docker container when running it: - -```sh -export API_KEY= -export CLIENT_ID= -docker run -p 8080:8080 --env API_KEY=$API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays -``` - -See [User Guide](docs/user-guide.md) for more details. - -## Before Creating a Pull Request - -### Check Code Metrics - -... check code metrics using [metrix++](https://github.com/metrixplusplus/metrixplusplus) - -- Configure the location of the cloned metrix++ scripts - ```sh - export METRIXPP=/path/to/metrixplusplus - ``` - -- Collect metrics - ```sh - python "$METRIXPP/metrix++.py" collect --std.code.complexity.cyclomatic --std.code.lines.code --std.code.todo.comments --std.code.maintindex.simple -- . - ``` - -- Get an overview - ```sh - python "$METRIXPP/metrix++.py" view --db-file=./metrixpp.db - ``` - -- Apply thresholds - ```sh - python "$METRIXPP/metrix++.py" limit --db-file=./metrixpp.db --max-limit=std.code.complexity:cyclomatic:5 --max-limit=std.code.lines:code:25:function --max-limit=std.code.todo:comments:0 --max-limit=std.code.mi:simple:1 - ``` - -At the time of writing, I want to stay below the following thresholds: - -``` ---max-limit=std.code.complexity:cyclomatic:5 ---max-limit=std.code.lines:code:25:function ---max-limit=std.code.todo:comments:0 ---max-limit=std.code.mi:simple:1 -``` - -Finally, remove all code duplication. The next section describes how to detect code duplication. - -### Remove Code Duplication Where Appropriate - -To detect duplicates I use the [CPD Copy Paste Detector](https://pmd.github.io/latest/pmd_userdocs_cpd.html) -tool from the [PMD Source Code Analyzer Project](https://pmd.github.io/latest/index.html). - -If you have installed PMD by download & unzip, replace `pmd` by `./run.sh`. -The [homebrew pmd formula](https://formulae.brew.sh/formula/pmd) makes the `pmd` command globally available. - -```sh -pmd cpd --minimum-tokens 50 --files src -``` - ## References -* Deutsche Bahn, Germany: [Open API-Portal](https://developer.deutschebahn.com/store/site/pages/home.jag) +- Deutsche Bahn, Germany: [DB API Marketplace](https://developers.deutschebahn.com/db-api-marketplace/apis/) diff --git a/docs/developer-guide.md b/docs/developer-guide.md new file mode 100644 index 0000000..43ca599 --- /dev/null +++ b/docs/developer-guide.md @@ -0,0 +1,119 @@ +# Train Delays Developer Guide + +## Prerequisite + +Please register with and subscribe to the [Timetables +API](https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables/api/1309#/Timetables_10197/overview). +This is described in detail in section [7.2.1 Prerequisites of the Architecture +Document](architecture.adoc#721-prerequisites). + +## Run the Application in a Docker Container + +The [build pipeline](../.github/workflows/build.yml) publishes the application to [Docker +Hub](https://hub.docker.com/r/boos/train-delays). Thus, you can pull an image and run it. + +Then, in the following, replace `` and `` with the values displayed in the section "Berechtigungsnachweise" for your application in [DB API Marketplace / Applications](https://developers.deutschebahn.com/db-api-marketplace/apis/application). + +Note: The API Key will not be revealed. Please save the key to a password safe when creating it (see [7.2.1 Prerequisites of the Architecture +Document](architecture.adoc#721-prerequisites)). + +```sh +export API_KEY= +export CLIENT_ID= +docker run -p 8080:8080 --env API_KEY=$API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays +``` + +## Run the Application Using a Local Java Installation + +To simply run the application: + +```sh +API_KEY="" CLIENT_ID="" ./gradlew bootRun +``` + +If you want to rebuild and reload the application automatically when the source code changes, you will need two terminals. + +In the first terminal, recompile the application continuously: + +```sh +./gradlew build --continuous +``` + +In the second terminal, run the application with live reload: + +```sh +API_KEY="" CLIENT_ID="" ./gradlew bootRun +``` + +See: [Stackoverflow: Spring Boot bootRun with continuous build](https://stackoverflow.com/questions/52092504/spring-boot-bootrun-with-continuous-build) + +## Open the User Interface + +Open a web browser and navigate to http://localhost:8080 + +## Query the Next Departure + +Fire an HTTP GET request to http://localhost:8080/nextdeparture + +```sh +curl --include http://localhost:8080/nextdeparture +``` + +[traindelays.http](./traindelays.http) contains additional sample requests. + +## Query the Open API Specification + +The Swagger UI contains online documentation and is available at http://localhost:8080/swagger-ui.html + +The Open API specification is available as JSON document at http://localhost:8080/v3/api-docs + +The YAML version of the Open API specification is available at http://localhost:8080/v3/api-docs.yaml + +## Before Creating a Pull Request + +### Check Code Metrics + +... check code metrics using [metrix++](https://github.com/metrixplusplus/metrixplusplus) + +- Configure the location of the cloned metrix++ scripts + ```sh + export METRIXPP=/path/to/metrixplusplus + ``` + +- Collect metrics + ```sh + python "$METRIXPP/metrix++.py" collect --std.code.complexity.cyclomatic --std.code.lines.code --std.code.todo.comments --std.code.maintindex.simple -- . + ``` + +- Get an overview + ```sh + python "$METRIXPP/metrix++.py" view --db-file=./metrixpp.db + ``` + +- Apply thresholds + ```sh + python "$METRIXPP/metrix++.py" limit --db-file=./metrixpp.db --max-limit=std.code.complexity:cyclomatic:5 --max-limit=std.code.lines:code:25:function --max-limit=std.code.todo:comments:0 --max-limit=std.code.mi:simple:1 + ``` + +At the time of writing, I want to stay below the following thresholds: + +``` +--max-limit=std.code.complexity:cyclomatic:5 +--max-limit=std.code.lines:code:25:function +--max-limit=std.code.todo:comments:0 +--max-limit=std.code.mi:simple:1 +``` + +Finally, remove all code duplication. The next section describes how to detect code duplication. + +### Remove Code Duplication Where Appropriate + +To detect duplicates I use the [CPD Copy Paste Detector](https://pmd.github.io/latest/pmd_userdocs_cpd.html) +tool from the [PMD Source Code Analyzer Project](https://pmd.github.io/latest/index.html). + +If you have installed PMD by download & unzip, replace `pmd` by `./run.sh`. +The [homebrew pmd formula](https://formulae.brew.sh/formula/pmd) makes the `pmd` command globally available. + +```sh +pmd cpd --minimum-tokens 50 --files src +``` \ No newline at end of file diff --git a/docs/traindelays.http b/docs/traindelays.http index 34e0d92..7a3e196 100644 --- a/docs/traindelays.http +++ b/docs/traindelays.http @@ -1,5 +1,11 @@ ### GET next departure from local system GET http://localhost:8080/nextdeparture +### GET open api specification in JSON format from local system +GET http://localhost:8080/v3/api-docs + +### GET open api specification in YAML format from local system +GET http://localhost:8080/v3/api-docs.yaml + ### GET next departure from production system GET https://train-delays-lvnrwcqd7q-ew.a.run.app/nextdeparture diff --git a/docs/user-guide.md b/docs/user-guide.md index 024c76f..6f71e83 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -1,47 +1,3 @@ # Train Delays User Guide -## As a Normal User ... - ... just navigate to the [Train Delays Web Application](https://train-delays-lvnrwcqd7q-ew.a.run.app/). - -## As a Software Developer ... - -### Prerequisite - -Please register with and subscribe to the [Timetables -API](https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables/api/1309#/Timetables_10197/overview). -This is described in detail in section [7.2.1 Prerequisites of the Architecture -Document](architecture.adoc#721-prerequisites). - -### Run the Application in a Docker Container - -The [build pipeline](../.github/workflows/build.yml) publishes the application to [Docker -Hub](https://hub.docker.com/r/boos/train-delays). Thus, you can pull an image and run it. - -Then, in the following, replace `` and `` with the values displayed in the section "Berechtigungsnachweise" for your application in [DB API Marketplace / Anwendungen](https://developers.deutschebahn.com/db-api-marketplace/apis/application). - -Note: The API Key will not be revealed. Please save the key to a password safe when creating it (see [7.2.1 Prerequisites of the Architecture -Document](architecture.adoc#721-prerequisites)). - -```sh -export API_KEY= -export CLIENT_ID= -docker run -p 8080:8080 --env API_KEY=$API_KEY --env CLIENT_ID=$CLIENT_ID boos/train-delays -``` - -To test the local Docker container, fire an HTTP GET request to http://localhost:8080/nextdeparture -See [traindelays.http](./traindelays.http) for a sample request. - -### Run the Application Using a Local Java Installation - -```sh -API_KEY="" ./gradlew bootRun -``` - -### Query the Next Departure - -Fire an HTTP GET request to http://localhost:8080/nextdeparture - -```sh -curl --include http://localhost:8080/nextdeparture -``` From bf1a3c8a0fcd70caa1a5435ea8b533e5aa7567c1 Mon Sep 17 00:00:00 2001 From: Stefan Boos Date: Sat, 16 Mar 2024 21:42:39 +0100 Subject: [PATCH 7/7] feat: improve OpenAPI documentation --- README.md | 3 +-- .../java/systems/boos/traindelays/OpenApiConfig.java | 12 ++++++++++++ .../boos/traindelays/TrainDelaysController.java | 2 +- src/main/resources/static/.well-known/ai-plugin.json | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 src/main/java/systems/boos/traindelays/OpenApiConfig.java diff --git a/README.md b/README.md index b08a17f..1ff4a49 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ [![Maintainability](https://api.codeclimate.com/v1/badges/90718a2dfc4e3bde6d44/maintainability)](https://codeclimate.com/github/wonderbird/train-delays/maintainability) [![Image Size](https://img.shields.io/docker/image-size/boos/train-delays)](https://hub.docker.com/repository/docker/boos/train-delays) -Find out when will the next train will leave the station Rösrath Stümpen. +Find out when the next train will leave the station Rösrath-Stümpen. This web application shows the expected departure time of the next train from the station Rösrath-Stümpen. -The [User Guide](docs/user-guide.md) describes how to run the application. The current version is one step on the road to the [Product Vision](docs/product-vision.md). diff --git a/src/main/java/systems/boos/traindelays/OpenApiConfig.java b/src/main/java/systems/boos/traindelays/OpenApiConfig.java new file mode 100644 index 0000000..e58411f --- /dev/null +++ b/src/main/java/systems/boos/traindelays/OpenApiConfig.java @@ -0,0 +1,12 @@ +package systems.boos.traindelays; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.servers.Server; + +@OpenAPIDefinition( + info = @Info(title = "Query train departure time", version = "v1", description = "Find out when the next train will leave the station Rösrath-Stümpen."), + servers = { @Server(url = "https://train-delays-lvnrwcqd7q-ew.a.run.app/", description = "Production server") } +) +public class OpenApiConfig { +} diff --git a/src/main/java/systems/boos/traindelays/TrainDelaysController.java b/src/main/java/systems/boos/traindelays/TrainDelaysController.java index 13c10a6..7aac7e1 100644 --- a/src/main/java/systems/boos/traindelays/TrainDelaysController.java +++ b/src/main/java/systems/boos/traindelays/TrainDelaysController.java @@ -23,7 +23,7 @@ public TrainDelaysController(TimetablesService timetablesService) { this.timetablesService = timetablesService; } - @Operation(summary = "Time of next train leaving Rösrath Stümpen", description = "Get the time when the next train leaves the station Rösrath-Stümpen") + @Operation(summary = "Time of next train leaving Rösrath-Stümpen", description = "Get the time when the next train leaves the station Rösrath-Stümpen") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Time of next departure"), @ApiResponse(responseCode = "204", description = "No trains received from DB Timetables API"), diff --git a/src/main/resources/static/.well-known/ai-plugin.json b/src/main/resources/static/.well-known/ai-plugin.json index e1f4d27..629ef15 100644 --- a/src/main/resources/static/.well-known/ai-plugin.json +++ b/src/main/resources/static/.well-known/ai-plugin.json @@ -3,7 +3,7 @@ "name_for_human": "Train Delays", "name_for_model": "train-delays", "description_for_human": "Query train delays. The API shows when the next train leaves the train station Rösrath-Stümpen.", - "description_for_model": "Tell the user when the next train leaves the train station Rösrath Stümpen.", + "description_for_model": "Tell the user when the next train leaves the train station Rösrath-Stümpen.", "auth": { "type": "none" },