diff --git a/.active.txt.swp b/.active.txt.swp
new file mode 100644
index 000000000..9ed1af507
Binary files /dev/null and b/.active.txt.swp differ
diff --git a/.github/ISSUE_TEMPLATE/report-bug.md b/.github/ISSUE_TEMPLATE/report-bug.md
index 3ee790e33..0893dd2b1 100644
--- a/.github/ISSUE_TEMPLATE/report-bug.md
+++ b/.github/ISSUE_TEMPLATE/report-bug.md
@@ -1,7 +1,7 @@
---
name: Report a Bug
-about: Template for reporting a Snomio bug
-description: "Template for reporting a Snomio bug"
+about: Template for reporting a Lingo bug
+description: "Template for reporting a Lingo bug"
title: ''
labels: "bug"
assignees: ''
@@ -9,10 +9,12 @@ assignees: ''
---
### ENVIRONMENT DETAILS
* **Environment (Dev/UAT/Prod):**
+* **Browser:**
* **Date observed:**
* **Observed by:**
### OBSERVED BEHAVIOUR
-
### EXPECTED BEHAVIOUR
+
+### STEPS TO REPRODUCE
diff --git a/.github/ISSUE_TEMPLATE/user-story.md b/.github/ISSUE_TEMPLATE/user-story.md
index 016ec13d2..ce2f74671 100644
--- a/.github/ISSUE_TEMPLATE/user-story.md
+++ b/.github/ISSUE_TEMPLATE/user-story.md
@@ -1,6 +1,6 @@
---
name: User story
-about: User story template for Snomio
+about: User story template for Lingo
title: ''
labels: ''
assignees: ''
diff --git a/.gitignore b/.gitignore
index 750a82001..f52f227bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,6 @@
.DS_Store
api/src/main/resources/static
ui/reports
-setenv.sh
\ No newline at end of file
+setenv.sh
+sergio-extension/dependency-reduced-pom.xml
+/eclrefset/target/
diff --git a/.trivyignore b/.trivyignore
index 1f3565fcf..60f4a1f72 100644
--- a/.trivyignore
+++ b/.trivyignore
@@ -1,14 +1,3 @@
-# This is 7 hours old and eclipse base image is not updated yet
-CVE-2023-4911
-CVE-2023-34062
-CVE-2023-6378
-CVE-2023-34054
-CVE-2023-34055
-CVE-2023-34053
-# No fixed version yet 10/01/24
-CVE-2023-51074
-CVE-2024-22243
-# No fixed version yet - 22/02/24
-CVE-2024-22234
-# Requires Spring boot starter upgrade
-CVE-2024-22262
+# Reactor-netty, in spring-boot-starter-webflux, there is currently not a fix for it, also does not affect us as it is
+# A vulnerability that only affects windows machines.
+CVE-2024-47535
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..f8d8f18eb
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,157 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+The following sections are considered for each release: **Added, Changed, Fixed, Security, Deprecated, Removed**
+
+## [Unreleased]
+- No updates yet.
+
+
+## [1.2.10.6] - 2025-07-02
+
+### Fixed
+
+- Fixed handling of primitive concept selection as component of a multicomponent, multipack product in one of the packs
+
+## [1.2.10.5] - 2025-06-24
+
+### Fixed
+
+- Detection of datatypes or object properties based on the SnowstormRelationship.getConcrete() Boolean result was unreliable due to null values. This led to missing clauses in the ECL and overly broad detection of existing concepts.
+
+## [1.2.10.4] - 2025-05-29
+
+### Added
+
+- Ability to drag/drop attachments onto tickets
+- Can now filter for refsets with inactive concepts
+- Can now create tasks on the snodine page, on any project
+- Create additional synonyms in the 7 box create screen
+
+### Changed
+
+- Sort refset members by title
+- Reference sets are now handled on the front end, all data is queried when a reference set is loaded
+
+### Fixed
+
+- Pagination of reference set members now extends beyond 10,000
+- Issues with the artgid reference set
+- Issues with the semantic tags when the duplicate fsn/pt warning would appear on the 7 box create screen
+
+## [1.2.10.3] - 2025-04-24
+
+### Added
+
+- Ability to manually lock Snomio processes during a release week (#1350)
+- Display a concept model diagram for a concept using the inferred view (#870)
+- Create additional synonyms for new product concepts within the 7-box Preview screen (#159)
+- Ticket management: Attach multiple files to a ticket in a single manual operation (#1263)
+- Separation of semantic tags from concept descriptions in the 7-box Preview screen (#1354)
+- Validation of concept semantic tags within the Preview screen (#1353)
+- Sergio: Add/update additional URLs targeting product information (#1262)
+
+### Changed
+
+- In the dashboard screen, add the saved filter's name as a title for each cell (#867)
+- 7-box Preview screen does not remove newline characters from manually-edited descriptions (#1328)
+- Task Management: Sort tasks by reviewers (#1303)
+- Sergio: Remove BlackTriangle label from ticket when the product is no longer BTS (#1370)
+- Sergio: Additional stabilisation improvements (#1300)
+- Snodine: Overnight processing should skip broken reference sets without aborting the entire run (#1398)
+
+### Fixed
+
+- Unable to edit the description of a multi-component product (#1323)
+- Sergio: Tickets are being updated with incomplete comments (#1277)
+- Sergio: Incorrect title for product URL in tickets (#1409)
+
+## [1.2.10.2] - 2025-02-27
+
+
+## [1.2.10.1] - 2025-02-27
+
+## [1.2.9] - 2024-12-06
+### Added
+- "Help & Support" button for reporting bugs or requesting features
+ * You need to specify your name and email address, then an internal ticket (which is neither Jira nor Snomio) will be generated.
+ * The system will capture some of the browser logs, the URL you're on, etc. and you can also add a screenshot.
+ * The development team is notified when a ticket is created, and bug fixes and features will be added to the Snomio backlog as required for tracking.
+ * This system will also automatically report backend errors encountered by Snomio, for example if the server gets a random error while communicating with Snowstorm.
+ * If you are unsure of whether an on-screen behaviour is an issue, or you have an initial suggestion for a complex feature, please continue to use the Teams channels for discussing interactively first.
+- Add and remove ARTG IDs from existing concepts
+ * From within a task, when the atomic data entry form is displayed one of the authoring options is “Edit Product”.
+ * After searching for and selecting a product, all of the CTPPs will have a pencil icon for editing the concept.
+ * In addition to adding and removing ARTG IDs, the FSN and PT of the CTPP can be modified as well.
+ * A history of these editing changes is not currently being recorded against the ticket. This will be added after a design discussion around recording other product/concept changes has occurred (e.g. when modifying a product by using the atomic data entry form).
+ * Until the history of changes is being recorded against a ticket, users should record these updates as a comment on the ticket – so reviewers can check the changes using the Authoring Platform.
+- Addition of environment-specific Lingo logo
+ * To match the Authoring Platform: Production = blue, UAT = green, Dev = red
+ * The logo colour helps ensure users (and testers) are working within the correct environment.
+- Modify and Delete saved ticket backlog filters
+ * Available within the System Settings after clicking the user’s name.
+ * The new modification feature currently only modifies the name of the filter. You can still modify the way the filter works by applying it to the backlog, and then saving over the top of the existing filter – you just could never change its name before.
+- Preview for attachments in the Edit Ticket screen
+ * The following document types will offer a preview: png/jpg/jpeg, pdf
+ * These are among the most commonly-used attachment file types. Extending the preview to other file types will require significant development effort.
+ * Attachments can still be downloaded from the tickets.
+### Changed
+- Users can highlight/copy text from list rows
+ * All lists (except the list of tickets on a task) can have their row text highlighted and copied to the clipboard (e.g. ticket numbers in the Sergio notifications).
+ * Previously, dragging the cursor across the row would cause a drag-and-drop event to start.
+- Within the 7-box model screens, when viewing the list of reference sets for a concept they are now sorted alphabetically
+- Internal changes to support open-sourcing of Snomio
+ * These changes do not affect the functionality of the applications, just makes them more generic for external developers to view and use.
+ * These changes affected a wide range of code across the platform, which has then undergone regression testing to ensure it will be suitable for deployment.
+### Fixed
+- In the product Advanced Search feature, entering a 5-digit number would cause an error message to be displayed
+ * This was related to the Advanced Search’s inherent ability to search for an ARTG ID.
+- Clicking the title of a ticket in the Edit Task screen sends the user to the Backlog list and then draws the Edit Ticket panel (instead of leaving the Edit Task screen open in the background)
+- When associating a task with a ticket in the Edit Task panel, task titles are artificially truncated
+- Ticket management: when a ticket is assigned to a user, the comments saved against the ticket are shown to have been created by the new user
+ * This was just a display issue; the data underneath was not being overwritten.
+- Unable to associate specific tickets with tasks
+ * The original list of tickets was manually fixed in the Production environment.
+ * Further changes have now occurred to reduce the chance of this occurring in the future, and to ensure that clearing the associated task from a ticket would occur without performing misleading validation.
+- Manage Products from Deleted Task When Reassigning Ticket to New Task
+ * After creating a product against a task, and then deleting that task and associating the ticket with another task, the saved product is still present in the Products list for the ticket.
+ * Users used to be able to click the product to view its 7-box model diagram, even though the concepts no longer exist. Now the only option is to upload the product’s details into the atomic data entry form.
+ * Products which have been saved against the ticket but are not available within the current task will be coloured green (because they are completed) however they will also have a warning logo displayed in the row.
+- 7-box Preview screen: Concept heading box should be red when multiple concepts exist for a box (was displaying as green, which was misleading)
+- 7-box Preview screen: Unknown validation error occurs after selecting a concept option (when multiple potential concepts have been found) and reloading screen
+ * Atomic data saved against a ticket can immediately be loaded into the atomic data entry form and then previewed; the 7-box Preview screen will show the MPUU (or whichever notable concept that was affected) in red and either an existing concept selected, or a new concept created, from within the screen.
+- 7-Box Preview screen: Product details saved against ticket are skewing new product creation calculation
+ * This was observed when multiple potential MPUUs were found during product creation. After selecting one and saving the product, then loading the product into the atomic data entry form and clicking Preview, the system would automatically select an MPUU instead of offering the original set of options to the user.
+
+## [1.2.8]
+
+## [1.2.7]
+
+## [1.2.5]
+
+## [1.2.4]
+
+## [1.2.3]
+
+## [1.2.2]
+
+## [1.2.1]
+
+## [1.2.0]
+
+## [1.1.3]
+
+### Fixed
+
+- a bug causing decimal concrete domain values that were whole numbers to not have a zero decimal
+ place rendered in the concrete domain value making the classifier think they were integers
+
+## [1.1.2]
+
+## [1.1.0]
+
+Initial testing version
diff --git a/LICENSE b/LICENSE
index 261eeb9e9..0bea90964 100644
--- a/LICENSE
+++ b/LICENSE
@@ -175,27 +175,933 @@
END OF TERMS AND CONDITIONS
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+THIRD PARTY COMPONENTS
+
+The following third party components are distributed with the Software. You
+agree to comply with the licence terms for these components as part of
+accessing the Software. Other third party software may also be identified in
+separate files distributed with the Software.
+
+ (Apache License, Version 2.0) Apache Commons Collections (org.apache.commons:commons-collections4:4.4 - https://commons.apache.org/proper/commons-collections/)
+ (Apache License, Version 2.0) Apache Commons CSV (org.apache.commons:commons-csv:1.11.0 - https://commons.apache.org/proper/commons-csv/)
+ (Apache License, Version 2.0) Apache Commons Validator (commons-validator:commons-validator:1.9.0 - http://commons.apache.org/proper/commons-validator/)
+ (Apache License, Version 2.0) Apache Maven Resources Plugin (org.apache.maven.plugins:maven-resources-plugin:3.3.1 - https://maven.apache.org/plugins/maven-resources-plugin/)
+ (Eclipse Public License 2.0) AspectJ Weaver (org.aspectj:aspectjweaver:1.9.22.1 - https://www.eclipse.org/aspectj/)
+ (Apache License, Version 2.0) Awaitility (org.awaitility:awaitility:4.2.1 - http://awaitility.org)
+ (Apache License, Version 2.0) com.drewnoakes:metadata-extractor (com.drewnoakes:metadata-extractor:2.19.0 - https://drewnoakes.com/code/exif/)
+ (Apache License, Version 2.0) Ehcache (org.ehcache:ehcache:3.10.8 - http://ehcache.org)
+ (Apache License, Version 2.0) flyway-core (org.flywaydb:flyway-core:10.10.0 - https://flywaydb.org/flyway-core)
+ (Apache License, Version 2.0) flyway-database-postgresql (org.flywaydb:flyway-database-postgresql:10.10.0 - https://flywaydb.org/flyway-database-postgresql)
+ (Apache License, Version 2.0) Gson (com.google.code.gson:gson:2.10.1 - https://github.com/google/gson/gson)
+ (Apache License, Version 2.0) Gson (com.google.code.gson:gson:2.11.0 - https://github.com/google/gson)
+ (Eclipse Public License 1.0) (MPL 2.0) H2 Database Engine (com.h2database:h2:2.3.230 - https://h2database.com)
+ (GNU Library General Public License v2.1 or later) hibernate-jcache - relocation (org.hibernate:hibernate-jcache:6.5.2.Final - https://hibernate.org/orm)
+ (Apache License, Version 2.0) imgscalr - A Java Image Scaling Library (org.imgscalr:imgscalr-lib:4.2 - http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/)
+ (Apache License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2 - https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310)
+ (Apache License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.17.2 - https://github.com/FasterXML/jackson)
+ (Eclipse Public License 2.0) JaCoCo :: Maven Plugin (org.jacoco:jacoco-maven-plugin:0.8.12 - https://www.jacoco.org/jacoco/trunk/doc/maven.html)
+ (Apache License, Version 2.0) Java JSON Schema Generator (com.github.victools:jsonschema-generator:4.36.0 - https://github.com/victools/jsonschema-generator)
+ (Apache License, Version 2.0) Java JSON Schema Generator Module – jackson (com.github.victools:jsonschema-module-jackson:4.36.0 - https://github.com/victools/jsonschema-generator)
+ (Apache License, Version 2.0) Java JSON Schema Generator Module – jakarta.validation (com.github.victools:jsonschema-module-jakarta-validation:4.36.0 - https://github.com/victools/jsonschema-generator/jsonschema-module-jakarta-validation)
+ (Eclipse Public License 2.0) (GNU Lesser General Public License Version 2.1, February 1999) JGraphT - Core (org.jgrapht:jgrapht-core:1.5.2 - http://www.jgrapht.org/jgrapht-core)
+ (Public Domain) JSON in Java (org.json:json:20240303 - https://github.com/douglascrockford/JSON-java)
+ (Eclipse Public License 2.0) JUnit Jupiter API (org.junit.jupiter:junit-jupiter-api:5.10.3 - https://junit.org/junit5/)
+ (Eclipse Public License 2.0) JUnit Jupiter Params (org.junit.jupiter:junit-jupiter-params:5.10.3 - https://junit.org/junit5/)
+ (Apache License, Version 2.0) MapStruct Core (org.mapstruct:mapstruct:1.5.5.Final - https://mapstruct.org/mapstruct/)
+ (Apache License, Version 2.0) MapStruct Processor (org.mapstruct:mapstruct-processor:1.5.5.Final - https://mapstruct.org/mapstruct-processor/)
+ (Apache License, Version 2.0) micrometer-registry-prometheus (io.micrometer:micrometer-registry-prometheus:1.13.2 - https://github.com/micrometer-metrics/micrometer)
+ (Apache License, Version 2.0) mockwebserver (com.squareup.okhttp3:mockwebserver:5.0.0-alpha.12 - https://square.github.io/okhttp/)
+ (Apache License, Version 2.0) okhttp (com.squareup.okhttp3:okhttp:5.0.0-alpha.12 - https://square.github.io/okhttp/)
+ (Apache License, Version 2.0) OpenTelemetry Instrumentation for Java (io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.6.0 - https://github.com/open-telemetry/opentelemetry-java-instrumentation)
+ (Apache License Version 2.0, January 2004) (GNU LGPL Version 3.0) OWLAPI :: Interfaces (net.sourceforge.owlapi:owlapi-api:4.5.19 - http://owlcs.github.io/owlapi/owlapi-api/)
+ (Apache License Version 2.0, January 2004) (GNU LGPL Version 3.0) OWLAPI Binding and Config (net.sourceforge.owlapi:owlapi-apibinding:4.5.19 - http://owlcs.github.io/owlapi/owlapi-apibinding/)
+ (Apache License Version 2.0, January 2004) (GNU LGPL Version 3.0) OWLAPI Default Implementation (net.sourceforge.owlapi:owlapi-impl:4.5.19 - http://owlcs.github.io/owlapi/owlapi-impl/)
+ (BSD-2-Clause) PostgreSQL JDBC Driver (org.postgresql:postgresql:42.7.3 - https://jdbc.postgresql.org)
+ (MIT License) Project Lombok (org.projectlombok:lombok:1.18.30 - https://projectlombok.org)
+ (MIT License) Project Lombok (org.projectlombok:lombok:1.18.34 - https://projectlombok.org)
+ (Apache License, Version 2.0) Querydsl - APT support (com.querydsl:querydsl-apt:5.1.0 - http://www.querydsl.com)
+ (Apache License, Version 2.0) Querydsl - Core module (com.querydsl:querydsl-core:5.1.0 - http://www.querydsl.com)
+ (Apache License, Version 2.0) Querydsl - JPA support (com.querydsl:querydsl-jpa:5.1.0 - http://www.querydsl.com)
+ (Apache License, Version 2.0) Querydsl - SQL Spring support (com.querydsl:querydsl-sql-spring:5.1.0 - https://querydsl.github.io/querydsl-sql-spring/)
+ (Apache License, Version 2.0) Querydsl - SQL support (com.querydsl:querydsl-sql:5.1.0 - https://querydsl.github.io/querydsl-sql/)
+ (Apache License, Version 2.0) REST Assured (io.rest-assured:rest-assured:5.3.2 - http://code.google.com/p/rest-assured)
+ (Apache License, Version 2.0) REST Assured (io.rest-assured:rest-assured:5.5.0 - https://rest-assured.io/)
+ (Apache License, Version 2.0) sergio-extension (au.gov.digitalhealth:sergio-extension:1.2.4-SNAPSHOT - https://spring.io/projects/spring-boot/snomio/sergio-extension)
+ (Apache License, Version 2.0) SNOMED CT Expression Constraint Language Parser (org.snomed.languages:snomed-ecl-parser:3.0.0 - no url defined)
+ (Apache License, Version 2.0) snomed-owl-toolkit (org.snomed.otf:snomed-owl-toolkit:5.4.0 - no url defined)
+ (Apache License, Version 2.0) snomio api (au.csiro:snowstorm-java-client:8.1.1 - no url defined)
+ (Apache License, Version 2.0) snomio-auth (au.gov.digitalhealth:snomio-auth:1.2.4-SNAPSHOT - https://spring.io/projects/spring-boot/snomio/snomio-auth)
+ (Apache License, Version 2.0) snomio-common (au.gov.digitalhealth:snomio-common:1.2.4-SNAPSHOT - https://spring.io/projects/spring-boot/snomio/snomio-common)
+ (Apache License, Version 2.0) Spring Context (org.springframework:spring-context:6.1.11 - https://github.com/spring-projects/spring-framework)
+ (Apache License, Version 2.0) Spring Data Core (org.springframework.data:spring-data-commons:3.3.2 - https://spring.io/projects/spring-data)
+ (Apache License, Version 2.0) Spring Data Envers (org.springframework.data:spring-data-envers:3.3.2 - https://spring.io/projects/spring-data-jpa/spring-data-envers)
+ (Apache License, Version 2.0) Spring Web (org.springframework:spring-web:6.1.6 - https://github.com/spring-projects/spring-framework)
+ (Apache License, Version 2.0) spring-boot (org.springframework.boot:spring-boot:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-configuration-processor (org.springframework.boot:spring-boot-configuration-processor:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter (org.springframework.boot:spring-boot-starter:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-actuator (org.springframework.boot:spring-boot-starter-actuator:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-amqp (org.springframework.boot:spring-boot-starter-amqp:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-aop (org.springframework.boot:spring-boot-starter-aop:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-data-jpa (org.springframework.boot:spring-boot-starter-data-jpa:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-hateoas (org.springframework.boot:spring-boot-starter-hateoas:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-security (org.springframework.boot:spring-boot-starter-security:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-test (org.springframework.boot:spring-boot-starter-test:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-validation (org.springframework.boot:spring-boot-starter-validation:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-web (org.springframework.boot:spring-boot-starter-web:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) spring-boot-starter-webflux (org.springframework.boot:spring-boot-starter-webflux:3.3.2 - https://spring.io/projects/spring-boot)
+ (Apache License, Version 2.0) springdoc-openapi-starter-webmvc-ui (org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0 - https://springdoc.org/springdoc-openapi-starter-webmvc-ui/)
+ (MIT License) Testcontainers :: JDBC :: PostgreSQL (org.testcontainers:postgresql:1.19.8 - https://java.testcontainers.org)
+ (MIT License) Testcontainers :: JUnit Jupiter Extension (org.testcontainers:junit-jupiter:1.19.8 - https://java.testcontainers.org)
+ (MIT License) Testcontainers :: RabbitMQ (org.testcontainers:rabbitmq:1.19.8 - https://java.testcontainers.org)
+ (MIT License) Testcontainers Core (org.testcontainers:testcontainers:1.19.8 - https://java.testcontainers.org)
+ (BSD License) TwelveMonkeys :: ImageIO :: WebP plugin (com.twelvemonkeys.imageio:imageio-webp:3.11.0 - https://github.com/haraldk/TwelveMonkeys/tree/master/imageio/imageio-webp)
+ (Apache License, Version 2.0) WireMock (com.github.tomakehurst:wiremock-standalone:3.0.0 - https://wiremock.org)
+
+# NPM Dependencies and Licenses
+
+ (MIT) @adobe/css-tools@4.4.0
+ (Apache-2.0) @ampproject/remapping@2.3.0
+ (MIT) @ant-design/colors@7.1.0
+ (MIT) @ant-design/icons-svg@4.4.2
+ (MIT) @ant-design/icons@5.4.0
+ (MIT) @asamuzakjp/dom-selector@2.0.2
+ (MIT) @babel/code-frame@7.24.7
+ (MIT) @babel/compat-data@7.25.2
+ (MIT) @babel/core@7.25.2
+ (MIT) @babel/generator@7.25.0
+ (MIT) @babel/helper-compilation-targets@7.25.2
+ (MIT) @babel/helper-module-imports@7.24.7
+ (MIT) @babel/helper-module-transforms@7.25.2
+ (MIT) @babel/helper-plugin-utils@7.24.8
+ (MIT) @babel/helper-simple-access@7.24.7
+ (MIT) @babel/helper-string-parser@7.24.8
+ (MIT) @babel/helper-validator-identifier@7.24.7
+ (MIT) @babel/helper-validator-option@7.24.8
+ (MIT) @babel/helpers@7.25.0
+ (MIT) @babel/highlight@7.24.7
+ (MIT) @babel/parser@7.25.0
+ (MIT) @babel/plugin-transform-react-jsx-self@7.24.7
+ (MIT) @babel/plugin-transform-react-jsx-source@7.24.7
+ (MIT) @babel/runtime@7.25.0
+ (MIT) @babel/template@7.25.0
+ (MIT) @babel/traverse@7.25.2
+ (MIT) @babel/types@7.25.2
+ (MIT) @colors/colors@1.5.0
+ (MIT) @ctrl/tinycolor@3.6.1
+ (Apache-2.0) @cypress/request@3.0.1
+ (MIT) @cypress/xvfb@1.2.4
+ (MIT) @dnd-kit/accessibility@3.1.0
+ (MIT) @dnd-kit/core@6.1.0
+ (MIT) @dnd-kit/sortable@8.0.0
+ (MIT) @dnd-kit/utilities@3.2.2
+ (MIT) @emotion/babel-plugin@11.12.0
+ (MIT) @emotion/cache@11.13.1
+ (MIT) @emotion/hash@0.9.2
+ (MIT) @emotion/is-prop-valid@0.8.8
+ (MIT) @emotion/is-prop-valid@1.3.0
+ (MIT) @emotion/memoize@0.7.4
+ (MIT) @emotion/memoize@0.9.0
+ (MIT) @emotion/react@11.13.0
+ (MIT) @emotion/serialize@1.3.0
+ (MIT) @emotion/sheet@1.4.0
+ (MIT) @emotion/styled@11.13.0
+ (MIT) @emotion/unitless@0.9.0
+ (MIT) @emotion/use-insertion-effect-with-fallbacks@1.1.0
+ (MIT) @emotion/utils@1.4.0
+ (MIT) @emotion/weak-memoize@0.4.0
+ (MIT) @esbuild/darwin-arm64@0.19.12
+ (MIT) @eslint-community/eslint-utils@4.4.0
+ (MIT) @eslint-community/regexpp@4.11.0
+ (MIT) @eslint/eslintrc@2.1.4
+ (MIT) @eslint/js@8.57.0
+ (MIT) @floating-ui/core@1.6.5
+ (MIT) @floating-ui/dom@1.6.8
+ (MIT) @floating-ui/react-dom@2.1.1
+ (MIT) @floating-ui/utils@0.2.5
+ (MIT) @formatjs/ecma402-abstract@2.0.0
+ (MIT) @formatjs/fast-memoize@2.2.0
+ (MIT) @formatjs/icu-messageformat-parser@2.7.8
+ (MIT) @formatjs/icu-skeleton-parser@1.8.2
+ (MIT) @formatjs/intl-displaynames@6.6.8
+ (MIT) @formatjs/intl-listformat@7.5.7
+ (MIT) @formatjs/intl-localematcher@0.5.4
+ (MIT) @formatjs/intl@2.10.4
+ (MIT) @hookform/resolvers@3.9.0
+ (Apache-2.0) @humanwhocodes/config-array@0.11.14
+ (Apache-2.0) @humanwhocodes/module-importer@1.0.1
+ (BSD-3-Clause) @humanwhocodes/object-schema@2.0.3
+ (MIT) @jest/expect-utils@29.7.0
+ (MIT) @jest/schemas@29.6.3
+ (MIT) @jest/types@29.6.3
+ (MIT) @jridgewell/gen-mapping@0.3.5
+ (MIT) @jridgewell/resolve-uri@3.1.2
+ (MIT) @jridgewell/set-array@1.2.1
+ (MIT) @jridgewell/sourcemap-codec@1.5.0
+ (MIT) @jridgewell/trace-mapping@0.3.25
+ (MIT) @mui/base@5.0.0-beta.10
+ (MIT) @mui/base@5.0.0-beta.40
+ (MIT) @mui/base@5.0.0-beta.9
+ (MIT) @mui/core-downloads-tracker@5.16.5
+ (MIT) @mui/icons-material@5.14.3
+ (MIT) @mui/lab@5.0.0-alpha.139
+ (MIT) @mui/material@5.14.3
+ (MIT) @mui/private-theming@5.16.5
+ (MIT) @mui/styled-engine@5.16.4
+ (MIT) @mui/system@5.12.1
+ (MIT) @mui/system@5.16.5
+ (MIT) @mui/types@7.2.15
+ (MIT) @mui/utils@5.16.5
+ (MIT) @mui/x-data-grid@6.11.0
+ (MIT) @mui/x-date-pickers@6.16.1
+ (MIT) @nodelib/fs.scandir@2.1.5
+ (MIT) @nodelib/fs.stat@2.0.5
+ (MIT) @nodelib/fs.walk@1.2.8
+ (Apache-2.0) @opentelemetry/api-logs@0.50.0
+ (Apache-2.0) @opentelemetry/api@1.8.0
+ (Apache-2.0) @opentelemetry/auto-instrumentations-web@0.38.0
+ (Apache-2.0) @opentelemetry/context-zone-peer-dep@1.25.1
+ (Apache-2.0) @opentelemetry/context-zone@1.25.1
+ (Apache-2.0) @opentelemetry/core@1.23.0
+ (Apache-2.0) @opentelemetry/core@1.25.1
+ (Apache-2.0) @opentelemetry/exporter-zipkin@1.25.1
+ (Apache-2.0) @opentelemetry/instrumentation-document-load@0.37.0
+ (Apache-2.0) @opentelemetry/instrumentation-fetch@0.50.0
+ (Apache-2.0) @opentelemetry/instrumentation-user-interaction@0.37.0
+ (Apache-2.0) @opentelemetry/instrumentation-xml-http-request@0.50.0
+ (Apache-2.0) @opentelemetry/instrumentation@0.50.0
+ (Apache-2.0) @opentelemetry/propagator-b3@1.25.1
+ (Apache-2.0) @opentelemetry/resources@1.23.0
+ (Apache-2.0) @opentelemetry/resources@1.25.1
+ (Apache-2.0) @opentelemetry/sdk-trace-base@1.23.0
+ (Apache-2.0) @opentelemetry/sdk-trace-base@1.25.1
+ (Apache-2.0) @opentelemetry/sdk-trace-web@1.23.0
+ (Apache-2.0) @opentelemetry/sdk-trace-web@1.25.1
+ (Apache-2.0) @opentelemetry/semantic-conventions@1.23.0
+ (Apache-2.0) @opentelemetry/semantic-conventions@1.25.1
+ (MIT) @popperjs/core@2.11.8
+ (MIT) @reduxjs/toolkit@2.2.7
+ (MIT) @remirror/core-constants@2.0.2
+ (MIT) @remix-run/router@1.18.0
+ (MIT) @rollup/rollup-darwin-arm64@4.19.1
+ (MIT) @sinclair/typebox@0.27.8
+ (MIT) @socket.io/component-emitter@3.1.2
+ (MIT) @tabler/icons-react@2.47.0
+ (MIT) @tabler/icons@2.47.0
+ (MIT) @tanstack/query-core@4.36.1
+ (MIT) @tanstack/query-core@5.51.15
+ (MIT) @tanstack/react-query@4.36.1
+ (MIT) @tanstack/react-query@5.51.15
+ (MIT) @testing-library/dom@9.3.4
+ (MIT) @testing-library/jest-dom@5.17.0
+ (MIT) @testing-library/react@14.3.1
+ (MIT) @tiptap/core@2.5.7
+ (MIT) @tiptap/extension-blockquote@2.5.7
+ (MIT) @tiptap/extension-bold@2.5.7
+ (MIT) @tiptap/extension-bubble-menu@2.5.7
+ (MIT) @tiptap/extension-bullet-list@2.5.7
+ (MIT) @tiptap/extension-code-block@2.5.7
+ (MIT) @tiptap/extension-code@2.5.7
+ (MIT) @tiptap/extension-color@2.5.7
+ (MIT) @tiptap/extension-document@2.5.7
+ (MIT) @tiptap/extension-dropcursor@2.5.7
+ (MIT) @tiptap/extension-floating-menu@2.5.7
+ (MIT) @tiptap/extension-font-family@2.5.7
+ (MIT) @tiptap/extension-gapcursor@2.5.7
+ (MIT) @tiptap/extension-hard-break@2.5.7
+ (MIT) @tiptap/extension-heading@2.5.7
+ (MIT) @tiptap/extension-highlight@2.5.7
+ (MIT) @tiptap/extension-history@2.5.7
+ (MIT) @tiptap/extension-horizontal-rule@2.5.7
+ (MIT) @tiptap/extension-image@2.5.7
+ (MIT) @tiptap/extension-italic@2.5.7
+ (MIT) @tiptap/extension-link@2.5.7
+ (MIT) @tiptap/extension-list-item@2.5.7
+ (MIT) @tiptap/extension-ordered-list@2.5.7
+ (MIT) @tiptap/extension-paragraph@2.5.7
+ (MIT) @tiptap/extension-placeholder@2.5.7
+ (MIT) @tiptap/extension-strike@2.5.7
+ (MIT) @tiptap/extension-subscript@2.5.7
+ (MIT) @tiptap/extension-superscript@2.5.7
+ (MIT) @tiptap/extension-table-cell@2.5.7
+ (MIT) @tiptap/extension-table-header@2.5.7
+ (MIT) @tiptap/extension-table-row@2.5.7
+ (MIT) @tiptap/extension-table@2.5.7
+ (MIT) @tiptap/extension-task-item@2.5.7
+ (MIT) @tiptap/extension-task-list@2.5.7
+ (MIT) @tiptap/extension-text-align@2.5.7
+ (MIT) @tiptap/extension-text-style@2.5.7
+ (MIT) @tiptap/extension-text@2.5.7
+ (MIT) @tiptap/extension-underline@2.5.7
+ (MIT) @tiptap/pm@2.5.7
+ (MIT) @tiptap/react@2.5.7
+ (MIT) @tiptap/starter-kit@2.5.7
+ (MIT) @types/antlr4@4.11.6
+ (MIT) @types/aria-query@5.0.4
+ (MIT) @types/babel__core@7.20.5
+ (MIT) @types/babel__generator@7.6.8
+ (MIT) @types/babel__template@7.4.4
+ (MIT) @types/babel__traverse@7.20.6
+ (MIT) @types/estree@1.0.5
+ (MIT) @types/fhir@0.0.35
+ (MIT) @types/fhir@0.0.41
+ (MIT) @types/file-saver@2.0.7
+ (MIT) @types/hoist-non-react-statics@3.3.5
+ (MIT) @types/istanbul-lib-coverage@2.0.6
+ (MIT) @types/istanbul-lib-report@3.0.3
+ (MIT) @types/istanbul-reports@3.0.4
+ (MIT) @types/jest@29.5.12
+ (MIT) @types/json-schema@7.0.15
+ (MIT) @types/lodash-es@4.17.12
+ (MIT) @types/lodash@4.17.7
+ (MIT) @types/node@22.0.0
+ (MIT) @types/parse-json@4.0.2
+ (MIT) @types/prop-types@15.7.12
+ (MIT) @types/react-copy-to-clipboard@5.0.7
+ (MIT) @types/react-dom@18.3.0
+ (MIT) @types/react-gravatar@2.6.14
+ (MIT) @types/react-transition-group@4.4.10
+ (MIT) @types/react@18.3.3
+ (MIT) @types/semver@7.5.8
+ (MIT) @types/shimmer@1.2.0
+ (MIT) @types/sinonjs__fake-timers@8.1.1
+ (MIT) @types/sizzle@2.3.8
+ (MIT) @types/sockjs-client@1.5.4
+ (MIT) @types/stack-utils@2.0.3
+ (MIT) @types/stompjs@2.3.9
+ (MIT) @types/testing-library__jest-dom@5.14.9
+ (MIT) @types/use-sync-external-store@0.0.3
+ (MIT) @types/use-sync-external-store@0.0.6
+ (MIT) @types/uuid@8.3.4
+ (MIT) @types/yargs-parser@21.0.3
+ (MIT) @types/yargs@17.0.32
+ (MIT) @types/yauzl@2.10.3
+ (MIT) @typescript-eslint/eslint-plugin@5.62.0
+ (BSD-2-Clause) @typescript-eslint/parser@5.62.0
+ (MIT) @typescript-eslint/scope-manager@5.62.0
+ (MIT) @typescript-eslint/type-utils@5.62.0
+ (MIT) @typescript-eslint/types@5.62.0
+ (BSD-2-Clause) @typescript-eslint/typescript-estree@5.62.0
+ (MIT) @typescript-eslint/utils@5.62.0
+ (MIT) @typescript-eslint/visitor-keys@5.62.0
+ (ISC) @ungap/structured-clone@1.2.0
+ (MIT) @vitejs/plugin-basic-ssl@1.1.0
+ (MIT) @vitejs/plugin-react@4.3.1
+ (MIT) @vitest/expect@1.6.0
+ (MIT) @vitest/runner@1.6.0
+ (MIT) @vitest/snapshot@1.6.0
+ (MIT) @vitest/spy@1.6.0
+ (MIT) @vitest/utils@1.6.0
+ (ISC) abbrev@1.1.1
+ (MIT) acorn-import-assertions@1.9.0
+ (MIT) acorn-jsx@5.3.2
+ (MIT) acorn-walk@8.3.3
+ (MIT) acorn@8.12.1
+ (MIT) add-px-to-style@1.0.0
+ (MIT) agent-base@7.1.1
+ (MIT) aggregate-error@3.1.0
+ (MIT) ajv@6.12.6
+ (MIT) ansi-colors@4.1.3
+ (MIT) ansi-escapes@4.3.2
+ (MIT) ansi-regex@5.0.1
+ (MIT) ansi-styles@3.2.1
+ (MIT) ansi-styles@4.3.0
+ (MIT) ansi-styles@5.2.0
+ (BSD-3-Clause) antlr4@4.10.1
+ (MIT) arch@2.2.0
+ (Python-2.0) argparse@2.0.1
+ (Apache-2.0) aria-query@5.1.3
+ (Apache-2.0) aria-query@5.3.0
+ (MIT) array-buffer-byte-length@1.0.1
+ (MIT) array-find-index@1.0.2
+ (MIT) array-union@2.1.0
+ (MIT) asap@2.0.6
+ (MIT) asn1@0.2.6
+ (MIT) assert-plus@1.0.0
+ (MIT) assertion-error@1.1.0
+ (MIT) astral-regex@2.0.0
+ (MIT) async@3.2.5
+ (MIT) asynckit@0.4.0
+ (ISC) at-least-node@1.0.0
+ (MIT) attr-accept@2.2.2
+ (MIT) available-typed-arrays@1.0.7
+ (Apache-2.0) aws-sign2@0.7.0
+ (MIT) aws4@1.13.0
+ (MPL-2.0) axe-core@4.10.0
+ (MIT) axios@1.7.2
+ (MIT) babel-plugin-macros@3.1.0
+ (MIT) balanced-match@1.0.2
+ (MIT) base64-js@1.5.1
+ (BSD-3-Clause) bcrypt-pbkdf@1.0.2
+ (MIT) bidi-js@1.0.3
+ (MIT) big.js@6.2.1
+ (Apache-2.0) blob-util@2.0.2
+ (MIT) bluebird@3.7.2
+ (MIT) brace-expansion@1.1.11
+ (MIT) braces@3.0.3
+ (MIT) browserslist@4.23.2
+ (MIT) buffer-crc32@0.2.13
+ (MIT) buffer@5.7.1
+ (MIT) bufferutil@4.0.8
+ (MIT) cac@6.7.14
+ (MIT) cachedir@2.4.0
+ (MIT) call-bind@1.0.7
+ (MIT) callsites@3.1.0
+ (CC-BY-4.0) caniuse-lite@1.0.30001643
+ (Apache-2.0) caseless@0.12.0
+ (MIT) chai@4.5.0
+ (MIT) chalk@2.4.2
+ (MIT) chalk@3.0.0
+ (MIT) chalk@4.1.2
+ (BSD-3-Clause) charenc@0.0.2
+ (MIT) check-error@1.0.3
+ (MIT) check-more-types@2.24.0
+ (MIT) ci-info@3.9.0
+ (MIT) cjs-module-lexer@1.3.1
+ (MIT) classnames@2.5.1
+ (MIT) clean-stack@2.2.0
+ (MIT) cli-cursor@3.1.0
+ (MIT) cli-table3@0.6.5
+ (MIT) cli-truncate@2.1.0
+ (MIT) clsx@1.2.1
+ (MIT) clsx@2.1.1
+ (MIT) color-convert@1.9.3
+ (MIT) color-convert@2.0.1
+ (MIT) color-name@1.1.3
+ (MIT) color-name@1.1.4
+ (MIT) colorette@2.0.20
+ (MIT) combined-stream@1.0.8
+ (MIT) commander@6.2.1
+ (MIT) common-tags@1.8.2
+ (MIT) concat-map@0.0.1
+ (MIT) confbox@0.1.7
+ (MIT) convert-source-map@1.9.0
+ (MIT) convert-source-map@2.0.0
+ (MIT) copy-to-clipboard@3.3.3
+ (MIT) core-util-is@1.0.2
+ (MIT) cosmiconfig@7.1.0
+ (MIT) crelt@1.0.6
+ (MIT) cross-spawn@7.0.3
+ (BSD-3-Clause) crypt@0.0.2
+ (MIT) css-tree@2.3.1
+ (MIT) css.escape@1.5.1
+ (MIT) cssstyle@4.0.1
+ (MIT) csstype@3.1.3
+ (MIT) cypress-axe@1.5.0
+ (MIT) cypress-promise@1.1.0
+ (MIT) cypress@13.13.1
+ (ISC) d@1.0.2
+ (MIT) dashdash@1.14.1
+ (MIT) data-urls@5.0.0
+ (MIT) dayjs@1.11.12
+ (MIT) debug@2.6.9
+ (MIT) debug@3.2.7
+ (MIT) debug@4.3.6
+ (MIT) debuglog@1.0.1
+ (MIT) decimal.js@10.4.3
+ (MIT) deep-eql@4.1.4
+ (MIT) deep-equal@2.2.3
+ (MIT) deep-is@0.1.4
+ (MIT) define-data-property@1.1.4
+ (MIT) define-properties@1.2.1
+ (MIT) delayed-stream@1.0.0
+ (MIT) dequal@2.0.3
+ (ISC) dezalgo@1.0.4
+ (MIT) diff-sequences@29.6.3
+ (MIT) dir-glob@3.0.1
+ (Apache-2.0) doctrine@3.0.0
+ (MIT) dom-accessibility-api@0.5.16
+ (MIT) dom-css@2.1.0
+ (MIT) dom-helpers@5.2.1
+ (BSD-2-Clause) dotenv@16.4.5
+ (MIT) ecc-jsbn@0.1.2
+ (Apache-2.0) ecl-builder@0.2.1
+ (ISC) electron-to-chromium@1.5.3
+ (MIT) emoji-regex@8.0.0
+ (MIT) encodeurl@1.0.2
+ (MIT) end-of-stream@1.4.4
+ (MIT) engine.io-client@6.5.4
+ (MIT) engine.io-parser@5.2.3
+ (MIT) enquirer@2.4.1
+ (BSD-2-Clause) entities@4.5.0
+ (MIT) error-ex@1.3.2
+ (MIT) es-define-property@1.0.0
+ (MIT) es-errors@1.3.0
+ (MIT) es-get-iterator@1.1.3
+ (ISC) es5-ext@0.10.64
+ (MIT) es6-iterator@2.0.3
+ (ISC) es6-symbol@3.1.4
+ (MIT) esbuild@0.19.12
+ (MIT) escalade@3.1.2
+ (MIT) escape-string-regexp@1.0.5
+ (MIT) escape-string-regexp@2.0.0
+ (MIT) escape-string-regexp@4.0.0
+ (MIT) eslint-plugin-react-hooks@4.6.2
+ (MIT) eslint-plugin-react-refresh@0.4.9
+ (BSD-2-Clause) eslint-scope@5.1.1
+ (BSD-2-Clause) eslint-scope@7.2.2
+ (Apache-2.0) eslint-visitor-keys@3.4.3
+ (MIT) eslint@8.57.0
+ (ISC) esniff@2.0.1
+ (BSD-2-Clause) espree@9.6.1
+ (BSD-3-Clause) esquery@1.6.0
+ (BSD-2-Clause) esrecurse@4.3.0
+ (BSD-2-Clause) estraverse@4.3.0
+ (BSD-2-Clause) estraverse@5.3.0
+ (MIT) estree-walker@3.0.3
+ (BSD-2-Clause) esutils@2.0.3
+ (MIT) event-emitter@0.3.5
+ (MIT) eventemitter2@6.4.7
+ (MIT) eventsource@2.0.2
+ (MIT) execa@4.1.0
+ (MIT) execa@8.0.1
+ (MIT) executable@4.1.1
+ (MIT) expect@29.7.0
+ (ISC) ext@1.7.0
+ (MIT) extend@3.0.2
+ (BSD-2-Clause) extract-zip@2.0.1
+ (MIT) extsprintf@1.3.0
+ (MIT) fast-deep-equal@3.1.3
+ (MIT) fast-glob@3.3.2
+ (MIT) fast-json-stable-stringify@2.1.0
+ (MIT) fast-levenshtein@2.0.6
+ (ISC) fastq@1.17.1
+ (Apache-2.0) faye-websocket@0.11.4
+ (MIT) fd-slicer@1.1.0
+ (MIT) figures@3.2.0
+ (MIT) file-entry-cache@6.0.1
+ (MIT) file-saver@2.0.5
+ (MIT) file-selector@0.6.0
+ (MIT) fill-range@7.1.1
+ (MIT) find-root@1.1.0
+ (MIT) find-up@5.0.0
+ (MIT) flat-cache@3.2.0
+ (ISC) flatted@3.3.1
+ (MIT) follow-redirects@1.15.6
+ (MIT) for-each@0.3.3
+ (Apache-2.0) forever-agent@0.6.1
+ (MIT) form-data@2.3.3
+ (MIT) form-data@4.0.0
+ (MIT) framer-motion@10.18.0
+ (MIT) fs-extra@9.1.0
+ (ISC) fs.realpath@1.0.0
+ (MIT) fsevents@2.3.3
+ (MIT) function-bind@1.1.2
+ (MIT) functions-have-names@1.2.3
+ (MIT) gensync@1.0.0-beta.2
+ (MIT) get-func-name@2.0.2
+ (MIT) get-intrinsic@1.2.4
+ (MIT) get-stream@5.2.0
+ (MIT) get-stream@8.0.1
+ (MIT) getos@3.2.1
+ (MIT) getpass@0.1.7
+ (ISC) glob-parent@5.1.2
+ (ISC) glob-parent@6.0.2
+ (ISC) glob@7.2.3
+ (MIT) global-dirs@3.0.1
+ (MIT) globals@11.12.0
+ (MIT) globals@13.24.0
+ (MIT) globby@11.1.0
+ (MIT) goober@2.1.14
+ (MIT) gopd@1.0.1
+ (ISC) graceful-fs@4.2.11
+ (MIT) graphemer@1.4.0
+ (MIT) has-bigints@1.0.2
+ (MIT) has-flag@3.0.0
+ (MIT) has-flag@4.0.0
+ (MIT) has-property-descriptors@1.0.2
+ (MIT) has-proto@1.0.3
+ (MIT) has-symbols@1.0.3
+ (MIT) has-tostringtag@1.0.2
+ (MIT) hasown@2.0.2
+ (BSD-3-Clause) hoist-non-react-statics@3.3.2
+ (ISC) hosted-git-info@2.8.9
+ (MIT) html-encoding-sniffer@4.0.0
+ (MIT) http-parser-js@0.5.8
+ (MIT) http-proxy-agent@7.0.2
+ (MIT) http-signature@1.3.6
+ (MIT) https-proxy-agent@7.0.5
+ (Apache-2.0) human-signals@1.1.1
+ (Apache-2.0) human-signals@5.0.0
+ (MIT) iconv-lite@0.6.3
+ (BSD-3-Clause) ieee754@1.2.1
+ (MIT) ignore@5.3.1
+ (MIT) immer@10.1.1
+ (MIT) import-fresh@3.3.0
+ (Apache-2.0) import-in-the-middle@1.7.1
+ (MIT) imurmurhash@0.1.4
+ (MIT) indent-string@4.0.0
+ (ISC) inflight@1.0.6
+ (ISC) inherits@2.0.4
+ (ISC) ini@2.0.0
+ (MIT) internal-slot@1.0.7
+ (BSD-3-Clause) intl-messageformat@10.5.14
+ (MIT) is-arguments@1.1.1
+ (MIT) is-array-buffer@3.0.4
+ (MIT) is-arrayish@0.2.1
+ (MIT) is-bigint@1.0.4
+ (MIT) is-boolean-object@1.1.2
+ (MIT) is-buffer@1.1.6
+ (MIT) is-callable@1.2.7
+ (MIT) is-ci@3.0.1
+ (MIT) is-core-module@2.15.0
+ (MIT) is-date-object@1.0.5
+ (MIT) is-extglob@2.1.1
+ (MIT) is-fullwidth-code-point@3.0.0
+ (MIT) is-glob@4.0.3
+ (MIT) is-installed-globally@0.4.0
+ (MIT) is-map@2.0.3
+ (MIT) is-number-object@1.0.7
+ (MIT) is-number@7.0.0
+ (MIT) is-path-inside@3.0.3
+ (MIT) is-potential-custom-element-name@1.0.1
+ (MIT) is-regex@1.1.4
+ (MIT) is-retina@1.0.3
+ (MIT) is-set@2.0.3
+ (MIT) is-shared-array-buffer@1.0.3
+ (MIT) is-stream@2.0.1
+ (MIT) is-stream@3.0.0
+ (MIT) is-string@1.0.7
+ (MIT) is-symbol@1.0.4
+ (MIT) is-typedarray@1.0.0
+ (MIT) is-unicode-supported@0.1.0
+ (MIT) is-weakmap@2.0.2
+ (MIT) is-weakset@2.0.3
+ (MIT) isarray@2.0.5
+ (ISC) isexe@2.0.0
+ (MIT) isstream@0.1.2
+ (MIT) jest-diff@29.7.0
+ (MIT) jest-get-type@29.6.3
+ (MIT) jest-matcher-utils@29.7.0
+ (MIT) jest-message-util@29.7.0
+ (MIT) jest-util@29.7.0
+ (MIT) js-tokens@4.0.0
+ (MIT) js-tokens@9.0.0
+ (MIT) js-yaml@4.1.0
+ (MIT) jsbn@0.1.1
+ (MIT) jsdom@23.2.0
+ (MIT) jsesc@2.5.2
+ (MIT) json-buffer@3.0.1
+ (MIT) json-parse-even-better-errors@2.3.1
+ (MIT) json-schema-traverse@0.4.1
+ ((AFL-2.1 OR BSD-3-Clause)) json-schema@0.4.0
+ (MIT) json-stable-stringify-without-jsonify@1.0.1
+ (ISC) json-stringify-safe@5.0.1
+ (MIT) json5@2.2.3
+ (MIT) jsonfile@6.1.0
+ (MIT) jsprim@2.0.2
+ (MIT) keyv@4.5.4
+ (MIT) konva@9.3.14
+ (MIT) lazy-ass@1.6.0
+ (MIT) levn@0.4.1
+ (BSD-3-Clause) license-checker@25.0.1
+ (MIT) lines-and-columns@1.2.4
+ (MIT) linkify-it@5.0.0
+ (MIT) linkifyjs@4.1.3
+ (MIT) listr2@3.14.0
+ (MIT) local-pkg@0.5.0
+ (MIT) locate-path@6.0.0
+ (MIT) lodash-es@4.17.21
+ (MIT) lodash.merge@4.6.2
+ (MIT) lodash.once@4.1.1
+ (MIT) lodash@4.17.21
+ (MIT) log-symbols@4.1.0
+ (MIT) log-update@4.0.0
+ (MIT) loose-envify@1.4.0
+ (MIT) loupe@2.3.7
+ (ISC) lru-cache@5.1.1
+ (MIT) lz-string@1.5.0
+ (MIT) magic-string@0.30.11
+ (MIT) markdown-it@14.1.0
+ (BSD-3-Clause) md5@2.3.0
+ (CC0-1.0) mdn-data@2.0.30
+ (MIT) mdurl@2.0.0
+ (MIT) merge-stream@2.0.0
+ (MIT) merge2@1.4.1
+ (MIT) micromatch@4.0.7
+ (MIT) mime-db@1.52.0
+ (MIT) mime-types@2.1.35
+ (MIT) mimic-fn@2.1.0
+ (MIT) mimic-fn@4.0.0
+ (MIT) min-indent@1.0.1
+ (ISC) minimatch@3.1.2
+ (MIT) minimist@1.2.8
+ (MIT) mkdirp@0.5.6
+ (MIT) mlly@1.7.1
+ (MIT) module-details-from-path@1.0.3
+ (MIT) ms@2.0.0
+ (MIT) ms@2.1.2
+ (MIT) mui-tiptap@1.9.5
+ (MIT) nanoid@3.3.7
+ (MIT) nanoid@5.0.7
+ (MIT) natural-compare-lite@1.4.0
+ (MIT) natural-compare@1.4.0
+ (ISC) next-tick@1.1.0
+ (MIT) node-gyp-build@4.8.1
+ (MIT) node-releases@2.0.18
+ (ISC) nopt@4.0.3
+ (BSD-2-Clause) normalize-package-data@2.5.0
+ (MIT) notistack@3.0.1
+ (ISC) npm-normalize-package-bin@1.0.1
+ (MIT) npm-run-path@4.0.1
+ (MIT) npm-run-path@5.3.0
+ (MIT) object-assign@4.1.1
+ (MIT) object-inspect@1.13.2
+ (MIT) object-is@1.1.6
+ (MIT) object-keys@1.1.1
+ (MIT) object.assign@4.1.5
+ (ISC) once@1.4.0
+ (MIT) onetime@5.1.2
+ (MIT) onetime@6.0.0
+ (MIT) optionator@0.9.4
+ (MIT) orderedmap@2.1.1
+ (MIT) os-homedir@1.0.2
+ (MIT) os-tmpdir@1.0.2
+ (ISC) osenv@0.1.5
+ (MIT) ospath@1.2.2
+ (MIT) p-limit@3.1.0
+ (MIT) p-limit@5.0.0
+ (MIT) p-locate@5.0.0
+ (MIT) p-map@4.0.0
+ (MIT) parent-module@1.0.1
+ (MIT) parse-json@5.2.0
+ (MIT) parse5@7.1.2
+ (MIT) path-exists@4.0.0
+ (MIT) path-is-absolute@1.0.1
+ (MIT) path-key@3.1.1
+ (MIT) path-key@4.0.0
+ (MIT) path-parse@1.0.7
+ (MIT) path-type@4.0.0
+ (MIT) pathe@1.1.2
+ (MIT) pathval@1.1.1
+ (MIT) pend@1.2.0
+ (MIT) performance-now@2.1.0
+ (ISC) picocolors@1.0.1
+ (MIT) picomatch@2.3.1
+ (MIT) pify@2.3.0
+ (MIT) pkg-types@1.1.3
+ (MIT) possible-typed-array-names@1.0.0
+ (MIT) postcss@8.4.40
+ (MIT) prefix-style@2.0.1
+ (MIT) prelude-ls@1.2.1
+ (MIT) prettier@3.2.4
+ (MIT) pretty-bytes@5.6.0
+ (MIT) pretty-format@27.5.1
+ (MIT) pretty-format@29.7.0
+ (MIT) primeflex@3.3.1
+ (MIT) primereact@10.8.0
+ (MIT) process@0.11.10
+ (MIT) prop-types@15.8.1
+ (MIT) property-expr@2.0.6
+ (MIT) prosemirror-changeset@2.2.1
+ (MIT) prosemirror-collab@1.3.1
+ (MIT) prosemirror-commands@1.6.0
+ (MIT) prosemirror-dropcursor@1.8.1
+ (MIT) prosemirror-gapcursor@1.3.2
+ (MIT) prosemirror-history@1.4.1
+ (MIT) prosemirror-inputrules@1.4.0
+ (MIT) prosemirror-keymap@1.2.2
+ (MIT) prosemirror-markdown@1.13.0
+ (MIT) prosemirror-menu@1.2.4
+ (MIT) prosemirror-model@1.22.2
+ (MIT) prosemirror-schema-basic@1.2.3
+ (MIT) prosemirror-schema-list@1.4.1
+ (MIT) prosemirror-state@1.4.3
+ (MIT) prosemirror-tables@1.4.0
+ (MIT) prosemirror-trailing-node@2.0.9
+ (MIT) prosemirror-transform@1.9.0
+ (MIT) prosemirror-view@1.33.9
+ (MIT) proxy-from-env@1.0.0
+ (MIT) proxy-from-env@1.1.0
+ (MIT) psl@1.9.0
+ (MIT) pump@3.0.0
+ (MIT) punycode.js@2.3.1
+ (MIT) punycode@2.3.1
+ (BSD-3-Clause) qs@6.10.4
+ (MIT) query-string@4.3.4
+ (MIT) querystringify@2.2.0
+ (MIT) queue-microtask@1.2.3
+ (MIT) raf@3.4.1
+ (MIT) rc-util@5.43.0
+ (MIT) react-colorful@5.6.1
+ (MIT) react-copy-to-clipboard@5.1.0
+ (MIT) react-custom-scrollbars-2@4.5.0
+ (MIT) react-device-detect@2.2.3
+ (MIT) react-dom@18.3.1
+ (MIT) react-dropzone@14.2.3
+ (MIT) react-gravatar@2.6.3
+ (MIT) react-hook-form@7.49.2
+ (BSD-3-Clause) react-intl@6.6.8
+ (MIT) react-is@16.13.1
+ (MIT) react-is@17.0.2
+ (MIT) react-is@18.3.1
+ (MIT) react-redux@8.1.3
+ (MIT) react-refresh@0.14.2
+ (MIT) react-router-dom@6.25.1
+ (MIT) react-router@6.25.1
+ (BSD-3-Clause) react-transition-group@4.4.5
+ (MIT) react@18.3.1
+ (ISC) read-installed@4.0.3
+ (ISC) read-package-json@2.1.2
+ (ISC) readdir-scoped-modules@1.1.0
+ (MIT) redent@3.0.0
+ (MIT) redux-thunk@3.1.0
+ (MIT) redux@5.0.1
+ (MIT) regenerator-runtime@0.14.1
+ (MIT) regexp.prototype.flags@1.5.2
+ (MIT) request-progress@3.0.0
+ (MIT) require-from-string@2.0.2
+ (MIT) require-in-the-middle@7.4.0
+ (MIT) requires-port@1.0.0
+ (MIT) reselect@4.1.8
+ (MIT) reselect@5.1.1
+ (MIT) resolve-from@4.0.0
+ (MIT) resolve@1.22.8
+ (MIT) restore-cursor@3.1.0
+ (MIT) reusify@1.0.4
+ (MIT) rfdc@1.4.1
+ (ISC) rimraf@3.0.2
+ (MIT) rollup@4.19.1
+ (MIT) rope-sequence@1.3.4
+ (MIT) rrweb-cssom@0.6.0
+ (MIT) run-parallel@1.2.0
+ (Apache-2.0) rxjs@7.8.1
+ (MIT) safe-buffer@5.2.1
+ (MIT) safer-buffer@2.1.2
+ (ISC) saxes@6.0.0
+ (MIT) scheduler@0.23.2
+ (ISC) semver@5.7.2
+ (ISC) semver@6.3.1
+ (ISC) semver@7.6.3
+ (MIT) set-function-length@1.2.2
+ (MIT) set-function-name@2.0.2
+ (MIT) shebang-command@2.0.0
+ (MIT) shebang-regex@3.0.0
+ (BSD-2-Clause) shimmer@1.2.1
+ (MIT) side-channel@1.0.6
+ (ISC) siginfo@2.0.0
+ (ISC) signal-exit@3.0.7
+ (ISC) signal-exit@4.1.0
+ (MIT) simplebar-core@1.2.6
+ (MIT) simplebar-react@3.2.6
+ (MIT) slash@3.0.0
+ (MIT) slice-ansi@3.0.0
+ (MIT) slice-ansi@4.0.0
+ (ISC) slide@1.1.6
+ (MIT) socket.io-client@4.7.5
+ (MIT) socket.io-parser@4.2.4
+ (MIT) sockjs-client@1.6.1
+ (BSD-3-Clause) source-map-js@1.2.0
+ (BSD-3-Clause) source-map@0.5.7
+ (MIT) spdx-compare@1.0.0
+ (Apache-2.0) spdx-correct@3.2.0
+ (CC-BY-3.0) spdx-exceptions@2.5.0
+ (MIT) spdx-expression-parse@3.0.1
+ (CC0-1.0) spdx-license-ids@3.0.18
+ ((MIT AND CC-BY-3.0)) spdx-ranges@2.1.1
+ (MIT) spdx-satisfies@4.0.1
+ (MIT) sshpk@1.18.0
+ (MIT) stack-utils@2.0.6
+ (MIT) stackback@0.0.2
+ (MIT) std-env@3.7.0
+ (Apache-2.0) stompjs@2.3.3
+ (MIT) stop-iteration-iterator@1.0.0
+ (MIT) strict-uri-encode@1.1.0
+ (MIT) string-width@4.2.3
+ (MIT) strip-ansi@6.0.1
+ (MIT) strip-final-newline@2.0.0
+ (MIT) strip-final-newline@3.0.0
+ (MIT) strip-indent@3.0.0
+ (MIT) strip-json-comments@3.1.1
+ (MIT) strip-literal@2.1.0
+ (MIT) stylis@4.2.0
+ (MIT) supports-color@5.5.0
+ (MIT) supports-color@7.2.0
+ (MIT) supports-color@8.1.1
+ (MIT) supports-preserve-symlinks-flag@1.0.0
+ (MIT) symbol-tree@3.2.4
+ (MIT) text-table@0.2.0
+ (MIT) throttleit@1.0.1
+ (MIT) through@2.3.8
+ (MIT) tiny-case@1.0.3
+ (MIT) tinybench@2.8.0
+ (MIT) tinypool@0.8.4
+ (MIT) tinyspy@2.2.1
+ (MIT) tippy.js@6.3.7
+ (MIT) tmp@0.2.3
+ (MIT) to-camel-case@1.0.0
+ (MIT) to-fast-properties@2.0.0
+ (MIT) to-no-case@1.0.2
+ (MIT) to-regex-range@5.0.1
+ (MIT) to-space-case@1.0.0
+ (MIT) toggle-selection@1.0.6
+ (MIT) toposort@2.0.2
+ (BSD-3-Clause) tough-cookie@4.1.4
+ (MIT) tr46@5.0.0
+ (MIT) treeify@1.1.0
+ (0BSD) tslib@1.14.1
+ (0BSD) tslib@2.6.3
+ (MIT) tss-react@4.9.11
+ (MIT) tsutils@3.21.0
+ (Apache-2.0) tunnel-agent@0.6.0
+ (Unlicense) tweetnacl@0.14.5
+ (MIT) type-check@0.4.0
+ (MIT) type-detect@4.1.0
+ ((MIT OR CC0-1.0)) type-fest@0.20.2
+ ((MIT OR CC0-1.0)) type-fest@0.21.3
+ ((MIT OR CC0-1.0)) type-fest@2.19.0
+ ((MIT OR CC0-1.0)) type-fest@3.13.1
+ (ISC) type@2.7.3
+ (MIT) typedarray-to-buffer@3.1.5
+ (Apache-2.0) typescript@5.3.3
+ (MIT) ua-parser-js@1.0.38
+ (MIT) uc.micro@2.1.0
+ (MIT) ufo@1.5.4
+ (MIT) undici-types@6.11.1
+ (MIT) universalify@0.2.0
+ (MIT) universalify@2.0.1
+ (MIT) untildify@4.0.0
+ (MIT) update-browserslist-db@1.1.0
+ (BSD-2-Clause) uri-js@4.4.1
+ (MIT) url-parse@1.5.10
+ (MIT) use-sync-external-store@1.2.0
+ (MIT) use-sync-external-store@1.2.2
+ (MIT) utf-8-validate@5.0.10
+ (MIT) util-extend@1.0.3
+ (MIT) uuid@8.3.2
+ (Apache-2.0) validate-npm-package-license@3.0.4
+ (MIT) verror@1.10.0
+ (MIT) vite-node@1.6.0
+ (MIT) vite@5.1.5
+ (MIT) vitest@1.6.0
+ (MIT) w3c-keyname@2.2.8
+ (MIT) w3c-xmlserializer@5.0.0
+ (BSD-2-Clause) webidl-conversions@7.0.0
+ (Apache-2.0) websocket-driver@0.7.4
+ (Apache-2.0) websocket-extensions@0.1.4
+ (Apache-2.0) websocket@1.0.35
+ (MIT) whatwg-encoding@3.1.1
+ (MIT) whatwg-mimetype@4.0.0
+ (MIT) whatwg-url@14.0.0
+ (MIT) which-boxed-primitive@1.0.2
+ (MIT) which-collection@1.0.2
+ (MIT) which-typed-array@1.1.15
+ (ISC) which@2.0.2
+ (MIT) why-is-node-running@2.3.0
+ (MIT) word-wrap@1.2.5
+ (MIT) wrap-ansi@6.2.0
+ (MIT) wrap-ansi@7.0.0
+ (ISC) wrappy@1.0.2
+ (MIT) ws@8.17.1
+ (MIT) ws@8.18.0
+ (Apache-2.0) xml-name-validator@5.0.0
+ (MIT) xmlchars@2.2.0
+ (MIT) xmlhttprequest-ssl@2.0.0
+ (MIT) yaeti@0.0.6
+ (ISC) yallist@3.1.1
+ (ISC) yaml@1.10.2
+ (MIT) yauzl@2.10.0
+ (MIT) yocto-queue@0.1.0
+ (MIT) yocto-queue@1.1.1
+ (MIT) yup@1.4.0
+ (MIT) zone.js@0.14.8
+ (MIT) zustand@4.5.4
diff --git a/README.md b/README.md
index 2b8b0fd04..3787d6d4c 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,23 @@
-# Snomio
+# Lingo
+
[](https://ncts-cd.australiaeast.cloudapp.azure.com/applications/snomio-dev) [](https://ncts-cd.australiaeast.cloudapp.azure.com/applications/snomio-uat)
-An integration with Snomed International's Authoring Platform that extends functionality to improve authoring of medicinal terminology.
+An integration with Snomed International's Authoring Platform that extends functionality to improve
+authoring of medicinal terminology.
+
+# ⚠️ WARNING
+
+Over the next couple of months this repo will be undergoing UI changes using RJSF.
-To run this project
+If you intend on contributing, this is likely to affect you. Please get in touch and we can explain where we are up to and how to contribute.
-cookies for the .ihtsdotools domain are only shared one the same domain so you will need to
-add snomio.ihtsdotools.org & snomio-api.ihtsdotools.org to your /etc/hosts file
+## Getting Started
-The ECL Refset Tool UI requires an npm package published to a registry in the aehrc Azure DevOps organization.
-To install you will need to setup credentials in your user `.npmrc` file to
-[connect to the aehrc-npm feed](https://dev.azure.com/aehrc/ontoserver/_artifacts/feed/aehrc-npm/connect).
+To run this project you will need to follow some changes that are listed
+in [docs/CONFIGURATION.md](/docs/CONFIGURATION.md). If you do not follow the set up in
+CONFIGURATION.md, the following steps will not be able to run the application.
+
+After you have followed these steps, to run the application:
```
cd ui
@@ -20,17 +27,36 @@ cd api
mvn spring-boot:run
```
-To build you will need to pass ims-username and ims-password as VM arguments eg
+From there you navigate to `WHATEVER_YOU_SET.ihtsdotools.org` (as specified in CONFIGURATION.md above).
+
+To build you will need to pass ims-username and ims-password as VM arguments, for example:
```
mvn clean package -Dims-username=myusername -Dims-password=mypassword
```
+## Dependencies & Technologies
+
+For a list of the major dependencies and technologies please
+read [here](/docs/design/technologies.md).
+
+For a detailed list of dependencies please
+view [here](https://github.com/aehrc/snomio/network/dependencies).
+
## License
-This project uses the Apache License 2.0.
+Snomio is copyright © 2024 Australian Digital Health Agency, and is licensed under the Apache
+License, Version 2.0 (the "License");
+you may not use Snomio or the content of this repository except in compliance with the License.
+
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
-To read more on it see [LICENSE](./LICENSE)
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
## Contributing
@@ -40,143 +66,17 @@ See [contributing.md](./contributing.md) for ways to get started.
## Code of conduct
-Please adhere to this project's [code_of_conduct.md](./code_of_con:q!duct.md).
-
-
-```mermaid
-C4Context
- title System Context diagram for Snomio
-
- Enterprise_Boundary(ext, "Other") {
- System(hpp, "HPP")
- System(artg, "ARTG")
- }
-
- Enterprise_Boundary(csiro, "CSIRO") {
- Person(ta,"Terminology Analyst")
- Person(amt_ta,"AMT Terminology Analyst")
- System(sergio, "Sergio")
-
- SystemDb_Ext(snomiodb,"Ticket Database")
-
- System(snomio, "Snomio")
-
- BiRel(amt_ta, snomio, "")
- Rel(snomio, snomiodb, "")
- Rel(sergio, snomio, "")
- }
-
- Enterprise_Boundary(si, "SNOMED International") {
- System(ims, "Identity Management Service")
- System(cis, "Component Identifier Service")
- SystemDb(cisdb,"Identifier database")
- System(as, "Authoring Service")
- System(authoring, "Authoring Platform")
- System(snowstorm, "Snowstorm")
- SystemDb_Ext(elastic,"Elasticsearch")
- Rel(snowstorm, elastic, "")
- Rel(snowstorm, cis, "")
- Rel(authoring, snowstorm, "")
- Rel(authoring, as, "")
- Rel(as, snowstorm, "")
- Rel(cis, cisdb, "")
- }
-
-BiRel(ta, authoring, "")
-BiRel(amt_ta, authoring, "")
-Rel(snomio, ims, "")
-Rel(snomio, as, "")
-Rel(snomio, cis, "")
-Rel(sergio, ims, "")
-Rel(snomio, snowstorm, "")
-Rel(sergio, hpp, "")
-Rel(sergio, artg, "")
-
-UpdateLayoutConfig($c4ShapeInRow="6", $c4BoundaryInRow="1")
-```
-## Deployment environment for reference
-```mermaid
-C4Context
- title High level Snomio Deployment Environment
-
- Person(developer, "Developer", "NCTS Developer or DevOps person")
-
- System_Boundary(github, "GitHub repositories") {
- Container(snomioRepo, "Snomio Repository", "Source Code", "https://github.com/aehrc/snomio", $link="https://github.com/aehrc/snomio")
- Container(sergioRepo, "Sergio Repository", "Source Code", "https://github.com/aehrc/sergio")
- Container(nctsArgoRepo, "NCTS ArgoCD repository", "GitOps code", "https://github.com/aehrc/ncts-argo")
- Container_Boundary(nctsHelmRepo, "NCTS Helm source repository") {
- Container(nctsHelmRepoContainer, "Git repository", "Helm Charts", "https://github.com/aehrc/ncts-helm")
- Container(nctsHelmGitHubActions, "GitHub Actions", "Build/Deploy")
- }
- }
-
- System_Boundary(aci, "Azure Cloud Infrastructure") {
- Container(azuredevops, "Azure DevOps CI/CD Pipelines")
- Container(acr, "NCTS Azure Container Registry", "Docker images and Helm charts", "nctsacr.azurecr.io")
-
- Container_Boundary(nctsaks, "Azure Kubernetes Cluster") {
- Container_Boundary(snomiodevns, "Snomio DEV Namespace") {
- Container(snomiodev, "Snomio DEV", "https://dev-snomio.ihtsdotools.org/")
- Container(sergiodev, "Sergio DEV", "sergio-dev-service in k8s")
- }
- Container_Boundary(snomiouatns, "Snomio UAT Namespace") {
- Container(snomiouat, "Snomio UAT", "https://uat-snomio.ihtsdotools.org/")
- Container(sergiouat, "Sergio UAT", "sergio-uat-service in k8s")
- }
- Container_Boundary(argocdns, "ArgoCD Namespace") {
- Container(argoCD, "ArgoCD GitOps Tool")
- }
- }
- Container_Boundary(nctsprodaks, "Production Azure Kubernetes Cluster") {
- Container_Boundary(snomioprodns, "Snomio Prod Namespace") {
- Container(snomioprod, "Snomio Prod", "https://snomio.ihtsdotools.org/")
- Container(sergioprod, "Sergio Prod", "sergio-service in k8s")
- }
- }
- }
-
- Rel(developer, snomioRepo, "Pushes changes")
- Rel(developer, sergioRepo, "Pushes changes")
- Rel(developer, nctsArgoRepo, "Pushes changes")
- Rel(developer, nctsHelmRepoContainer, "Pushes changes")
-
- Rel(snomioRepo, azuredevops, "CI Build")
- Rel(sergioRepo, azuredevops, "CI Build")
- Rel(nctsHelmGitHubActions, acr, "Builds and Pushes Helm Charts")
-
- Rel(azuredevops, acr, "Builds and Pushes Images")
- Rel(azuredevops, nctsArgoRepo, "Updates Image References")
-
- Rel(acr, argoCD, "Pulls Released Helm Charts and Docker Images")
- Rel(nctsArgoRepo, argoCD, "Pulls Changes")
- Rel(nctsHelmRepoContainer, argoCD, "Pulls Helm Charts")
-
- Rel(argoCD, snomiodev, "Deploys Application")
- Rel(argoCD, sergiodev, "Deploys Application")
- Rel(argoCD, snomiouat, "Deploys Application")
- Rel(argoCD, sergiouat, "Deploys Application")
- Rel(argoCD, snomioprod, "Deploys Application")
- Rel(argoCD, sergioprod, "Deploys Application")
-
- UpdateElementStyle(snomioRepo, $bgColor="green", $borderColor="green")
- UpdateElementStyle(sergiodev, $bgColor="grey", $borderColor="gray")
- UpdateElementStyle(sergiouat, $bgColor="grey", $borderColor="gray")
- UpdateElementStyle(sergioprod, $bgColor="grey", $borderColor="gray")
- UpdateElementStyle(sergioRepo, $bgColor="grey", $borderColor="gray")
-
- UpdateRelStyle(developer, snomioRepo, "green", "red", "10", "-20")
- UpdateRelStyle(developer, nctsHelmRepoContainer, "green", "red", "25", "120")
- UpdateRelStyle(developer, nctsArgoRepo, "green", "red", "-80", "-40")
- UpdateRelStyle(nctsHelmRepoContainer, argoCD, "green", "red", "-140", "-40")
- UpdateRelStyle(acr, argoCD, "green", "red", "-140", "-340")
- UpdateRelStyle(nctsArgoRepo, argoCD, "green", "red", "-60", "40")
- UpdateRelStyle(snomioRepo, azuredevops, "green", "red", "-370", "20")
- UpdateRelStyle(sergioRepo, azuredevops, "", "", "-200", "20")
- UpdateRelStyle(nctsHelmGitHubActions, acr, "green", "red", "-170", "40")
- UpdateRelStyle(azuredevops, nctsArgoRepo, "green", "red", "-60", "20")
- UpdateRelStyle(argoCD, snomiodev, "green", "red", "-60", "20")
- UpdateRelStyle(argoCD, snomiouat, "green", "red", "-80", "20")
- UpdateRelStyle(argoCD, snomioprod, "green", "red", "-110", "20")
- UpdateRelStyle(azuredevops, acr, "green", "red", "10", "0")
-```
+Please adhere to this project's [code_of_conduct.md](./code_of_conduct.md).
+
+## Design
+
+For more information on the design of Lingo see the [design documentation](./docs/DESIGN.md).
+
+## Deployment and Configuration
+
+For more information on how to deploy and configure Lingo see
+the [deployment](./docs/DEPLOYMENT.md) and [configuration](./docs/CONFIGURATION.md) documentation.
+
+## User guide
+
+A basic [user guide](./docs/USERGUIDE.md) is available to orientate new users.
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 000000000..48587300c
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,23 @@
+# How to release an Snomio version
+
+This page contains the steps needed to produce and publish a Snomio release.
+
+## 1. Perform the release
+
+1. Clean check out the `main` branch
+2. Run `mvn gitflow:release-start` to start the release process, this will ask for a release version
+ and create a new branch for the release
+3. Update the CHANGELOG.md, replacing the `[Unreleased]` header with the new version number and date
+4. ~~Update the eclrefset project's snomio.auth.version property for the snapshot version~~
+5. Commit the changes
+7. Run `mvn gitflow:release-finish -DskipTestProject=true` to finish the release process, this will
+ 1. merge the release branch back into `main`
+ 2. tag the release in git
+8. ~~Update the eclrefset project's snomio.auth.version to the new POM version~~
+9. ~~Commit the changes to the eclrefet project~~
+
+*TODO - update the eclrefset project to be a module of the parent POM to avoid the need for steps 4,
+8, and 9*
+
+The above will trigger a build on the CI server for the tag which `gitflow:release-finish` will
+push. This will build, test and deploy a new image to the container registry.
\ No newline at end of file
diff --git a/active.txt b/active.txt
new file mode 100644
index 000000000..b5bae0396
--- /dev/null
+++ b/active.txt
@@ -0,0 +1,35 @@
+docs/Deployment
+bugfix/package-rename
+feature/environment-specific-logos
+fix-e2e-tests
+dependabot/npm_and_yarn/ui/main/tabler/icons-react-3.19.0
+dependabot/maven/eclrefset/org.springframework-spring-web-6.1.12
+dependabot/npm_and_yarn/utils/jira-ticket-export/rollup-3.29.5
+dependabot/npm_and_yarn/ui/main/jsdom-25.0.1
+dependabot/npm_and_yarn/utils/jira-ticket-export/multi-d66d039ac5
+dependabot/npm_and_yarn/utils/jira-ticket-export/multi-cf87d80143
+dependabot/npm_and_yarn/ui/vite-5.1.8
+new_import
+dependabot/npm_and_yarn/utils/jira-ticket-export/multi-9423f4c335
+bugfix/ticket-comments
+dependabot/npm_and_yarn/utils/jira-ticket-export/vite-4.5.5
+dependabot/maven/main/org.mapstruct-mapstruct-processor-1.6.2
+dependabot/maven/main/org.mapstruct-mapstruct-1.6.2
+fix-trivy-webmvc
+dependabot/npm_and_yarn/utils/jira-ticket-export/multi-ceff1a497b
+documentation
+dependabot/npm_and_yarn/utils/jira-ticket-export/micromatch-4.0.8
+dependabot/npm_and_yarn/ui/main/testing-library/jest-dom-6.5.0
+dependabot/npm_and_yarn/utils/jira-ticket-export/axios-1.7.4
+dependabot/maven/main/com.h2database-h2-2.3.232
+dependabot/npm_and_yarn/ui/main/mui/icons-material-5.16.7
+dependabot/maven/main/org.awaitility-awaitility-4.2.2
+ing-comp-pack-ordering
+dependabot/npm_and_yarn/utils/jira-ticket-export/braces-3.0.3
+feature/rabbit
+dependabot/npm_and_yarn/ui/main/react-redux-9.1.2
+ecl-refset-process-unexpected-processing-volume
+snodine
+fix-duplicate-TP-issue
+origin/HEAD -> origin/main
+main
diff --git a/api/.gitignore b/api/.gitignore
index 558560049..5e5934050 100644
--- a/api/.gitignore
+++ b/api/.gitignore
@@ -5,3 +5,4 @@ out
.idea
src/main/resources/static/*
application-custom.properties
+src/main/resources/application-local.properties
\ No newline at end of file
diff --git a/api/pom.xml b/api/pom.xml
index b8d3e95a4..0418c6b4a 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -1,11 +1,45 @@
+
api
-
+
+ build-helper-maven-plugin
+
+
+
+
+ target/generated-sources/java
+
+
+
+ add-source
+
+ generate-sources
+
+
+ org.codehaus.mojo
+ 3.6.0
+
fmt-maven-plugin
@@ -27,7 +61,6 @@
flyway-maven-plugin
org.flywaydb
- ${flyway-version}
jacoco-maven-plugin
@@ -82,7 +115,7 @@
jsonschema-maven-plugin
- com/csiro/**/models/**/*,au/csiro/**/model/*
+ au/gov/digitalhealth/**/models/**/*,au/csiro/**/model/*
WITH_ALL_DEPENDENCIES
false
@@ -113,13 +146,23 @@
${project.version}
- com.csiro.snomio.SnomioApplication
+ au.gov.digitalhealth.lingo.LingoApplication
8080
- eclipse-temurin:17
+ ${java.docker.image}
+
+
+ arm64
+ linux
+
+
+ amd64
+ linux
+
+
${docker.registry.host}/${docker.repository}
@@ -132,7 +175,7 @@
- dockerBuild
+ build
package
@@ -148,15 +191,35 @@
${argLine} -Dspring.profiles.active=test
+
+ license-maven-plugin
+
+ ${project.parent.basedir}/src/license/HEADER.txt
+
+ **/*.java
+ **/pom.xml
+
+
+
+
+
+ format
+
+ validate
+
+
+ com.mycila
+ 4.0.rc2
+
+
imgscalr-lib
org.imgscalr
4.2
-
-
+
metadata-extractor
com.drewnoakes
@@ -167,7 +230,7 @@
imageio-webp
com.twelvemonkeys.imageio
runtime
- 3.10.1
+ 3.11.0
@@ -194,15 +257,20 @@
org.aspectj
- io.micrometer
micrometer-registry-prometheus
+ io.micrometer
runtime
- io.opentelemetry.instrumentation
opentelemetry-instrumentation-annotations
- 2.3.0
+ io.opentelemetry.instrumentation
+ 2.6.0
+
+ io.sentry
+ sentry-spring-boot-starter-jakarta
+ ${sentry.version}
+
spring-boot-starter-actuator
org.springframework.boot
@@ -210,13 +278,18 @@
spring-boot-starter-hateoas
org.springframework.boot
- 3.2.5
+ 3.3.2
spring-boot-configuration-processor
org.springframework.boot
true
+
+ springdoc-openapi-starter-webmvc-ui
+ org.springdoc
+ 2.6.0
+
gson
com.google.code.gson
@@ -287,16 +360,21 @@
${rest-assured.version}
- com.squareup.okhttp3
okhttp
- 5.0.0-alpha.12
+ com.squareup.okhttp3
test
+ 5.0.0-alpha.12
- com.squareup.okhttp3
mockwebserver
- 5.0.0-alpha.12
+ com.squareup.okhttp3
test
+ 5.0.0-alpha.12
+
+
+ wiremock-standalone
+ com.github.tomakehurst
+ 3.0.0
postgresql
@@ -306,7 +384,10 @@
flyway-core
org.flywaydb
- ${flyway-version}
+
+
+ flyway-database-postgresql
+ org.flywaydb
jackson-datatype-jsr310
@@ -330,7 +411,7 @@
commons-validator
commons-validator
- 1.8.0
+ 1.9.0
spring-context
@@ -339,7 +420,7 @@
commons-csv
org.apache.commons
- 1.11.0
+ 1.12.0
commons-collections4
@@ -361,6 +442,11 @@
org.testcontainers
test
+
+ rabbitmq
+ org.testcontainers
+ test
+
jgrapht-core
org.jgrapht
@@ -387,34 +473,53 @@
${owlapi.version}
- snomio-common
- com.csiro
- ${snomio.common.version}
+ lingo-common
+ au.gov.digitalhealth
+
+
+ lingo-auth
+ au.gov.digitalhealth
- snomio-auth
- com.csiro
- ${snomio.auth.version}
+ sergio-extension
+ au.gov.digitalhealth
+
+
+ awaitility
+ org.awaitility
+ 4.2.2
+
+
+ mapstruct
+ org.mapstruct
+ 1.6.3
+
+
+ mapstruct-processor
+ org.mapstruct
+ provided
+ 1.5.5.Final
+
+
+ hibernate-jcache
+ org.hibernate
+ ${hibernate.version}
+
+
+ ehcache
+ org.ehcache
+ 3.10.8
-
-
-
- testcontainers-bom
- org.testcontainers
- import
- pom
- 1.19.3
-
-
-
- Api for snomio
+ Api for Lingo
4.0.0
- snomio api
+
+ lingo api
+
- snomio
- com.csiro
- 1.0.0-SNAPSHOT
+ lingo
+ au.gov.digitalhealth
+ 1.2.10.7-SNAPSHOT
@@ -449,26 +554,65 @@
${project.build.directory}/classes/static
+
+
+
+
+
+ aarch64
+
+
+
+
+
+ jib-maven-plugin
+
+
+ eclipse-temurin:17
+
+
+ arm64
+ linux
+
+
+
+
+
+
+
+ dockerBuild
+
+ package
+
+
+ com.google.cloud.tools
+ ${jib.version}
+
+
+
+ local
+
+
1.1.3
nctsacr.azurecr.io
snomio
- 9.22.3
- 2.22.1
- 2.2.224
- 0.8.11
+ 2.23
+ 2.3.232
+ 0.8.12
+ eclipse-temurin:17
17
3.1.0
1.5.2
- 3.4.0
- 4.34.0
- 3.4.1
+ 3.4.3
+ 4.36.0
+ 3.5.0
4.5.19
- 42.7.2
+ 42.7.3
0.23.0
5.1.0
- 5.0.0
- 8.1.1-SNAPSHOT
+ 5.4.0
+ 7.18.0
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/ExtensionChecker.java b/api/src/main/java/au/gov/digitalhealth/lingo/ExtensionChecker.java
new file mode 100644
index 000000000..1421ab827
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/ExtensionChecker.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo;
+
+import au.gov.digitalhealth.lingo.extension.LingoExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+@Component
+@Configuration
+@PropertySource(value = "classpath:application-extension.properties", ignoreResourceNotFound = true)
+@SuppressWarnings("java:S6813")
+public class ExtensionChecker implements ApplicationRunner {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExtensionChecker.class);
+
+ @Value("${snomio.extensions.sergio.enabled}")
+ boolean sergioEnabled;
+
+ // SonarLint no good here don't remove this
+ @Autowired private ApplicationContext applicationContext;
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ if (!sergioEnabled) {
+ logger.warn("Sergio extension is disabled.");
+ return;
+ }
+
+ String[] extensionBeanNames = applicationContext.getBeanNamesForType(LingoExtension.class);
+ if (extensionBeanNames.length > 0) {
+ logger.info("The following extensions have been found and will be initialised:");
+ for (String beanName : extensionBeanNames) {
+ LingoExtension extension = (LingoExtension) applicationContext.getBean(beanName);
+ logger.info(" - {}", beanName);
+ extension.initialise();
+ }
+ } else {
+ logger.warn("No extensions found.");
+ }
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/LingoApplication.java b/api/src/main/java/au/gov/digitalhealth/lingo/LingoApplication.java
new file mode 100644
index 000000000..070c6a4e8
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/LingoApplication.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo;
+
+import au.gov.digitalhealth.lingo.configuration.Configuration;
+import lombok.extern.java.Log;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@EnableTransactionManagement
+@EnableAspectJAutoProxy
+@Log
+public class LingoApplication extends Configuration {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LingoApplication.class, args);
+ }
+
+ @Bean
+ public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
+ return args -> {
+ log.finer("Beans");
+
+ String[] beansNames = ctx.getBeanDefinitionNames();
+ for (String beanName : beansNames) {
+ log.finer(beanName);
+ }
+ };
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTime.java b/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTime.java
new file mode 100644
index 000000000..d84a1bc42
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTime.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LogExecutionTime {}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTimeAspect.java b/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTimeAspect.java
new file mode 100644
index 000000000..f764383dc
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/aspect/LogExecutionTimeAspect.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.aspect;
+
+import au.gov.digitalhealth.lingo.auth.helper.AuthHelper;
+import java.util.Arrays;
+import java.util.logging.Level;
+import lombok.extern.java.Log;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+@Log
+@Aspect
+@Component
+public class LogExecutionTimeAspect {
+
+ final AuthHelper authHelper;
+
+ public LogExecutionTimeAspect(AuthHelper authHelper) {
+ this.authHelper = authHelper;
+ }
+
+ @Pointcut("@annotation(au.gov.digitalhealth.lingo.aspect.LogExecutionTime)")
+ public void callAt() {}
+
+ @Around("callAt()")
+ public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
+ long start = System.currentTimeMillis();
+
+ Object proceed = joinPoint.proceed();
+
+ long executionTime = System.currentTimeMillis() - start;
+
+ if (log.isLoggable(Level.FINE)) {
+ log.fine(
+ joinPoint.getSignature()
+ + " for user "
+ + authHelper.getImsUser().getLogin()
+ + " executed in "
+ + executionTime
+ + "ms");
+ log.fine("Parameters: " + Arrays.toString(joinPoint.getArgs()));
+ }
+ return proceed;
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUser.java b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUser.java
new file mode 100644
index 000000000..817bb36d2
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUser.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.auth;
+
+import java.util.HashMap;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+public class JiraUser {
+
+ private String name;
+
+ private String key;
+
+ private String emailAddress;
+
+ private String displayName;
+
+ private boolean active;
+
+ private HashMap avatarUrls;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserItems.java b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserItems.java
new file mode 100644
index 000000000..b2db26b2c
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserItems.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.auth;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+public class JiraUserItems {
+ private Integer size;
+
+ @JsonProperty("max-results")
+ private Integer maxResults;
+
+ @JsonProperty("start-index")
+ private Integer startIndex;
+
+ @JsonProperty("end-index")
+ private Integer endIndex;
+
+ private List items;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserResponse.java b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserResponse.java
new file mode 100644
index 000000000..c3f2c07fd
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/auth/JiraUserResponse.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.auth;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JiraUserResponse {
+ private String name;
+ private JiraUserItems users;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ApiWebConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ApiWebConfiguration.java
new file mode 100644
index 000000000..d27f74823
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ApiWebConfiguration.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import au.gov.digitalhealth.lingo.auth.helper.AuthHelper;
+import au.gov.digitalhealth.lingo.log.SnowstormLogger;
+import au.gov.digitalhealth.lingo.util.AuthSnowstormLogger;
+import io.netty.handler.logging.LogLevel;
+import lombok.extern.java.Log;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.transport.logging.AdvancedByteBufFormat;
+
+@Configuration
+@Log
+public class ApiWebConfiguration {
+
+ private final AuthHelper authHelper;
+
+ public ApiWebConfiguration(AuthHelper authHelper) {
+ this.authHelper = authHelper;
+ }
+
+ @Bean
+ public WebClient snowStormApiClient(
+ @Value("${ihtsdo.snowstorm.api.url}") String authoringServiceUrl,
+ WebClient.Builder webClientBuilder) {
+ HttpClient httpClient =
+ HttpClient.create()
+ .baseUrl(authoringServiceUrl)
+ .wiretap(
+ "reactor.netty.http.client.HttpClient",
+ LogLevel.DEBUG,
+ AdvancedByteBufFormat.TEXTUAL);
+ return webClientBuilder
+ .codecs(
+ clientCodecConfigurer ->
+ clientCodecConfigurer.defaultCodecs().maxInMemorySize(1024 * 1024 * 100))
+ .baseUrl(authoringServiceUrl)
+ .clientConnector(new ReactorClientHttpConnector(httpClient))
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .filter(authHelper.addImsAuthCookie) // Cookies are injected through filter
+ .build();
+ }
+
+ @Bean
+ public WebClient authoringPlatformApiClient(
+ @Value("${ihtsdo.ap.api.url}") String authoringServiceUrl,
+ WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(authoringServiceUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .filter(authHelper.addImsAuthCookie) // Cookies are injected through filter
+ .build();
+ }
+
+ @Bean
+ public WebClient nameGeneratorApiClient(
+ @Value("${name.generator.api.url}") String namegenApiUrl,
+ WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(namegenApiUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @Bean
+ public WebClient defaultAuthoringPlatformApiClient(
+ @Value("${ihtsdo.ap.api.url}") String authoringServiceUrl,
+ WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(authoringServiceUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .filter(authHelper.addDefaultAuthCookie) // Cookies are injected through filter
+ .build();
+ }
+
+ @Bean
+ public WebClient sergioApiClient(
+ @Value("${sergio.base.url}") String sergioUrl, WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(sergioUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .filter(authHelper.addDefaultAuthCookie)
+ .filter(logRequest())
+ .build();
+ }
+
+ private ExchangeFilterFunction logRequest() {
+ return ExchangeFilterFunction.ofRequestProcessor(
+ clientRequest -> {
+ log.info("Request: " + clientRequest.method() + " " + clientRequest.url());
+ clientRequest
+ .headers()
+ .forEach((name, values) -> values.forEach(value -> log.info(name + "=" + value)));
+ // Log cookies
+ clientRequest
+ .cookies()
+ .forEach(
+ (name, values) ->
+ values.forEach(value -> log.info("Cookie: " + name + "=" + value)));
+
+ return Mono.just(clientRequest);
+ });
+ }
+
+ @Bean
+ public WebClient otCollectorZipkinClient(
+ @Value("${snomio.telemetry.zipkinendpoint}") String zipkinEndpointUrl,
+ WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(zipkinEndpointUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @Bean
+ public WebClient otCollectorOTLPClient(
+ @Value("${snomio.telemetry.otelendpoint}") String otelEndpointUrl,
+ WebClient.Builder webClientBuilder) {
+ return webClientBuilder
+ .baseUrl(otelEndpointUrl)
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @Bean
+ public SnowstormLogger snowstormLogger(AuthSnowstormLogger authLogger) {
+ return authLogger;
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/CachingConfig.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/CachingConfig.java
new file mode 100644
index 000000000..17db14b82
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/CachingConfig.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import au.gov.digitalhealth.lingo.service.JiraUserManagerService;
+import au.gov.digitalhealth.lingo.service.SnowstormClient;
+import au.gov.digitalhealth.lingo.util.CacheConstants;
+import java.util.concurrent.TimeUnit;
+import lombok.extern.java.Log;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+@Configuration
+@EnableCaching
+@EnableScheduling
+@Log
+public class CachingConfig {
+
+ SnowstormClient snowstormClient;
+
+ JiraUserManagerService jiraUserManagerService;
+
+ @Value("${caching.spring.jiraUser.enabled}")
+ private boolean jiraUserCacheEnabled;
+
+ @Value("${ihtsdo.ap.codeSystem}")
+ String codeSystem;
+
+ CachingConfig(SnowstormClient snowstormClient, JiraUserManagerService jiraUserManagerService) {
+ this.snowstormClient = snowstormClient;
+ this.jiraUserManagerService = jiraUserManagerService;
+ }
+
+ @CacheEvict(value = CacheConstants.USERS_CACHE, allEntries = true)
+ @Scheduled(fixedRateString = "${caching.spring.usersTTL}")
+ public void emptyUsersCache() {
+ log.finer("emptying user cache");
+ }
+
+ @CacheEvict(value = CacheConstants.JIRA_USERS_CACHE, allEntries = true)
+ @Scheduled(fixedRateString = "${caching.spring.usersTTL}")
+ public void emptyJiraUsersCache() {
+ if (jiraUserCacheEnabled) {
+ log.finer("refreshing jira user cache");
+ try {
+ jiraUserManagerService.getAllJiraUsers();
+ } catch (Exception e) {
+ log.warning("Error refreshing jira user cache: " + e.getMessage());
+ }
+ }
+ }
+
+ @CacheEvict(value = CacheConstants.SNOWSTORM_STATUS_CACHE, allEntries = true)
+ @Scheduled(fixedRateString = "60000")
+ public void refreshSnowstormStatusCache() {
+ log.finer("Refresh snowstorm status cache");
+ try {
+ snowstormClient.getStatus(codeSystem);
+ } catch (Exception e) {
+ log.warning("Error refreshing snowstorm status cache: " + e.getMessage());
+ }
+ }
+
+ @CacheEvict(value = CacheConstants.AP_STATUS_CACHE, allEntries = true)
+ @Scheduled(fixedRateString = "60000")
+ public void refreshApStatusCache() {
+ log.finer("Refreshing ap status cache");
+ }
+
+ @CacheEvict(value = CacheConstants.ALL_TASKS_CACHE, allEntries = true)
+ @Scheduled(fixedRateString = "60000")
+ public void refreshAllTasksCache() {
+ log.finer("Refresh all Tasks cache");
+ }
+
+ @CacheEvict(value = CacheConstants.COMPOSITE_UNIT_CACHE)
+ @Scheduled(fixedRateString = "60", timeUnit = TimeUnit.MINUTES)
+ public void refreshCompositeUnitCache() {
+ log.finer("Refresh composite unit cache");
+ }
+
+ @CacheEvict(value = CacheConstants.UNIT_NUMERATOR_DENOMINATOR_CACHE)
+ @Scheduled(fixedRateString = "60", timeUnit = TimeUnit.MINUTES)
+ public void refreshUniNumeratorDenominatorCache() {
+ log.finer("Refresh unit numerator denominator cache");
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/Configuration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/Configuration.java
new file mode 100644
index 000000000..7db7d854f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/Configuration.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication(
+ scanBasePackages = {"au.gov.digitalhealth.lingo", "au.gov.digitalhealth.tickets"})
+@EnableConfigurationProperties
+@ConfigurationPropertiesScan(
+ basePackages = {"au.gov.digitalhealth.lingo", "au.gov.digitalhealth.tickets"})
+@EntityScan("au.gov.digitalhealth")
+@ComponentScan(basePackages = {"au.gov.digitalhealth.lingo", "au.gov.digitalhealth.tickets"})
+@EnableJpaRepositories(
+ basePackages = {"au.gov.digitalhealth.lingo", "au.gov.digitalhealth.tickets"})
+public abstract class Configuration {}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FhirConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FhirConfiguration.java
new file mode 100644
index 000000000..1f53e6c17
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FhirConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "fhir")
+@Getter
+@Setter
+@Validated
+public class FhirConfiguration {
+
+ @Value("${fhir.server.url}")
+ String fhirServerBaseUrl;
+
+ @Value("${fhir.extension}")
+ String fhirServerExtension;
+
+ @Value("${fhir.preferred-for-language.code}")
+ String fhirPreferredForLanguage;
+
+ @Value("${fhir.request-count}")
+ String fhirRequestCount;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FieldBindingConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FieldBindingConfiguration.java
new file mode 100644
index 000000000..666e6fd4b
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/FieldBindingConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import au.gov.digitalhealth.lingo.util.CacheConstants;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "snomio.field-bindings")
+@Getter
+@Setter
+@Validated
+public class FieldBindingConfiguration {
+ private static final String DEFAULT_BRANCH_KEY = "MAIN_SNOMEDCT-AU_AUAMT";
+ Map> mappers = new HashMap<>();
+
+ @Cacheable(cacheNames = CacheConstants.VALIDATION_EXCLUDED_SUBSTANCES)
+ public Set getExcludedSubstances() {
+ // will use default branch for now
+ Map resultMap =
+ mappers.getOrDefault(DEFAULT_BRANCH_KEY, mappers.entrySet().iterator().next().getValue());
+ String excludedItems = resultMap.getOrDefault("product.validation.exclude.substances", "");
+ return Arrays.stream(excludedItems.split(","))
+ .map(String::trim)
+ .filter(item -> !item.isEmpty())
+ .collect(Collectors.toSet());
+ }
+
+ @Cacheable(cacheNames = CacheConstants.BRAND_SEMANTIC_TAG)
+ public String getBrandSemanticTag() {
+ // will use default branch for now
+ Map resultMap =
+ mappers.getOrDefault(DEFAULT_BRANCH_KEY, mappers.entrySet().iterator().next().getValue());
+ return resultMap.getOrDefault("product.productName.semanticTag", "");
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/IhtsdoConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/IhtsdoConfiguration.java
new file mode 100644
index 000000000..27ebd5f90
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/IhtsdoConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "ihtsdo")
+@Getter
+@Setter
+@Validated
+public class IhtsdoConfiguration {
+
+ @Value("${ihtsdo.ims.api.url}")
+ String imsApiUrl;
+
+ @Value("${ihtsdo.ims.api.cookie.name}")
+ String imsApiCookieName;
+
+ @Value("${ihtsdo.ims.api.cookie.value}")
+ String imsApiCookieValue;
+
+ @Value("${ihtsdo.ap.api.url}")
+ String apApiUrl;
+
+ @Value("${ihtsdo.ap.projectkey}")
+ String apProjectKey;
+
+ @Value("${ihtsdo.ap.defaultBranch}")
+ String apDefaultBranch;
+
+ @Value("${ihtsdo.ap.snodine.defaultBranch}")
+ String apSnodineDefaultBranch;
+
+ @Value("${ihtsdo.ap.languageHeader}")
+ String apLanguageHeader;
+
+ @Value("${ihtsdo.base.api.url}")
+ String apApiBaseUrl;
+
+ @Value("${snomio.snodine.snowstorm.proxy}")
+ String snodineSnowstormProxy;
+
+ @Value("${snomio.snodine.extensionModules}")
+ List snodineExtensionModules;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ModellingConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ModellingConfiguration.java
new file mode 100644
index 000000000..a52ff573f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/ModellingConfiguration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import java.util.Set;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "snomio.modelling")
+@Getter
+@Setter
+@Validated
+public class ModellingConfiguration {
+ Set ungroupedRelationshipTypes =
+ Set.of(
+ 116680003L,
+ 784276002L,
+ 774159003L,
+ 766953001L,
+ 738774007L,
+ 736473005L,
+ 766939001L,
+ 733930001L,
+ 272741003L,
+ 736475003L,
+ 774081006L,
+ 736518005L,
+ 411116001L,
+ 766952006L,
+ 726542003L,
+ 766954007L,
+ 733932009L,
+ 774158006L,
+ 736474004L,
+ 736472000L,
+ 30394011000036104L,
+ 30465011000036106L,
+ 30523011000036108L,
+ 700000061000036106L,
+ 700000071000036103L,
+ 700000091000036104L,
+ 700000101000036108L,
+ 733933004L,
+ 763032000L,
+ 733928003L,
+ 733931002L,
+ 736476002L);
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/NamespaceConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/NamespaceConfiguration.java
new file mode 100644
index 000000000..2477c366d
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/NamespaceConfiguration.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Getter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "snomio.namespace")
+@Getter
+@Validated
+public class NamespaceConfiguration {
+ Map map = new HashMap<>();
+
+ public static String getConceptPartitionId(int namespace) {
+ String partitionId;
+ if (namespace == 0) {
+ partitionId = "00";
+ } else {
+ partitionId = "10";
+ }
+ return partitionId;
+ }
+
+ public Integer getNamespace(String key) {
+ return map.get(key);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/RequestLoggingFilterConfig.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/RequestLoggingFilterConfig.java
new file mode 100644
index 000000000..f7a69ca6f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/RequestLoggingFilterConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.filter.CommonsRequestLoggingFilter;
+
+@Configuration
+public class RequestLoggingFilterConfig {
+
+ @Bean
+ public CommonsRequestLoggingFilter logFilter() {
+ CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
+ filter.setIncludeQueryString(true);
+ filter.setIncludePayload(true);
+ filter.setMaxPayloadLength(100000000);
+ filter.setIncludeHeaders(false);
+ filter.setAfterMessagePrefix("REQUEST DATA: ");
+ return filter;
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SecureConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SecureConfiguration.java
new file mode 100644
index 000000000..25b511b71
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SecureConfiguration.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import lombok.Builder;
+import lombok.Value;
+
+@Value
+@Builder
+public class SecureConfiguration {
+
+ String sentryDsn;
+ String sentryEnvironment;
+ String sentryTracesSampleRate;
+ Boolean sentryEnabled;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SentryConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SentryConfiguration.java
new file mode 100644
index 000000000..2bfb7b6d2
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SentryConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "sentry")
+@Getter
+@Setter
+@Validated
+public class SentryConfiguration {
+
+ @Value("${sentry.dsn}")
+ private String sentryDsn;
+
+ @Value("${sentry.environment}")
+ private String sentryEnvironment;
+
+ @Value("${sentry.traces-sample-rate}")
+ private String sentryTracesSampleRate;
+
+ @Value("${sentry.enabled}")
+ private Boolean sentryEnabled;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SpaConfig.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SpaConfig.java
new file mode 100644
index 000000000..800de4f4c
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/SpaConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import java.io.IOException;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.resource.PathResourceResolver;
+
+@Configuration
+public class SpaConfig implements WebMvcConfigurer {
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+
+ // By setting this, you instruct Spring to prioritize this handler above the
+ // default one (which is order 0), obviously don't do this. But it's good to
+ // understand.
+ // -- registry.setOrder(-1);
+
+ // Handler for Swagger UI
+ registry
+ .addResourceHandler("/swagger-ui/**")
+ .addResourceLocations("classpath:/META-INF/resources/webjars/springdoc-openapi-ui/")
+ .resourceChain(true);
+
+ registry
+ // Capture everything (REST controllers get priority over this, see above)
+ .addResourceHandler("/**")
+ // Add locations where files might be found
+ .addResourceLocations("classpath:/static/**")
+ // Needed to allow use of `addResolver` below
+ .resourceChain(true)
+ // This thing is what does all the resolving. This impl. is responsible for
+ // resolving ALL files. Meaning nothing gets resolves automatically by pointing
+ // out "static" above.
+ .addResolver(
+ new PathResourceResolver() {
+ @Override
+ protected Resource getResource(String resourcePath, Resource location)
+ throws IOException {
+ Resource requestedResource = location.createRelative(resourcePath);
+
+ // If we actually hit a file, serve that. This is stuff like .js and .css files.
+ if (requestedResource.exists() && requestedResource.isReadable()) {
+ return requestedResource;
+ }
+
+ // Anything else returns the index.
+ return new ClassPathResource("/static/index.html");
+ }
+ });
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/configuration/UserInterfaceConfiguration.java b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/UserInterfaceConfiguration.java
new file mode 100644
index 000000000..81ba70d58
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/configuration/UserInterfaceConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.configuration;
+
+import java.util.List;
+import lombok.Builder;
+import lombok.Value;
+
+@Value
+@Builder
+public class UserInterfaceConfiguration {
+
+ String appName = "lingo";
+
+ String imsUrl;
+
+ String apUrl;
+
+ String apProjectKey;
+
+ String apDefaultBranch;
+
+ String apSnodineDefaultBranch;
+
+ String apLanguageHeader;
+
+ String apApiBaseUrl;
+
+ String fhirServerBaseUrl;
+
+ String fhirServerExtension;
+
+ String fhirPreferredForLanguage;
+
+ String fhirRequestCount;
+
+ String snodineSnowstormProxy;
+
+ List snodineExtensionModules;
+
+ String appEnvironment;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/AuthController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/AuthController.java
new file mode 100644
index 000000000..521e2968f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/AuthController.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.auth.helper.AuthHelper;
+import au.gov.digitalhealth.lingo.auth.model.ImsUser;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/api/auth",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class AuthController {
+
+ private final AuthHelper authHelper;
+
+ public AuthController(AuthHelper authHelper) {
+ this.authHelper = authHelper;
+ }
+
+ @GetMapping(value = "")
+ public ImsUser auth(HttpServletRequest request) {
+ return authHelper.getImsUser();
+ }
+
+ @PostMapping(value = "/logout")
+ public void logout(HttpServletRequest request, HttpServletResponse response) {
+ authHelper.cancelImsCookie(request, response);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ConfigController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ConfigController.java
new file mode 100644
index 000000000..d35b8bc5d
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ConfigController.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.configuration.FhirConfiguration;
+import au.gov.digitalhealth.lingo.configuration.IhtsdoConfiguration;
+import au.gov.digitalhealth.lingo.configuration.UserInterfaceConfiguration;
+import au.gov.digitalhealth.lingo.configuration.UserInterfaceConfiguration.UserInterfaceConfigurationBuilder;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/config",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class ConfigController {
+
+ private final IhtsdoConfiguration ihtsdoConfiguration;
+
+ private final FhirConfiguration fhirConfiguration;
+
+ @Value("${snomio.environment}")
+ private String appEnvironment;
+
+ public ConfigController(
+ IhtsdoConfiguration ihtsdoConfiguration, FhirConfiguration fhirConfiguration) {
+ this.ihtsdoConfiguration = ihtsdoConfiguration;
+ this.fhirConfiguration = fhirConfiguration;
+ }
+
+ @GetMapping(value = "")
+ public UserInterfaceConfiguration config(HttpServletRequest request) {
+ UserInterfaceConfigurationBuilder builder =
+ UserInterfaceConfiguration.builder()
+ .imsUrl(ihtsdoConfiguration.getImsApiUrl())
+ .apUrl(ihtsdoConfiguration.getApApiUrl())
+ .apProjectKey(ihtsdoConfiguration.getApProjectKey())
+ .apDefaultBranch(ihtsdoConfiguration.getApDefaultBranch())
+ .apSnodineDefaultBranch(ihtsdoConfiguration.getApSnodineDefaultBranch())
+ .apLanguageHeader(ihtsdoConfiguration.getApLanguageHeader())
+ .apApiBaseUrl(ihtsdoConfiguration.getApApiBaseUrl())
+ .fhirServerBaseUrl(fhirConfiguration.getFhirServerBaseUrl())
+ .fhirServerExtension(fhirConfiguration.getFhirServerExtension())
+ .fhirPreferredForLanguage(fhirConfiguration.getFhirPreferredForLanguage())
+ .fhirRequestCount(fhirConfiguration.getFhirRequestCount())
+ .snodineSnowstormProxy(ihtsdoConfiguration.getSnodineSnowstormProxy())
+ .snodineExtensionModules(ihtsdoConfiguration.getSnodineExtensionModules())
+ .appEnvironment(appEnvironment);
+
+ return builder.build();
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/DeviceController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/DeviceController.java
new file mode 100644
index 000000000..ab8b755a5
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/DeviceController.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.aspect.LogExecutionTime;
+import au.gov.digitalhealth.lingo.product.ProductCreationDetails;
+import au.gov.digitalhealth.lingo.product.ProductSummary;
+import au.gov.digitalhealth.lingo.product.details.DeviceProductDetails;
+import au.gov.digitalhealth.lingo.product.details.PackageDetails;
+import au.gov.digitalhealth.lingo.service.DeviceProductCalculationService;
+import au.gov.digitalhealth.lingo.service.DeviceService;
+import au.gov.digitalhealth.lingo.service.ProductCreationService;
+import au.gov.digitalhealth.lingo.service.TaskManagerService;
+import jakarta.validation.Valid;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/api",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class DeviceController {
+
+ private final DeviceService deviceService;
+ private final DeviceProductCalculationService deviceProductCalculationService;
+ private final TaskManagerService taskManagerService;
+ private final ProductCreationService productCreationService;
+
+ DeviceController(
+ DeviceService deviceService,
+ DeviceProductCalculationService deviceProductCalculationService,
+ TaskManagerService taskManagerService,
+ ProductCreationService productCreationService) {
+ this.deviceService = deviceService;
+ this.deviceProductCalculationService = deviceProductCalculationService;
+ this.taskManagerService = taskManagerService;
+ this.productCreationService = productCreationService;
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/devices/{productId}")
+ public PackageDetails getDevicePackageAtomioData(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return deviceService.getPackageAtomicData(branch, productId.toString());
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/devices/product/{productId}")
+ public DeviceProductDetails getDeviceProductAtomioData(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return deviceService.getProductAtomicData(branch, productId.toString());
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/devices/product")
+ public ResponseEntity createDeviceProductFromAtomioData(
+ @PathVariable String branch,
+ @RequestBody @Valid ProductCreationDetails<@Valid DeviceProductDetails> creationDetails)
+ throws InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ return new ResponseEntity<>(
+ productCreationService.createProductFromAtomicData(branch, creationDetails),
+ HttpStatus.CREATED);
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/devices/product/$calculate")
+ public ProductSummary calculateDeviceProductFromAtomioData(
+ @PathVariable String branch,
+ @RequestBody @Valid PackageDetails<@Valid DeviceProductDetails> productDetails) {
+ taskManagerService.validateTaskState(branch);
+ return deviceProductCalculationService.calculateProductFromAtomicData(branch, productDetails);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/JiraUserController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/JiraUserController.java
new file mode 100644
index 000000000..0c67cda1f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/JiraUserController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.auth.JiraUser;
+import au.gov.digitalhealth.lingo.service.JiraUserManagerService;
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/users")
+public class JiraUserController {
+
+ private final JiraUserManagerService jiraUserManagerService;
+
+ public JiraUserController(JiraUserManagerService jiraUserManagerService) {
+ this.jiraUserManagerService = jiraUserManagerService;
+ }
+
+ @GetMapping("")
+ public List getAllUsers(HttpServletRequest request) {
+ return jiraUserManagerService.getAllJiraUsers();
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/MedicationController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/MedicationController.java
new file mode 100644
index 000000000..7073aa959
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/MedicationController.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.aspect.LogExecutionTime;
+import au.gov.digitalhealth.lingo.configuration.FieldBindingConfiguration;
+import au.gov.digitalhealth.lingo.exception.MultipleFieldBindingsProblem;
+import au.gov.digitalhealth.lingo.exception.NoFieldBindingsProblem;
+import au.gov.digitalhealth.lingo.product.ProductBrands;
+import au.gov.digitalhealth.lingo.product.ProductCreationDetails;
+import au.gov.digitalhealth.lingo.product.ProductPackSizes;
+import au.gov.digitalhealth.lingo.product.ProductSummary;
+import au.gov.digitalhealth.lingo.product.bulk.BrandPackSizeCreationDetails;
+import au.gov.digitalhealth.lingo.product.bulk.BulkProductAction;
+import au.gov.digitalhealth.lingo.product.details.MedicationProductDetails;
+import au.gov.digitalhealth.lingo.product.details.PackageDetails;
+import au.gov.digitalhealth.lingo.service.BrandPackSizeService;
+import au.gov.digitalhealth.lingo.service.MedicationProductCalculationService;
+import au.gov.digitalhealth.lingo.service.MedicationService;
+import au.gov.digitalhealth.lingo.service.ProductCreationService;
+import au.gov.digitalhealth.lingo.service.TaskManagerService;
+import jakarta.validation.Valid;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/api",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class MedicationController {
+
+ private final MedicationService medicationService;
+ private final MedicationProductCalculationService medicationProductCalculationService;
+ private final TaskManagerService taskManagerService;
+ private final FieldBindingConfiguration fieldBindingConfiguration;
+ private final ProductCreationService productCreationService;
+ private final BrandPackSizeService brandPackSizeService;
+
+ MedicationController(
+ MedicationService medicationService,
+ MedicationProductCalculationService medicationProductCalculationService,
+ TaskManagerService taskManagerService,
+ FieldBindingConfiguration fieldBindingConfiguration,
+ ProductCreationService productCreationService,
+ BrandPackSizeService brandPackSizeService) {
+ this.medicationService = medicationService;
+ this.medicationProductCalculationService = medicationProductCalculationService;
+ this.fieldBindingConfiguration = fieldBindingConfiguration;
+ this.taskManagerService = taskManagerService;
+ this.productCreationService = productCreationService;
+ this.brandPackSizeService = brandPackSizeService;
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/medications/{productId}")
+ public PackageDetails getMedicationPackageAtomicData(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return medicationService.getPackageAtomicData(branch, productId.toString());
+ }
+
+ /**
+ * Finds the other pack sizes for a given product.
+ *
+ * @param branch The branch to search in.
+ * @param productId The product ID to search for.
+ * @return The other pack sizes for the given product.
+ */
+ @LogExecutionTime
+ @GetMapping("/{branch}/medications/{productId}/pack-sizes")
+ public ProductPackSizes getMedicationProductPackSizes(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return medicationService.getProductPackSizes(branch, productId);
+ }
+
+ /**
+ * Finds the brands for a given product.
+ *
+ * @param branch The branch to search in.
+ * @param productId The product ID to search for.
+ * @return The brands for the given product.
+ */
+ @LogExecutionTime
+ @GetMapping("/{branch}/medications/{productId}/brands")
+ public ProductBrands getMedicationProductBrands(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return medicationService.getProductBrands(branch, productId);
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/medications/product/{productId}")
+ public MedicationProductDetails getMedicationProductAtomioData(
+ @PathVariable String branch, @PathVariable Long productId) {
+ return medicationService.getProductAtomicData(branch, productId.toString());
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/medications/field-bindings")
+ public Map getMedicationAtomioDataFieldBindings(@PathVariable String branch) {
+ String branchKey = branch.replace("|", "_");
+
+ Set keys =
+ fieldBindingConfiguration.getMappers().keySet().stream()
+ .filter(branchKey::startsWith)
+ .collect(Collectors.toSet());
+
+ if (keys.isEmpty()) {
+ throw new NoFieldBindingsProblem(branchKey, fieldBindingConfiguration.getMappers().keySet());
+ } else if (keys.size() > 1) {
+ throw new MultipleFieldBindingsProblem(branchKey, keys);
+ }
+
+ return fieldBindingConfiguration.getMappers().get(keys.iterator().next());
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/medications/product")
+ public ResponseEntity createMedicationProductFromAtomioData(
+ @PathVariable String branch,
+ @RequestBody @Valid
+ ProductCreationDetails<@Valid MedicationProductDetails> productCreationDetails)
+ throws InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ return new ResponseEntity<>(
+ productCreationService.createProductFromAtomicData(branch, productCreationDetails),
+ HttpStatus.CREATED);
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/medications/product/new-brand-pack-sizes")
+ public ResponseEntity createProductFromBrandPackSizeCreationDetails(
+ @PathVariable String branch,
+ @RequestBody @Valid BulkProductAction creationDetails)
+ throws InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ return new ResponseEntity<>(
+ productCreationService.createProductFromBrandPackSizeCreationDetails(
+ branch, creationDetails),
+ HttpStatus.CREATED);
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/medications/product/$calculate")
+ public ProductSummary calculateMedicationProductFromAtomicData(
+ @PathVariable String branch,
+ @RequestBody @Valid PackageDetails<@Valid MedicationProductDetails> productDetails)
+ throws ExecutionException, InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ return medicationProductCalculationService.calculateProductFromAtomicData(
+ branch, productDetails);
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/medications/product/$calculateNewBrandPackSizes")
+ public ProductSummary calculateNewBrandPackSizeMedicationProducts(
+ @PathVariable String branch,
+ @RequestBody @Valid BrandPackSizeCreationDetails brandPackSizeCreationDetails) {
+ taskManagerService.validateTaskState(branch);
+ return brandPackSizeService.calculateNewBrandPackSizes(branch, brandPackSizeCreationDetails);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ProductsController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ProductsController.java
new file mode 100644
index 000000000..267985eb9
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/ProductsController.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.csiro.snowstorm_client.model.SnowstormTermLangPojo;
+import au.gov.digitalhealth.lingo.aspect.LogExecutionTime;
+import au.gov.digitalhealth.lingo.product.Edge;
+import au.gov.digitalhealth.lingo.product.Node;
+import au.gov.digitalhealth.lingo.product.ProductSummary;
+import au.gov.digitalhealth.lingo.product.details.ExternalIdentifier;
+import au.gov.digitalhealth.lingo.product.update.ProductUpdateRequest;
+import au.gov.digitalhealth.lingo.service.ProductSummaryService;
+import au.gov.digitalhealth.lingo.service.ProductUpdateService;
+import au.gov.digitalhealth.lingo.service.TaskManagerService;
+import au.gov.digitalhealth.tickets.models.BulkProductAction;
+import jakarta.validation.Valid;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import lombok.extern.java.Log;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(
+ value = "/api",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+@Log
+public class ProductsController {
+
+ final ProductSummaryService productService;
+ final TaskManagerService taskManagerService;
+ final ProductUpdateService productUpdateService;
+
+ public ProductsController(
+ ProductSummaryService productService,
+ TaskManagerService taskManagerService,
+ ProductUpdateService productUpdateService) {
+ this.productService = productService;
+ this.taskManagerService = taskManagerService;
+ this.productUpdateService = productUpdateService;
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/product-model/{productId}")
+ public ProductSummary getProductModel(@PathVariable String branch, @PathVariable Long productId) {
+ return productService.getProductSummary(branch, productId.toString());
+ }
+
+ @LogExecutionTime
+ @PutMapping("/{branch}/product-model/{productId}/update")
+ public ResponseEntity updateProductDescriptions(
+ @PathVariable String branch,
+ @PathVariable Long productId,
+ @RequestBody @Valid ProductUpdateRequest productUpdateRequest)
+ throws InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ BulkProductAction response =
+ productUpdateService.updateProduct(branch, String.valueOf(productId), productUpdateRequest);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/product-model/{productId}/externalIdentifiers")
+ public ResponseEntity> getExternalIdentifiers(
+ @PathVariable String branch, @PathVariable Long productId) throws InterruptedException {
+ Set externalIdentifiers =
+ productUpdateService.getExternalIdentifiers(branch, String.valueOf(productId));
+ return new ResponseEntity<>(externalIdentifiers, HttpStatus.OK);
+ }
+
+ @LogExecutionTime
+ @GetMapping("/{branch}/product-model-graph/{productId}")
+ public String getProductModelGraph(@PathVariable String branch, @PathVariable Long productId) {
+
+ ProductSummary summary = productService.getProductSummary(branch, productId.toString());
+
+ Map> nodesByType = new HashMap<>();
+
+ summary
+ .getNodes()
+ .forEach(
+ node -> nodesByType.computeIfAbsent(node.getLabel(), k -> new HashSet<>()).add(node));
+
+ StringBuilder graph = new StringBuilder();
+ graph.append("digraph G {\n rankdir=\"BT\"\n");
+ for (Entry> entry : nodesByType.entrySet()) {
+ graph.append(" subgraph cluster_").append(entry.getKey()).append(" {\n");
+ graph.append(" label = \"").append(entry.getKey()).append("\";\n");
+ for (Node node : entry.getValue()) {
+ SnowstormTermLangPojo pt = node.getConcept().getPt();
+ if (pt != null) {
+ graph
+ .append(" ")
+ .append(node.getConcept().getConceptId())
+ .append(" [label=\"")
+ .append(pt.getTerm())
+ .append("\"];\n");
+ }
+ }
+ graph.append(" }\n");
+ }
+ for (Edge edge : summary.getEdges()) {
+ graph
+ .append(" ")
+ .append(edge.getSource())
+ .append(" -> ")
+ .append(edge.getTarget())
+ .append(" [label=\"")
+ .append(edge.getLabel())
+ .append("\" ")
+ .append(
+ edge.getLabel().equals(ProductSummaryService.IS_A_LABEL)
+ ? "arrowhead=empty"
+ : "style=dashed arrowhead=open")
+ .append("];\n");
+ }
+ return graph.append("}").toString();
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/QualifierController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/QualifierController.java
new file mode 100644
index 000000000..03641c2b2
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/QualifierController.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.csiro.snowstorm_client.model.SnowstormConceptMini;
+import au.gov.digitalhealth.lingo.aspect.LogExecutionTime;
+import au.gov.digitalhealth.lingo.product.BrandCreationRequest;
+import au.gov.digitalhealth.lingo.service.ProductCreationService;
+import au.gov.digitalhealth.lingo.service.TaskManagerService;
+import jakarta.validation.Valid;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(
+ value = "/api",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class QualifierController {
+
+ private final TaskManagerService taskManagerService;
+ private final ProductCreationService productCreationService;
+
+ QualifierController(
+ TaskManagerService taskManagerService, ProductCreationService productCreationService) {
+ this.taskManagerService = taskManagerService;
+ this.productCreationService = productCreationService;
+ }
+
+ @LogExecutionTime
+ @PostMapping("/{branch}/qualifier/product-name")
+ public ResponseEntity createBrand(
+ @PathVariable String branch, @RequestBody @Valid BrandCreationRequest brandCreationRequest)
+ throws InterruptedException {
+ taskManagerService.validateTaskState(branch);
+ return new ResponseEntity<>(
+ productCreationService.createBrand(branch, brandCreationRequest), HttpStatus.CREATED);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/SecureConfigController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/SecureConfigController.java
new file mode 100644
index 000000000..1c67cc94f
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/SecureConfigController.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.configuration.SecureConfiguration;
+import au.gov.digitalhealth.lingo.configuration.SentryConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/api/config",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class SecureConfigController {
+
+ private final SentryConfiguration sentryConfiguration;
+
+ public SecureConfigController(SentryConfiguration sentryConfiguration) {
+ this.sentryConfiguration = sentryConfiguration;
+ }
+
+ @GetMapping(value = "")
+ public SecureConfiguration getConfig() {
+ SecureConfiguration.SecureConfigurationBuilder builder =
+ SecureConfiguration.builder()
+ .sentryDsn(sentryConfiguration.getSentryDsn())
+ .sentryEnabled(sentryConfiguration.getSentryEnabled())
+ .sentryEnvironment(sentryConfiguration.getSentryEnvironment())
+ .sentryTracesSampleRate(sentryConfiguration.getSentryTracesSampleRate());
+ return builder.build();
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/StatusController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/StatusController.java
new file mode 100644
index 000000000..ae0e554a4
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/StatusController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.service.ServiceStatus;
+import au.gov.digitalhealth.lingo.service.ServiceStatus.SnowstormStatus;
+import au.gov.digitalhealth.lingo.service.ServiceStatus.Status;
+import au.gov.digitalhealth.lingo.service.SnowstormClient;
+import au.gov.digitalhealth.lingo.service.TaskManagerClient;
+import au.gov.digitalhealth.lingo.service.identifier.IdentifierSource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(
+ value = "/api/status",
+ produces = {MediaType.APPLICATION_JSON_VALUE})
+public class StatusController {
+
+ TaskManagerClient taskManagerClient;
+ SnowstormClient snowstormClient;
+ IdentifierSource identifierSource;
+
+ @Value("${ihtsdo.ap.codeSystem}")
+ String codeSystem;
+
+ StatusController(
+ TaskManagerClient taskManagerClient,
+ SnowstormClient snowstormClient,
+ IdentifierSource identifierSource) {
+ this.taskManagerClient = taskManagerClient;
+ this.snowstormClient = snowstormClient;
+ this.identifierSource = identifierSource;
+ }
+
+ @GetMapping(value = "")
+ public ServiceStatus status(HttpServletRequest request, HttpServletResponse response) {
+ Status apStatus = taskManagerClient.getStatus();
+ SnowstormStatus snowstormStatus = snowstormClient.getStatus(codeSystem);
+ Status cisStatus = identifierSource.getStatus();
+
+ return ServiceStatus.builder()
+ .authoringPlatform(apStatus)
+ .snowstorm(snowstormStatus)
+ .cis(cisStatus)
+ .build();
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TasksController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TasksController.java
new file mode 100644
index 000000000..397673c87
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TasksController.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.lingo.service.TaskManagerClient;
+import au.gov.digitalhealth.lingo.util.Task;
+import com.google.gson.JsonArray;
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/tasks")
+public class TasksController {
+
+ private final TaskManagerClient taskManagerClient;
+
+ public TasksController(TaskManagerClient taskManagerClient) {
+ this.taskManagerClient = taskManagerClient;
+ }
+
+ @GetMapping("")
+ public List tasks(HttpServletRequest request) {
+ return taskManagerClient.getAllTasks();
+ }
+
+ @GetMapping("/myTasks")
+ public JsonArray myTasks(HttpServletRequest request) {
+ return taskManagerClient.getUserTasks();
+ }
+
+ @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity createTask(@RequestBody Task task) {
+ Task createdTask = taskManagerClient.createTask(task);
+ return new ResponseEntity<>(createdTask, HttpStatus.OK);
+ }
+}
diff --git a/api/src/main/java/com/csiro/snomio/controllers/TelemetryController.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TelemetryController.java
similarity index 89%
rename from api/src/main/java/com/csiro/snomio/controllers/TelemetryController.java
rename to api/src/main/java/au/gov/digitalhealth/lingo/controllers/TelemetryController.java
index 9260c1257..219d21e1f 100644
--- a/api/src/main/java/com/csiro/snomio/controllers/TelemetryController.java
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TelemetryController.java
@@ -1,7 +1,22 @@
-package com.csiro.snomio.controllers;
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
-import com.csiro.snomio.auth.model.ImsUser;
-import com.csiro.snomio.exception.TelemetryProblem;
+import au.gov.digitalhealth.lingo.auth.model.ImsUser;
+import au.gov.digitalhealth.lingo.exception.TelemetryProblem;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -23,6 +38,7 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
@@ -41,11 +57,10 @@ public class TelemetryController {
public static final String SERVICE_NAME = "serviceName";
public static final String SERVICE_DOT_NAME = "service.name";
public static final String RESOURCE_SPANS = "resourceSpans";
+ private final ObjectMapper objectMapper = new ObjectMapper();
WebClient zipkinClient;
WebClient otlpClient;
- private final ObjectMapper objectMapper = new ObjectMapper();
-
@Value("${snomio.telemetry.otelendpoint}")
private String otelExporterEndpoint;
@@ -79,7 +94,7 @@ public Mono forwardTelemetry(
user = Base64.getEncoder().encodeToString(imsUser.getLogin().getBytes());
} else {
user = principal.toString();
- log.info("Principal is: " + principal.toString());
+ log.info("Principal is: " + principal);
}
try {
@@ -123,6 +138,12 @@ private Mono sendTelemetryData(String finalData, WebClient webClient, Http
return Mono.empty();
}
return Mono.error(e); // Propagate other errors
+ })
+ .onErrorResume(
+ WebClientRequestException.class,
+ e -> {
+ log.severe("Collector error when forwarding telemetry data. " + e.getMessage());
+ return Mono.empty();
});
}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TicketFiltersDto.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TicketFiltersDto.java
new file mode 100644
index 000000000..f6f399682
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/TicketFiltersDto.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import au.gov.digitalhealth.tickets.helper.SearchConditionBody;
+import jakarta.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.time.Instant;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+public class TicketFiltersDto implements Serializable {
+
+ private Long id;
+ private Integer version;
+ private Instant created;
+ private String createdBy;
+ private Instant modified;
+ private String modifiedBy;
+ @NotNull private String name;
+ @NotNull private SearchConditionBody filter;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/UiSearchConfigurationDto.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/UiSearchConfigurationDto.java
new file mode 100644
index 000000000..fea1f3c31
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/UiSearchConfigurationDto.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers;
+
+import jakarta.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.time.Instant;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/** DTO for {@link UiSearchConfiguration} */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+public class UiSearchConfigurationDto implements Serializable {
+
+ private Long id;
+ private Integer version;
+ private Instant created;
+ private String createdBy;
+ private Instant modified;
+ private String modifiedBy;
+ @NotNull private String username;
+ private TicketFiltersDto filter;
+ private int grouping;
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/controllers/swagger/OpenAPIConfig.java b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/swagger/OpenAPIConfig.java
new file mode 100644
index 000000000..cad6052bc
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/controllers/swagger/OpenAPIConfig.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.controllers.swagger;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.servers.Server;
+import java.util.ArrayList;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OpenAPIConfig {
+
+ @Value("${snomio.base.url:/}")
+ public String baseUrl;
+
+ @Bean
+ public OpenAPI customOpenAPI() {
+
+ List servers = new ArrayList<>();
+ servers.add(new Server().url(baseUrl).description("Default server url"));
+
+ return new OpenAPI()
+ .info(
+ new Info()
+ .title("Lingo")
+ .version("1.0")
+ .description(
+ "An application that allows authoring of medicinal products through the IHTSDO Authoring Platform."))
+ .servers(servers);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/CISClientProblem.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/CISClientProblem.java
new file mode 100644
index 000000000..0c5cfa6f0
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/CISClientProblem.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+import org.springframework.http.HttpStatus;
+
+public class CISClientProblem extends LingoProblem {
+ public CISClientProblem(String message) {
+ super(
+ "cis-integration",
+ "CIS client integration problem",
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ message);
+ }
+
+ public CISClientProblem(String message, Throwable e) {
+ super(
+ "cis-integration",
+ "CIS client integration problem",
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ message,
+ e);
+ }
+
+ public static CISClientProblem cisClientProblemForOperation(String operation, Throwable e) {
+ return new CISClientProblem("Failed to " + operation + " identifiers.", e);
+ }
+
+ public static CISClientProblem cisClientProblemForOperation(String operation) {
+ return new CISClientProblem("Failed to " + operation + " identifiers.");
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/CsvCreationProblem.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/CsvCreationProblem.java
new file mode 100644
index 000000000..c51ac160d
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/CsvCreationProblem.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+import org.springframework.http.HttpStatus;
+
+public class CsvCreationProblem extends LingoProblem {
+
+ public CsvCreationProblem(String message) {
+ super(
+ "file-creation-problem", "Error Creating File", HttpStatus.INTERNAL_SERVER_ERROR, message);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/DateFormatProblem.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/DateFormatProblem.java
new file mode 100644
index 000000000..7cd5a339b
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/DateFormatProblem.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+import org.springframework.http.HttpStatus;
+
+public class DateFormatProblem extends LingoProblem {
+
+ public DateFormatProblem(String message) {
+ super("date-format-problem", "Date Format Problem", HttpStatus.BAD_REQUEST, message);
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/EmptyProductCreationProblem.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/EmptyProductCreationProblem.java
new file mode 100644
index 000000000..ba7def03d
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/EmptyProductCreationProblem.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+import org.springframework.http.HttpStatus;
+
+public class EmptyProductCreationProblem extends LingoProblem {
+
+ public EmptyProductCreationProblem() {
+ super(
+ "empty-product-creation-problem",
+ "Empty product creation problem",
+ HttpStatus.UNPROCESSABLE_ENTITY,
+ "Product creation request did not contain any concepts to create");
+ }
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/ErrorMessages.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/ErrorMessages.java
new file mode 100644
index 000000000..afa490f1c
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/ErrorMessages.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+public class ErrorMessages {
+
+ public static final String TICKET_ID_NOT_FOUND = "Ticket with ID %s not found";
+
+ public static final String COMMENT_ID_NOT_FOUND = "Comment with ID %s not found";
+
+ public static final String COMMENT_NOT_FOUND_FOR_TICKET =
+ "Comment with ID %s not found for Ticket with Id %s";
+
+ public static final String TICKET_NUMBER_NOT_FOUND = "Ticket with Number %s not found";
+ public static final String LABEL_ID_NOT_FOUND = "Label with ID %s not found";
+
+ public static final String LABEL_NAME_NOT_FOUND = "Label with Name %s not found";
+
+ public static final String EXTERNAL_REQUESTOR_NAME_NOT_FOUND =
+ "External Requestor with Name %s not found";
+
+ public static final String EXTERNAL_REQUESTOR_ID_NOT_FOUND =
+ "External Requestor with ID %s not found";
+ public static final String TASK_ASSOCIATION_ID_NOT_FOUND = "TaskAssociation with ID %s not found";
+ public static final String TASK_ASSOCIATION_ALREADY_EXISTS =
+ "TaskAssociation already exists for ticket with id %s";
+ public static final String PRIORITY_BUCKET_ID_NOT_FOUND = "Priority Bucket with ID %s not found";
+ public static final String ADDITIONAL_FIELD_VALUE_ID_NOT_FOUND =
+ "Additional field with ID %s not found";
+ public static final String ITERATION_NOT_FOUND = "Iteration with ID %s not found";
+
+ public static final String STATE_NOT_FOUND = "State with ID %s not found";
+
+ public static final String STATE_LABEL_NOT_FOUND = "State with Label %s not found";
+
+ public static final String TICKET_ASSOCIATION_EXISTS =
+ "Association between tickets %s and %s already exists";
+
+ public static final String ID_NOT_FOUND = "ID %s not found";
+
+ private ErrorMessages() {}
+}
diff --git a/api/src/main/java/au/gov/digitalhealth/lingo/exception/GlobalExceptionHandler.java b/api/src/main/java/au/gov/digitalhealth/lingo/exception/GlobalExceptionHandler.java
new file mode 100644
index 000000000..63fdb127b
--- /dev/null
+++ b/api/src/main/java/au/gov/digitalhealth/lingo/exception/GlobalExceptionHandler.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2024 Australian Digital Health Agency ABN 84 425 496 912.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package au.gov.digitalhealth.lingo.exception;
+
+import au.gov.digitalhealth.lingo.auth.exception.AuthenticationProblem;
+import com.drew.lang.annotations.Nullable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.springframework.http.*;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.method.annotation.HandlerMethodValidationException;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+ @ExceptionHandler(AuthenticationProblem.class)
+ ProblemDetail handleAuthenticationProblem(AuthenticationProblem e) {
+ return e.getBody();
+ }
+
+ @Override
+ protected ResponseEntity